Bug 33568: Restore action buttons
[koha.git] / koha-tmpl / intranet-tmpl / prog / en / modules / catalogue / detail.tt
1 [% USE raw %]
2 [% USE Asset %]
3 [% USE To %]
4 [% USE Koha %]
5 [% USE KohaDates %]
6 [% USE KohaPlugins %]
7 [% USE AuthorisedValues %]
8 [% USE Branches %]
9 [% USE Biblio %]
10 [% USE Frameworks %]
11 [% USE Price %]
12 [% USE TablesSettings %]
13 [% PROCESS 'i18n.inc' %]
14 [% SET CoverImagePlugins = KohaPlugins.get_plugins_intranet_cover_images %]
15
16 [% IF Koha.Preference('AmazonAssocTag') %]
17     [% AmazonAssocTag = '?tag=' _ Koha.Preference('AmazonAssocTag') %]
18 [% ELSE %]
19     [% AmazonAssocTag = '' %]
20 [% END %]
21
22 [% ShowCourseReserves = 0 | html %]
23 [% IF UseCourseReserves %]
24     [% FOREACH item IN itemloop %]
25        [% IF item.course_reserves %]
26            [% FOREACH r IN item.course_reserves %]
27                [% IF r.course.enabled == 'yes' %]
28                    [% ShowCourseReserves = 1 | html %]
29                [% END %]
30            [% END %]
31         [% END %]
32     [% END %]
33 [% END %]
34
35 [% SET plugins_intranet_catalog_biblio_tabs = KohaPlugins.get_plugins_intranet_catalog_biblio_tab({ biblio => biblio, biblio_id => biblionumber }) %]
36
37 [% SET footerjs = 1 %]
38 [% INCLUDE 'doc-head-open.inc' %]
39 <title>[% FILTER collapse %]
40     [% IF ( unknownbiblionumber ) %]
41         [% t("Unknown record") | html %]
42     [% ELSE %]
43         [% title_in_title = INCLUDE 'biblio-title-head.inc' %]
44         [% tx("Details for {title}", { title = title_in_title }) | html %]
45     [% END %] &rsaquo;
46     [% t("Catalog") | html %] &rsaquo;
47     [% t("Koha") | html %]
48 [% END %]</title>
49 [% Asset.css("lib/Chocolat/css/chocolat.css") | $raw %]
50 [% INCLUDE 'doc-head-close.inc' %]
51 </head>
52
53 <body id="catalog_detail" class="catalog">
54
55 [% WRAPPER 'header.inc' %]
56     [% INCLUDE 'cat-search.inc' %]
57 [% END %]
58
59 [% WRAPPER 'sub-header.inc' %]
60     [% WRAPPER breadcrumbs %]
61         [% WRAPPER breadcrumb_item %]
62             <a href="/cgi-bin/koha/catalogue/search.pl">Catalog</a>
63         [% END %]
64
65         [% IF ( unknownbiblionumber ) %]
66             [% WRAPPER breadcrumb_item bc_active= 1 %]
67                 <span>Unknown record</span>
68             [% END %]
69         [% ELSE %]
70             [% WRAPPER breadcrumb_item %]
71                 [% INCLUDE 'biblio-title.inc' link = 1 %]
72             [% END %]
73             [% WRAPPER breadcrumb_item bc_active= 1 %]
74                 <span>Details</span>
75             [% END %]
76         [% END %]
77     [% END #/ WRAPPER breadcrumbs %]
78 [% END #/ WRAPPER sub-header.inc %]
79
80 <div class="main container-fluid">
81     <div class="row">
82         <div class="col-sm-10 col-sm-push-2">
83             <main>
84                 [% INCLUDE 'messages.inc' %]
85                 <div class="row">
86
87 [% IF ( unknownbiblionumber ) %]
88   <div class="dialog message">The record you requested does not exist ([% biblionumber | html %]).</div>
89 [% ELSE %]
90
91 [% IntranetCoce    = Koha.Preference('IntranetCoce') %]
92 [% CoceProviders   = Koha.Preference('CoceProviders') %]
93 [% CoceHost        = Koha.Preference('CoceHost') %]
94 [% SyndeticsCovers = Koha.Preference('SyndeticsEnabled') && Koha.Preference('SyndeticsCoverImages') %]
95
96 [% INCLUDE 'cat-toolbar.inc' %]
97     [% IF ( ocoins ) %]
98         <!-- COinS / OpenURL -->
99         <span class="Z3988" title="[% ocoins | html %]"></span>
100     [% END %]
101
102     [% IF ( CoverImagePlugins || AmazonCoverImages  || LocalCoverImages || IntranetCoce || ( SyndeticsCovers ) || (Koha.Preference('CustomCoverImages') && Koha.Preference('CustomCoverImagesURL')) ) %]
103         <div id="catalogue_detail_biblio" class="col-xs-9">
104     [% ELSE %]
105         <div id="catalogue_detail_biblio" class="col-xs-12">
106     [% END %]
107         [% IF decoding_error || analytics_error %]
108             <div class="page-section bg-danger">
109                <h1>Errors found</h1>
110                [% IF decoding_error %]
111                    <h2>Encoding errors</h2>
112                    <p class="biberror">There is at least one encoding error with this bibliographic record, the view may be degraded.</p>
113                    <pre class="error">[% decoding_error | html %]</pre>
114                [% END %]
115                [% IF analytics_error %]
116                    <h2>Analytics errors</h2>
117                    <p class="analytics_error">There was an error searching for analytic records, please see the logs for details.</p>
118                [% END %]
119             </div>
120         [% END %]
121
122         <div class="page-section">
123
124         [% XSLTBloc | $raw %]
125
126         [% IF shelves.count %]
127             <span class="results_summary"><span class="label">Lists that include this title: </span>
128             [% FOREACH s IN shelves %]
129                 <a href="/cgi-bin/koha/virtualshelves/shelves.pl?op=view&amp;shelfnumber=[% s.shelfnumber | uri %]">[% s.shelfname | html %]</a>
130                 [% IF ( loop.last ) %][% ELSE %]|[% END %]
131             [% END %]
132             </span>
133         [% END %]
134         [% IF ( TagsEnabled &&  TagsShowOnDetail &&  TagLoop ) %]
135                 <span class="results_summary"><span class="label">Tags:</span>
136                     [% FOREACH TagLoo IN TagLoop %]
137                         [% IF ( CAN_user_tools_moderate_tags ) %]
138                         <a href="/cgi-bin/koha/tags/list.pl?tag=[% TagLoo.term |uri %]">[% TagLoo.term | html %]</a>
139                         [% ELSE %]
140                         [% TagLoo.term | html %]
141                         [% END %]
142                         <span class="weight">([% TagLoo.weight_total | html %])</span>[% IF ( loop.last ) %][% ELSE %], [% END %]
143                     [% END %]
144                     </span>
145         [% END %]
146         <span id="catalogue_detail_marc_preview" class="results_summary"><span class="label">MARC preview:</span> <a href="/cgi-bin/koha/catalogue/showmarc.pl?id=[% biblionumber | uri %]&amp;viewas=html" title="MARC" class="previewMARC">Show</a></span>
147         <span id="catalogue_detail_framework" class="results_summary">
148             <span class="label">MARC framework:</span>
149             <span class="frameworkcode">[% Frameworks.GetName(biblio.frameworkcode) | html %]</span>
150         </span>
151         [% IF !item_level_itypes ||  Koha.Preference("BiblioItemtypeInfo") %]
152            <span class="results_summary itemtype"><span class="label">Itemtype:</span>
153           [% IF ( !noItemTypeImages && imageurl ) %]
154               <img src="[% imageurl | html %]" alt="" />
155           [% END %]
156           [% IF ( description ) %]
157               <span class="itypetext">[% description | html %]</span>
158           [% ELSE %]
159               <span class="itypetext">[% itemtype | html %]</span>
160           [% END %]
161           </span>
162         [% END %]
163
164         [% IF ( Koha.Preference('SearchEngine') == 'Elasticsearch' ) %]
165             <span id="catalogue_detail_elastic_record" class="results_summary"><span class="label">Elasticsearch record:</span> <a href="/cgi-bin/koha/catalogue/showelastic.pl?id=[% biblionumber | uri %]" title="Elasticsearch record" class="previewElastic">Show</a></span>
166         [% END %]
167
168         [% IF ( holdcount ) %]
169             <span class="results_summary">
170                 <span class="label">Holds:</span>
171                 <span class="number_box">
172                     [% IF CAN_user_reserveforothers_place_holds %]
173                         <a href="/cgi-bin/koha/reserve/request.pl?biblionumber=[% biblionumber | uri %]">[% holdcount | html %]</a>
174                     [% ELSE %]
175                         <span>[% holdcount | html %]</span>
176                     [% END %]
177                 </span>
178             </span>
179         [% END %]
180
181         [% IF illrequests.count %]
182             <span class="results_summary">
183                 <span class="label">ILL requests:</span>
184                 [% IF CAN_user_ill %]
185                     [% FOREACH ill IN illrequests %]
186                         <a href="/cgi-bin/koha/ill/ill-requests.pl?method=illview&illrequest_id=[% ill.illrequest_id | uri %]">Request [% ill.illrequest_id | html %]</a>[% IF ! loop.last %], [% END %]
187                     [% END %]
188                 [% ELSE %]
189                     [% FOREACH ill IN illrequests %]
190                         <span>Request [% ill.illrequest_id | html %]</span>[% IF ! loop.last %], [% END %]
191                     [% END %]
192                 [% END %]
193             </span>
194         [% END %]
195
196         [% IF ( article_requests_count = biblio.article_requests.filter_by_current.count ) %]
197             <span class="results_summary">
198                 <span class="label">Article requests:</span>
199                 <span class="number_box">
200                     <a href="/cgi-bin/koha/circ/request-article.pl?biblionumber=[% biblionumber | uri %]">[% article_requests_count | html %]</a>
201                 </span>
202             </span>
203         [% END %]
204
205         [% IF course_reserves %]
206             <span class="results_summary"><span class="label">Courses that have reserved this title: </span>
207             [% FOREACH c IN course_reserves %]
208                 <a href="/cgi-bin/koha/course_reserves/course-details.pl?course_id=[% c.course_id | uri %]">[% c.course.course_name | html %]</a>
209                 [% IF ( loop.last ) %][% ELSE %]|[% END %]
210             [% END %]
211             </span>
212         [% END %]
213         </div> [%# .page-section %]
214
215         [% IF ( CoverImagePlugins || AmazonCoverImages  || LocalCoverImages || IntranetCoce || ( SyndeticsCovers ) || (Koha.Preference('CustomCoverImages') && Koha.Preference('CustomCoverImagesURL')) ) %]
216         </div>
217             <div class="col-xs-3 bookcoverimg">
218                 <div id="biblio-cover-slider" class="cover-slider" data-isbn="[% normalized_isbn | html %]">
219                     [% IF ( LocalCoverImages ) %]
220                         [% IF localimages.count %]
221                             [% FOREACH image IN localimages %]
222                                 <div class="cover-image local-coverimg">
223                                     <a href="/cgi-bin/koha/catalogue/image.pl?imagenumber=[% image.imagenumber | uri %]" title="Local cover image">
224                                         <img src="/cgi-bin/koha/catalogue/image.pl?thumbnail=1&amp;imagenumber=[% image.imagenumber | uri %]" alt="Local cover image" data-link="/cgi-bin/koha/catalogue/imageviewer.pl?biblionumber=[% biblionumber | uri %]&amp;imagenumber=[% image.imagenumber | uri %]" />
225                                     </a>
226                                     <div class="hint">Local cover image</div>
227                                 </div>
228                             [% END %]
229                         [% END %]
230                     [% END %]
231
232                     [% IF ( AmazonCoverImages && normalized_isbn) %]
233                         <div class="cover-image" id="amazon-bookcoverimg">
234                             <a href="https://images-na.ssl-images-amazon.com/images/P/[% normalized_isbn | uri %].01.LZZZZZZZ.jpg" title="Amazon cover image">
235                                 <img src="https://images-na.ssl-images-amazon.com/images/P/[% normalized_isbn | uri %].01.MZZZZZZZ.jpg" alt="Amazon cover image" data-link="http://www.amazon[% AmazonTld | uri %]/gp/reader/[% normalized_isbn | uri %][% AmazonAssocTag | uri %]#reader-link"/>
236                             </a>
237                             <div class="hint">Image from Amazon.com</div>
238                         </div>
239                     [% END %]
240
241                     [% IF ( IntranetCoce && CoceProviders && normalized_isbn ) %]
242                         [% coce_id = normalized_ean || normalized_isbn %]
243                         <div class="cover-image coce-coverimg">
244                             [% IF ( coce_id ) %]
245                                 <a title="Image from Coce" class="[% coce_id | html %]" id="coce-thumbnail-preview"></a>
246                             [% ELSE %]
247                                 <span class="no-image">No cover image available</span>
248                             [% END %]
249                             <div class="hint">Image from Coce</div>
250                         </div>
251                     [% END %]
252
253                     [% IF ( SyndeticsCovers ) %]
254                         [% IF ( content_identifier_exists ) %]
255                         <div class="cover-image" id="syndetics-bookcoverimg">
256                             <a href="https://secure.syndetics.com/index.aspx?isbn=[% normalized_isbn | url %]/LC.GIF&amp;client=[% Koha.Preference('SyndeticsClientCode') | url %]&amp;type=xw10&amp;upc=[% normalized_upc | url %]&amp;oclc=[% normalized_oclc | url %]" title="Syndetics cover image">
257                                 <img src="https://secure.syndetics.com/index.aspx?isbn=[% normalized_isbn | url %]/[% Koha.Preference('SyndeticsCoverImageSize') | url %].GIF&amp;client=[% Koha.Preference('SyndeticsClientCode') | url %]&amp;type=xw10&amp;upc=[% normalized_upc | url %]&amp;oclc=[% normalized_oclc | url %]" alt="" class="thumbnail" />
258                             </a>
259                             <div class="hint">Image from Syndetics</div>
260                         </div>
261                             [% ELSE %]
262                                 <span class="no-image">No cover image available</span>
263                             [% END %]
264                     [% END %]
265
266                     [% IF Koha.Preference('CustomCoverImages') && Koha.Preference('CustomCoverImagesURL') %]
267                         [% SET custom_cover_image_url = biblio.custom_cover_image_url %]
268                         [% IF custom_cover_image_url %]
269                             <div class="cover-image" id="custom-coverimg">
270                                 <a class="custom_cover_image" href="[% custom_cover_image_url | url %]" title="Custom cover image">
271                                     <img id="custom-img" alt="Custom cover image" src="[% custom_cover_image_url | url %]" />
272                                 </a>
273                                 <div class="hint">Custom cover image</div>
274                             </div>
275                         [% END %]
276                     [% END %]
277                 </div> <!-- /.cover-slider -->
278             </div> <!-- /.bookcoverimg.col-xs-3 -->
279         [% ELSE %]
280         </div> <!-- /.col-xs-* -->
281         [% END # /IF ( AmazonCoverImages, etc ) %]
282 </div>
283
284 <div id="bibliodetails" class="toptabs">
285
286 <ul class="nav nav-tabs" role="tablist">
287     [% IF (SeparateHoldings) %]
288         <li role="presentation">
289             <a href="#holdings" aria-controls="holdings" role="tab" data-toggle="tab">[% Branches.GetLoggedInBranchname | html %] holdings ([% itemloop.size() || 0 | html %])</a>
290         </li>
291         <li role="presentation">
292             <a href="#otherholdings"  aria-controls="otherholdings" role="tab" data-toggle="tab">Other holdings ([% otheritemloop.size() || 0 | html %])</a>
293         </li>
294     [% ELSE %]
295         <li role="presentation">
296             <a href="#holdings" aria-controls="holdings" role="tab" data-toggle="tab">Holdings ([% itemloop.size() || 0 | html %])</a>
297         </li>
298     [% END %]
299     [% IF Koha.Preference('EnableItemGroups') %]
300         <li role="presentation">
301             <a href="#item_groups" aria-controls="item_groups" role="tab" data-toggle="tab">Item groups</a>
302         </li>
303     [% END %]
304 [% IF ( MARCNOTES || notes ) %]<li role="presentation"><a href="#description" aria-controls="description" role="tab" data-toggle="tab">Descriptions ([% ( MARCNOTES.size || 1 ) | html %])</a></li>[% END %]
305 [% IF ComponentParts && ComponentParts.size %]<li id="components_tab" role="presentation"><a href="#components"  aria-controls="components" role="tab" data-toggle="tab">Components ([% ComponentParts.size | html %])</a></li>[% END %]
306 [% IF ( subscriptionsnumber ) %]<li role="presentation"><a href="#subscriptions"  aria-controls="subscriptions" role="tab" data-toggle="tab">Subscriptions</a></li>[% END %]
307 [% IF Koha.Preference('AcquisitionDetails') %]<li role="presentation"><a href="#acq_details"  aria-controls="acq_details" role="tab" data-toggle="tab">Acquisition details</a></li>[% END %]
308 [% IF suggestions.count %]<li role="presentation"><a href="#suggestion_details"  aria-controls="suggestion_details" role="tab" data-toggle="tab">Suggestion details</a></li>[% END %]
309 [% IF ( FRBRizeEditions ) %][% IF ( XISBNS ) %]<li role="presentation"><a href="#editions"  aria-controls="editions" role="tab" data-toggle="tab">Editions</a></li>[% END %][% END %]
310 [% IF ( ( Koha.Preference('CatalogConcerns') || Koha.Preference('OpacCatalogConcerns') ) && CAN_user_editcatalogue_edit_catalogue ) %]<li role="presentation"><a href="#concerns" aria-controls="concerns" role="tab" data-toggle="tab">Concerns ([% biblio.tickets.count | html %])</a></li>[% END %]
311 [% IF ( LocalCoverImages ) %]
312     <li role="presentation">
313         <a href="#images"  aria-controls="images" role="tab" data-toggle="tab">Images ([% localimages.count || 0 | html %])</a>
314     </li>
315 [% END %]
316 [% IF HTML5MediaEnabled && HTML5MediaSets.size %]
317     <li id="media_tab" role="presentation"><a href="#html5media"  aria-controls="html5media" role="tab" data-toggle="tab">Play media</a></li>
318 [% END %]
319 [% IF ( Koha.Preference('NovelistSelectStaffEnabled') && Koha.Preference('NovelistSelectStaffProfile') && Koha.Preference('NovelistSelectStaffView') == 'tab' ) %]
320     <li class="NovelistSelect" style="display:none;" role="presentation"><a href="#NovelistSelect"  aria-controls="NovelistSelect" role="tab" data-toggle="tab">NoveList Select</a></li>
321 [% END %]
322 [% FOREACH plugins_intranet_catalog_biblio_tab IN plugins_intranet_catalog_biblio_tabs %]
323     <li role="presentation"><a href="#[% plugins_intranet_catalog_biblio_tab.id | uri %]"  aria-controls="[% plugins_intranet_catalog_biblio_tab.id | uri %]" role="tab" data-toggle="tab">[% plugins_intranet_catalog_biblio_tab.title | html %]</a></li>
324 [% END %]
325 </ul>
326
327 <div class="tab-content">
328 [% items_table_block_iter = 0 %]
329 [% BLOCK items_table %]
330     [% items_table_block_iter = items_table_block_iter + 1 %]
331     <div class="[% tab | html %]_table_table_controls">
332         [% IF (StaffDetailItemSelection) %]
333             | <a href="#" class="SelectAll" data-tab="[% tab | html %]"><i class="fa fa-check"></i> Select all</a> |
334             <a href="#" class="ClearAll" data-tab="[% tab | html %]"><i class="fa fa-times"></i> Clear all</a>
335             <span class="itemselection_actions">
336               | Actions:
337               [% IF CAN_user_tools_items_batchdel %]
338                 <a class="itemselection_action_delete"><i class="fa fa-trash-can"></i> Delete selected items</a>
339               [% END %]
340               [% IF CAN_user_tools_items_batchmod %]
341                 <a class="itemselection_action_modify"><i class="fa-solid fa-pencil" aria-hidden="true"></i> Modify selected items</a>
342               [% END %]
343               [% IF CAN_user_editcatalogue_manage_item_groups && biblio.item_groups.count %]
344                 <a class="itemselection_action_item_group_set" href="#"><i class="fa fa-book"></i> Add/move to item group</a>
345                 <a class="itemselection_action_item_group_unset" href="#"><i class="fa fa-unlink"></i> Remove from item group</a>
346               [% END %]
347             </span>
348         [% END %]
349     </div>
350     <table class="items_table" id="[% tab | html %]_table">
351         <thead>
352             <tr>
353                 [% IF (StaffDetailItemSelection) %]<th id="[% tab | html %]_checkbox" data-colname="[% tab | html %]_checkbox" class="NoSort"></th>[% END %]
354                 [% IF Koha.Preference('LocalCoverImages') && ( tab == 'holdings' && itemloop_has_images || tab == 'otherholdings' && otheritemloop_has_images ) %]
355                     <th id="[% tab | html %]_cover_image" data-colname="[% tab | html %]_cover_image">Cover image</th>
356                 [% END %]
357                 [% IF ( item_level_itypes ) %]<th id="[% tab | html %]_itype" data-colname="[% tab | html %]_itype">Item type</th>[% END %]
358                 <th id="[% tab | html %]_holdingbranch" data-colname="[% tab | html %]_holdingbranch">Current library</th>
359                 <th id="[% tab | html %]_homebranch" data-colname="[% tab | html %]_homebranch">Home library</th>
360                 [% IF ( itemdata_ccode ) %]<th id="[% tab | html %]_ccode" data-colname="[% tab | html %]_ccode">Collection</th>[% END %]
361                 [% IF Koha.Preference('EnableItemGroups') %]
362                     <th id="[% tab | html %]_item_group" data-colname="[% tab | html %]_item_group">Item group</th>
363                 [% END %]
364                 <th id="[% tab | html %]_itemcallnumber" data-colname="[% tab | html %]_itemcallnumber">Call number</th>
365                 [% IF volinfo %]
366                     <th id="[% tab | html %]_enumchron" data-colname="[% tab | html %]_enumchron">Serial enumeration / chronology</th>
367                 [% END %]
368                 <th id="[% tab | html %]_status" data-colname="[% tab | html %]_status">Status</th>
369                 <th id="[% tab | html %]_lastseen" data-colname="[% tab | html %]_lastseen">Last seen</th>
370                 <th id="[% tab | html %]_issues" data-colname="[% tab | html %]_issues">Checkouts</th>
371                 <th id="[% tab | html %]_renewals" data-colname="[% tab | html %]_renewals">Renewals</th>
372                 <th id="[% tab | html %]_dateaccessioned" data-colname="[% tab | html %]_dateaccessioned">Date accessioned</th>
373                 <th id="[% tab | html %]_datelastborrowed" data-colname="[% tab | html %]_datelastborrowed">Date last borrowed</th>
374                 <th id="[% tab | html %]_barcode" data-colname="[% tab | html %]_barcode">Barcode</th>
375                 [% IF ( itemdata_uri ) %]<th id="[% tab | html %]_uri" data-colname="[% tab | html %]_uri">URL</th>[% END %]
376                 [% IF ( itemdata_copynumber ) %]<th id="[% tab | html %]_copynumber" data-colname="[% tab | html %]_copynumber">Copy number</th>[% END %]
377                 [% IF ( itemdata_stocknumber ) %]<th id="[% tab | html %]_stocknumber" data-colname="[% tab | html %]_stocknumber">Inventory number</th>[% END %]
378                 [% IF materials %]<th id="[% tab | html %]_materials" data-colname="[% tab | html %]_materials">Materials specified</th>[% END %]
379                 [% IF ( itemdata_itemnotes ) %]<th id="[% tab | html %]_itemnotes" data-colname="[% tab | html %]_itemnotes">Public notes</th>[% END %]
380                 [% IF ( itemdata_nonpublicnotes ) %]<th id="[% tab | html %]_itemnotes_nonpublic" data-colname="[% tab | html %]_itemnotes_nonpublic">Non-public notes</th>[% END %]
381                 [% IF ( hostrecords ) %]<th id="[% tab | html %]_hostrecord" data-colname="[% tab | html %]_hostrecord">Host records</th>[% END %]
382                 [% IF ( analyze ) %]<th id="[% tab | html %]_usedin" data-colname="[% tab | html %]_usedin">Used in</th><th></th>[% END %]
383                 [% IF ( ShowCourseReserves ) %]<th id="[% tab | html %]_course_reserves" data-colname="[% tab | html %]_course_reserves">Course reserves</th>[% END %]
384                 [% IF ( SpineLabelShowPrintOnBibDetails ) %]<th id="[% tab | html %]_spinelabel" data-colname="[% tab | html %]_spinelabel" class="NoSort">Spine label</th>[% END %]
385                 [% IF ( CAN_user_editcatalogue_edit_items ) %]<th id="[% tab | html %]_actions" data-colname="[% tab | html %]_actions"class="NoSort noExport">&nbsp;</th>[% END %]
386             </tr>
387         </thead>
388         <tbody>
389             [% FOREACH item IN items %]
390                 [% SET date_due = item.object.checkout.date_due %]
391                 <tr id="item_[% item.itemnumber | html %]" data-itemnumber="[% item.itemnumber | html %]" data-duedate="[% date_due | html %]">
392                 [% IF (StaffDetailItemSelection) %]
393                     <td style="text-align:center;vertical-align:middle">
394                         [% IF item.can_be_edited %]
395                             <input type="checkbox" value="[% item.itemnumber | html %]" name="itemnumber" />
396                         [% END %]
397                     </td>
398                 [% END %]
399                     [% IF Koha.Preference('LocalCoverImages') && ( tab == 'holdings' && itemloop_has_images || tab == 'otherholdings' && otheritemloop_has_images ) %]
400                         <td class="cover">
401                             <div class="bookcoverimg">
402                                 <div class="cover-slider">
403                                     [% FOREACH image IN item.object.cover_images %]
404                                         <div class="cover-image local-coverimg">
405                                             <a href="/cgi-bin/koha/catalogue/image.pl?itemnumber=[% image.itemnumber | uri %]&amp;imagenumber=[% image.imagenumber | uri %]" title="Local cover image">
406                                                 <img src="/cgi-bin/koha/catalogue/image.pl?thumbnail=1&amp;imagenumber=[% image.imagenumber | uri %]" alt="Local cover image" data-link="/cgi-bin/koha/catalogue/imageviewer.pl?itemnumber=[% item.itemnumber | uri %]&amp;imagenumber=[% image.imagenumber | uri %]" />
407                                             </a>
408                                         </div>
409                                     [% END %]
410                                 </div>
411                             </div>
412                         </td>
413                     [% END %]
414
415                     [% IF ( item_level_itypes ) %]
416                         <td class="itype">
417                             [% SET itemtype = item.itemtype %]
418                             [% IF !noItemTypeImages && itemtype.image_location('intranet') %]
419                                 <img src="[% itemtype.image_location('intranet') | html %]" alt="[% itemtype.translated_description | html %]" title="[% itemtype.translated_description | html %]" />
420                             [% END %]
421                             <span class="itypedesc itypetext">[% itemtype.translated_description | html %]</span>
422                         </td>
423                     [% END %]
424                     <td class="location">[% UNLESS ( singlebranchmode ) %][% Branches.GetName( item.holdingbranch ) | html %] [% END %]</td>
425                     <td class="homebranch">
426                         <span class="homebranchdesc">[% Branches.GetName(item.homebranch) | html %]</span>
427                         <span class="shelvingloc">
428                         [%# If permanent location is defined, show description or code and             %]
429                         [%# display current location in parentheses. If not, display current location. %]
430                         [%# Note that permanent location is a code, and location may be an authval.    %]
431                             [% SET item_location = AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.location', authorised_value => item.location ) %]
432                             [% IF item.permanent_location %]
433                                 [% SET permloc_authval = AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.location', authorised_value => item.permanent_location ) %]
434                                 [% permloc_authval | html %]
435                                 [% IF item_location AND item_location != permloc_authval AND item.location != item.permanent_location %]
436                                     ([% item_location | html %])
437                                 [% END %]
438                             [% ELSE %]
439                                 [% item_location | html %]
440                             [% END %]
441                         </span>
442                     </td>
443                     [% IF ( itemdata_ccode ) %]<td>[% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.ccode', authorised_value => item.ccode ) | html %]</td>[% END %]
444                     [% IF Koha.Preference('EnableItemGroups') %]<td class="item_group">[% item.object.item_group.description | html %]</td>[% END %]
445                     <td class="itemcallnumber">[% IF ( item.itemcallnumber ) %] [% item.itemcallnumber | html %][% END %]</td>
446                     [% IF ( volinfo ) %]
447                         [% SET serial = item.serial %]
448                         [% IF itemdata_publisheddate #If there is at least one published date, use it for sorting %]
449                             <td class="enumchron" data-order="[% serial.publisheddate | html %]">
450                         [% ELSE %]
451                             <td class="enumchron">
452                         [% END %]
453                             [% IF ( itemdata_enumchron ) %]
454                                 [% IF item.enumchron && serial.serialseq %]
455                                     <span class="enum">[% item.enumchron | html %]</span>
456                                     [% IF ( serial.serialseq && item.enumchron != serial.serialseq ) %]
457                                         <span class="sep"> -- </span>
458                                         <span class="serialseq">[% serial.serialseq | html %]</span>
459                                     [% END %]
460                                 [% ELSIF item.enumchron %]
461                                     <span class="enum">[% item.enumchron | html %]</span>
462                                 [% ELSIF item.serialseq %]
463                                     <span class="serialseq">[% serial.serialseq | html %]</span>
464                                 [% END %]
465                                 [% IF serial.publisheddate %]
466                                     <span class="pubdate">([% serial.publisheddate | $KohaDates %])</span>
467                                 [% END %]
468                             [% END %]
469                             </span>
470                         </td>
471                     [% END %]
472                     <td class="status">
473
474                         [% IF item.object.checkout %]
475                           [% IF item.object.checkout.onsite_checkout %]
476                             <div class="item_status localuse">Currently in local use
477                           [% ELSE %]
478                             <div class="item_status datedue">Checked out
479                           [% END %]
480                               [% IF item.object.checkout.onsite_checkout %]
481                                 by
482                               [% ELSE %]
483                                 to
484                               [% END %]
485                               [% INCLUDE 'patron-title.inc' patron=item.object.checkout.patron hide_patron_infos_if_needed=1 %]
486                             : due [% date_due | $KohaDates as_due_date => 1 %]
487                             </div>
488                         [% ELSIF ( transfer = item.object.get_transfer ) %]
489                             [% IF (transfer.datesent) %]
490                                 <div class="item_status intransit">In transit from [% Branches.GetName( transfer.frombranch ) | html %] to [% Branches.GetName( transfer.tobranch ) | html %] since [% transfer.datesent | $KohaDates %]</div>
491                             [% ELSE %]
492                                 <div class="item_status transitrequested">Transit pending from [% Branches.GetName( transfer.frombranch ) | html %] to [% Branches.GetName( transfer.tobranch ) | html %] since [% transfer.daterequested | $KohaDates %]</div>
493                             [% END %]
494                         [% END %]
495
496                         [% IF ( item.itemlost ) %]
497                             [% SET itemlost_description = AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.itemlost', authorised_value => item.itemlost ) %]
498                             [% IF itemlostloop %]
499                                 <div class="item_status lost">[% itemlost_description | html %]</div>
500                             [% ELSE %]
501                                 <div class="item_status lost">Unavailable (lost or missing)</div>
502                             [% END %]
503                         [% END %]
504
505                         [% IF ( item.withdrawn ) %]
506                             [% SET withdrawn_description = AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.withdrawn', authorised_value => item.withdrawn ) %]
507                             [% IF withdrawn_description %]
508                                 <div class="item_status wdn">[% withdrawn_description | html %]</div>
509                             [% ELSE %]
510                                 <div class="item_status wdn">Withdrawn</div>
511                             [% END %]
512                         [% END %]
513
514                         [% IF ( item.damaged ) %]
515                             [% SET damaged_description = AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.damaged', authorised_value => item.damaged ) %]
516                             [% IF damaged_description %]
517                                 <div class="item_status dmg">[% damaged_description | html %]</div>
518                             [% ELSE %]
519                                 <div class="item_status dmg">Damaged</div>
520                             [% END %]
521                         [% END %]
522
523                         [% IF ( item.notforloan || item.itemtype.notforloan ) %]
524                             <div class="item_status notforloan">Not for loan
525                             [% SET not_for_loan_description = AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.notforloan', authorised_value => item.notforloan ) %]
526                             [% IF not_for_loan_description %]
527                                 <span class="reason">([% not_for_loan_description | html %])</span>
528                             [% END %]
529                             </div>
530                         [% END %]
531
532                         [% SET hold = item.first_hold %]
533                         [% IF hold %]
534                             [% IF hold.waitingdate %]
535                                 <div class="item_status waitingat">Waiting at [% Branches.GetName( hold.branchcode ) | html %][% IF ( hold.desk_id ) %], [% hold.desk.desk_name | html %][% END %] since [% hold.waitingdate | $KohaDates %].</div>
536                                 [% IF canreservefromotherbranches AND ( hold.waitingdate OR hold.priority == 1 ) %]
537                                     <span class="heldfor">Hold for:</span>
538                                     [% INCLUDE 'patron-title.inc' patron=hold.borrower hide_patron_infos_if_needed=1 %]
539                                 [% END %]
540                             [% ELSE %]
541                                 <div class="item_status holdonitem">There is an item level hold on this item (priority = [% hold.priority | html %]).</div>
542                             [% END %]
543                         [% END %]
544
545                         [% IF Koha.Preference('UseRecalls') %]
546                             [% SET recall = item.object.recall %]
547                             [% IF recall %]
548                                 [% IF recall.waiting_date %]
549                                     <div class="item_status recallat">Waiting at [% Branches.GetName( recall.pickup_library_id ) | html %] since [% recall.waiting_date | $KohaDates %]</div>
550                                 [% ELSE %]
551                                     [% patron_link = BLOCK %]<a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% recall.patron_id | uri %]">[% recall.patron.firstname | html %] [% recall.patron.surname | html %] ([% recall.patron.cardnumber | html %])</a>[% END %]
552                                     <div class="item_status recallby">recalled by [% patron_link| $raw %] on [% recall.created_date | $KohaDates %]</div>
553                                 [% END %]
554                             [% END %]
555                         [% END %]
556
557                         [% UNLESS ( item.notforloan || item.itemtype.notforloan || item.onloan || item.itemlost || item.withdrawn || item.damaged || transfer || hold || ( Koha.Preference('UseRecalls') && recall ) ) %]
558                             <div class="item_status available">Available</div>
559                         [% END %]
560
561                         [% IF ( item.restricted ) %]
562                             <div class="item_status restricted">([% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.restricted', authorised_value => item.restricted ) | html %])</div>
563                         [% END %]
564
565                         [% IF ( item.bundle_host ) %]
566                             <div class="item_status bundled">In bundle: [% INCLUDE 'biblio-title.inc' biblio = item.bundle_host.biblio link = 1 %]</div>
567                         [% END %]
568
569                     </td>
570                     <td class="datelastseen" data-order="[% item.datelastseen | html %]">[% item.datelastseen | $KohaDates with_hours => 1 %]</td>
571                     <td class="issues" data-order="[% item.issues || 0 | html %]">[% item.issues || 0 | html %]</td>
572                     <td class="renewals" data-order="[% item.renewals || 0 | html %]">[% item.renewals || 0 | html %]</td>
573                     <td class="dateaccessioned" data-order="[% item.dateaccessioned | html %]">[% item.dateaccessioned | $KohaDates %]</td>
574                     <td class="datelastborrowed" data-order="[% item.datelastborrowed | html %]">[% item.datelastborrowed | $KohaDates %]</td>
575                     <td><a href="/cgi-bin/koha/catalogue/moredetail.pl?itemnumber=[% item.itemnumber | uri %]&amp;biblionumber=[% item.biblionumber | uri %]&amp;bi=[% item.biblioitemnumber | uri %]#item[% item.itemnumber | uri %]">[% item.barcode | html %]</a></td>
576                     [% IF ( itemdata_uri ) %]
577                         [% IF item.uri.split(' \| ').size > 1 %]
578                             <td class="uri">
579                                 [% FOREACH uri IN item.uri.split(' \| ') %]<a href="[% uri | url %]">[% uri | html %]</a><br>[% END %]
580                             </td>
581                         [% ELSE %]
582                             <td class="uri">
583                                 [% IF item.uri %]
584                                     <a href="[% item.uri | url %]">[% IF Koha.Preference('URLLinkText') %][% Koha.Preference('URLLinkText') | html %][% ELSE %]Link to resource[% END %]</a>
585                                 [% END %]
586                             </td>
587                         [% END %]
588                     [% END %]
589                     [% IF ( itemdata_copynumber ) %]
590                         <td class="copynumber">[% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.copynumber', authorised_value => item.copynumber ) | html %]</td>
591                     [% END %]
592                     [% IF ( itemdata_stocknumber ) %]
593                         <td class="stocknumber">[% item.stocknumber | html %]</td>
594                     [% END %]
595                     [% IF materials %]
596                         <td class="materials"> [% item.materials | html %] </td>
597                     [% END %]
598                     [% IF ( itemdata_itemnotes ) %]
599                         <td><div class="itemnotes">[% item.object.itemnotes.replace('\n','<br />') | $raw %]</div></td>
600                     [% END %]
601                     [% IF itemdata_nonpublicnotes %]
602                         <td class="nonpublicnote">[% item.itemnotes_nonpublic | html %]</td>
603                     [% END %]
604                     [% IF ( hostrecords ) %]
605                         <td>[% IF ( item.hostbiblionumber) %]<a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% item.hostbiblionumber | uri %]" >[% item.hosttitle | html %]</a>[% END %]</td>
606                     [% END %]
607                     [% IF ( analyze ) %]
608                         <td>
609                             [% IF ( item.countanalytics ) %]
610                                 <a href="/cgi-bin/koha/catalogue/search.pl?idx=hi&amp;q=[% item.itemnumber | uri %]">[% item.countanalytics | html %] analytics</a>
611                             [% END %]
612                         </td>
613                     [% END %]
614                     [% IF ( analyze ) %]
615                         <td><a href="/cgi-bin/koha/cataloguing/addbiblio.pl?hostbiblionumber=[% item.biblionumber | uri %]&amp;hostitemnumber=[% item.itemnumber | uri %]">Create analytics</a></td>
616                     [% END %]
617
618                 [% IF ShowCourseReserves %]
619                     <td>
620                         [% IF item.course_reserves %]
621                             [% FOREACH r IN item.course_reserves %]
622                                 [% IF r.course.enabled == 'yes' %]
623                                     <p>
624                                       <a href="/cgi-bin/koha/course_reserves/course-details.pl?course_id=[% r.course.course_id | uri %]">
625                                          [% r.course.course_name | html %]
626                                          <!--[% IF r.course.course_number %] [% r.course.course_number | html %] [% END %]-->
627                                          [% IF r.course.section %] [% r.course.section | html %] [% END %]
628                                          [% IF r.course.term %] [% AuthorisedValues.GetByCode( 'TERM', r.course.term ) | html %] [% END %]
629                                       </a>
630                                    </p>
631                                [% END %]
632                            [% END %]
633                        [% END %]
634                     </td>
635                 [% END %]
636
637                 [% IF ( SpineLabelShowPrintOnBibDetails ) %]
638                     <td><a class="btn btn-default btn-xs print-label" href="/cgi-bin/koha/labels/spinelabel-print.pl?barcode=[% item.barcode | uri %]"><i class="fa fa-print"></i> Print label</a></td>
639                 [% END %]
640
641                 [% IF CAN_user_editcatalogue_edit_items %]
642                     <td class="actions">
643                         [% IF item.can_be_edited %]
644                             [% IF Koha.Preference('LocalCoverImages') OR Koha.Preference('OPACLocalCoverImages') %]
645                                 <div class="btn-group">
646                                     <a  class="btn btn-default btn-xs" href="/cgi-bin/koha/cataloguing/additem.pl?op=edititem&biblionumber=[% item.biblionumber | html %]&itemnumber=[% item.itemnumber | html %]#edititem"><i class="fa-solid fa-pencil" aria-hidden="true"></i> Edit</a><a class="btn btn-default btn-xs dropdown-toggle" data-toggle="dropdown"><span class="caret"></span></a>
647                                     <ul class="dropdown-menu pull-right">
648                                         <li><a href="/cgi-bin/koha/tools/upload-cover-image.pl?itemnumber=[% item.itemnumber | uri %]&amp;filetype=image"><i class="fa fa-upload"></i> Upload image</a></li>
649                                     </ul>
650                                 </div>
651                             [% ELSE %]
652                                 <a class="btn btn-default btn-xs" href="/cgi-bin/koha/cataloguing/additem.pl?op=edititem&biblionumber=[% item.biblionumber | html %]&itemnumber=[% item.itemnumber | html %]#edititem"><i class="fa-solid fa-pencil" aria-hidden="true"></i> Edit</a>
653                             [% END %]
654                         [% END %]
655                         [% IF bundlesEnabled %]
656                             <button class="btn btn-default btn-xs details-control"><i class="fa fa-folder"></i> Manage bundle ([% item.bundled | html %]|[% item.bundled_lost | html %])</button>
657                         [% END %]
658                     </td>
659                 [% END %]
660                 </tr>
661             [% END %]
662         </tbody>
663     </table>
664
665 [% END %][%# end of block items_table %]
666
667 [% IF Koha.Preference('EnableItemGroups') %]
668     <div role="tabpanel" class="tab-pane" id="item_groups">
669         [% IF CAN_user_editcatalogue_manage_item_groups %]
670             <div class="item_groups_table_table_controls">
671                 <a href="#" class="item-group-create btn btn-default btn-xs"><i class="fa fa-plus"></i> New item group</a>
672             </div>
673         [% END %]
674         <table class="items-group-table" id="items-group-table">
675             <thead>
676                 <tr>
677                     <th>Display order</th>
678                     <th>Description</th>
679                     <th class="NoSort">&nbsp;</th>
680                 </tr>
681             </thead>
682         </table>
683     </div>
684 [% END %]
685
686
687 <div role="tabpanel" class="tab-pane" id="holdings">
688
689 [% IF ( Koha.Preference('NovelistSelectStaffEnabled') && Koha.Preference('NovelistSelectStaffProfile') && Koha.Preference('NovelistSelectStaffView') == 'above' ) %]
690     <span class="results_summary NovelistSelect" style="display:none;">
691         <span class="label">Novelist Select: </span>
692         <div data-novelist-novelistselect=[% normalized_isbn | html %]></div>
693     </span>
694 [% END %]
695
696 [% IF ( count ) %]
697     [% IF ( showncount ) %]
698         [%# PROCESS items_table tab="holdings" items=itemloop %]
699
700         [% SET tab="holdings" %]
701         <table id="table_items">
702             <thead>
703                 [% IF (StaffDetailItemSelection) %]<th id="[% tab | html %]_checkbox" data-colname="[% tab | html %]_checkbox" class="NoSort"></th>[% END %]
704                 [% IF Koha.Preference('LocalCoverImages') %]
705                     <th id="[% tab | html %]_cover_image" data-colname="[% tab | html %]_cover_image">Cover image</th>
706                 [% END %]
707                 [% IF ( item_level_itypes ) %]<th id="[% tab | html %]_itype" data-colname="[% tab | html %]_itype">Item type</th>[% END %]
708                 <th id="[% tab | html %]_holdingbranch" data-colname="[% tab | html %]_holdingbranch">Current library</th>
709                 <th id="[% tab | html %]_homebranch" data-colname="[% tab | html %]_homebranch">Home library</th>
710                 <th id="[% tab | html %]_ccode" data-colname="[% tab | html %]_ccode">Collection</th>
711                 [% IF Koha.Preference('EnableItemGroups') %]
712                     <th id="[% tab | html %]_item_group" data-colname="[% tab | html %]_item_group">Item group</th>
713                 [% END %]
714                 <th id="[% tab | html %]_itemcallnumber" data-colname="[% tab | html %]_itemcallnumber">Call number</th>
715                 <th id="[% tab | html %]_enumchron" data-colname="[% tab | html %]_enumchron">Serial enumeration / chronology</th>
716                 <th id="[% tab | html %]_status" data-colname="[% tab | html %]_status">Status</th>
717                 <th id="[% tab | html %]_lastseen" data-colname="[% tab | html %]_lastseen">Last seen</th>
718                 <th id="[% tab | html %]_issues" data-colname="[% tab | html %]_issues">Checkouts</th>
719                 <th id="[% tab | html %]_renewals" data-colname="[% tab | html %]_renewals">Renewals</th>
720                 <th id="[% tab | html %]_dateaccessioned" data-colname="[% tab | html %]_dateaccessioned">Date accessioned</th>
721                 <th id="[% tab | html %]_datelastborrowed" data-colname="[% tab | html %]_datelastborrowed">Date last borrowed</th>
722                 <th id="[% tab | html %]_barcode" data-colname="[% tab | html %]_barcode">Barcode</th>
723                 <th id="[% tab | html %]_uri" data-colname="[% tab | html %]_uri">URL</th>
724                 <th id="[% tab | html %]_copynumber" data-colname="[% tab | html %]_copynumber">Copy number</th>
725                 <th id="[% tab | html %]_stocknumber" data-colname="[% tab | html %]_stocknumber">Inventory number</th>
726                 <th id="[% tab | html %]_materials" data-colname="[% tab | html %]_materials">Materials specified</th>
727                 <th id="[% tab | html %]_itemnotes" data-colname="[% tab | html %]_itemnotes">Public notes</th>
728                 <th id="[% tab | html %]_itemnotes_nonpublic" data-colname="[% tab | html %]_itemnotes_nonpublic">Non-public notes</th>
729                 [% IF ( hostrecords ) %]<th id="[% tab | html %]_hostrecord" data-colname="[% tab | html %]_hostrecord">Host records</th>[% END %]
730                 [% IF ( analyze ) %]<th id="[% tab | html %]_usedin" data-colname="[% tab | html %]_usedin">Used in</th><th></th>[% END %]
731                 [% IF ( ShowCourseReserves ) %]<th id="[% tab | html %]_course_reserves" data-colname="[% tab | html %]_course_reserves">Course reserves</th>[% END %]
732                 [% IF ( SpineLabelShowPrintOnBibDetails ) %]<th id="[% tab | html %]_spinelabel" data-colname="[% tab | html %]_spinelabel" class="NoSort">Spine label</th>[% END %]
733                 [% IF ( CAN_user_editcatalogue_edit_items ) %]<th id="[% tab | html %]_actions" data-colname="[% tab | html %]_actions"class="NoSort noExport">&nbsp;</th>[% END %]
734                 </tr>
735             </thead>
736         </table>
737     [% END %]
738
739     [% IF ( hiddencount ) %]
740        <p><a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% biblionumber | uri %]&amp;showallitems=1">Show all items ([% hiddencount | html %] hidden)</a>
741     [% END %]
742 [% ELSE %]
743     [% IF ( ALTERNATEHOLDINGS ) %]
744     [% FOREACH ALTERNATEHOLDING IN ALTERNATEHOLDINGS %]
745         <div id="alternateholdings"><span class="holdings_label">Holdings:</span> [% ALTERNATEHOLDING.holding | html %]</div>
746     [% END %]
747     [% ELSE %]
748     <div id="noitems">No physical items for this record</div>
749     [% END %]
750 [% END %]
751
752 [% IF ( Koha.Preference('NovelistSelectStaffEnabled') && Koha.Preference('NovelistSelectStaffProfile') && Koha.Preference('NovelistSelectStaffView') == 'below' ) %]
753     <span class="results_summary NovelistSelect" style="display:none;">
754         <span class="label">Novelist Select: </span>
755         <div data-novelist-novelistselect=[% normalized_isbn | html %]></div>
756     </span>
757 [% END %]
758     </div>
759
760 [% IF (SeparateHoldings) %]
761     <div role="tabpanel" class="tab-pane" id="otherholdings">
762         [% IF (otheritemloop.size) %]
763             [% PROCESS items_table tab="otherholdings" items=otheritemloop %]
764         [% ELSE %]
765             <span class="nootheritems">No other items.</span>
766         [% END %]
767     </div>
768 [% END %]
769
770 [% IF ( MARCNOTES ) %]
771
772 <div role="tabpanel" class="tab-pane" id="description">
773 <div class="content_set">
774
775     [% FOREACH MARCNOTE IN MARCNOTES %]
776         <p class="marcnote marcnote-[% MARCNOTE.tag | html %]" id="marcnote-[% MARCNOTE.tag | html %]-[% loop.count | html %]">
777             [% IF MARCNOTE.marcnote.match('^https?://\S+$') %]
778                 <a href="[% MARCNOTE.marcnote | url %]">[% MARCNOTE.marcnote | html %]</a>
779             [% ELSE %]
780                 [% MARCNOTE.marcnote | html | html_line_break %]
781             [% END %]
782         </p>
783 [% END %]
784 </div>
785 </div>
786
787 [% END %]
788
789 [% IF ComponentParts && ComponentParts.size %]
790 <div role="tabpanel" class="tab-pane" id="components">
791     <div class="content_set">
792         <table>
793             [% FOR PART IN ComponentParts %]
794             <tr>
795                 <td>
796                     [% PART | $raw %]
797                 </td>
798             </tr>
799             [% END %]
800         </table>
801         [% IF ComponentParts.size == Koha.Preference('MaxComponentRecords')%]
802         <p>Only [% ComponentParts.size | html %] results are shown: <a href="/cgi-bin/koha/catalogue/search.pl?q=[% ComponentPartsQuery | url %]"/>show all component parts</a></p>
803         [% END %]
804     </div> <!-- /.content_set -->
805 </div> <!-- /#components -->
806
807 [% END %]
808
809 [% IF ( subscriptionsnumber ) %]
810 <div role="tabpanel" class="tab-pane" id="subscriptions">
811 <div id="catalogue_detail_subscriptions">
812     <h2>This is a serial subscription</h2>
813     <p> (There are [% subscriptionsnumber | html %] subscriptions associated with this title).</p> 
814     [% FOREACH subscription IN subscriptions %]
815             [% IF subscription.branchcode %]
816                 <h3>At library: [% Branches.GetName(subscription.branchcode) || subscription.branchcode | html %]</h3>
817             [% END %]
818             [% IF ( subscription.closed ) %]<p>This subscription is closed.</p>[% END %]
819             [% IF ( subscription.location ) %]<p class="subscription_location">Location: [% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.location', authorised_value => subscription.location ) | html %]</p>[% END %]
820             [% IF ( subscription.callnumber ) %]<p>Callnumber: [% subscription.callnumber | html %] </p>[% END %]
821             [% IF ( subscription.subscriptionnotes ) %]<p>[% subscription.subscriptionnotes | html | html_line_break %] </p>[% END %]
822             [% IF ( subscription.missinglist ) %]<p>Missing issues: [% subscription.missinglist | html %] </p>[% END %]
823             [% IF ( subscription.librariannote ) %]<p>([% subscription.librariannote | html %])</p>[% END %]
824             [% IF ( subscription.latestserials ) %]
825             <p> The [% subscription.staffdisplaycount | html %] latest issues related to this subscription:</p>
826             <table>
827                 <tr>
828                     <th>Issue #</th>
829                     <th>Date arrived</th>
830                     <th>Date published</th>
831                     <th>Date published (text)</th>
832                     <th>Status</th>
833                     <th>Note</th>
834                 </tr>
835             [% FOREACH latestserial IN subscription.latestserials %]
836                 <tr>
837                     <td>[% latestserial.serialseq | html %]</td>
838                     <td data-order="[% latestserial.planneddate | html %]">[% latestserial.planneddate | $KohaDates %]</td>
839                     <td data-order="[% latestserial.publisheddate | html %]">[% latestserial.publisheddate | $KohaDates %]</td>
840                     <td>[% latestserial.publisheddatetext | html %]</td>
841                     <td>
842                         [% INCLUDE 'serial-status.inc' serial = latestserial %]
843                     </td>
844                     <td>[% latestserial.notes | html %]</td>
845                 </tr>
846             [% END %]
847             </table>
848             [% END %]
849             [% IF ( CAN_user_serials ) %]
850                 <p>
851                     <a class="btn btn-link" href="/cgi-bin/koha/serials/subscription-detail.pl?subscriptionid=[% subscription.subscriptionid | uri %]"><i class="fa fa-list" aria-hidden="true"></i> Subscription details</a>
852                 </p>
853             [% END %]
854     [% END %]
855 </div>
856 </div>
857 [% END %]
858
859 [% IF Koha.Preference('AcquisitionDetails') %]
860 <div role="tabpanel" class="tab-pane" id="acq_details">
861   [% IF orders.count %]
862     <table id="orders">
863       <thead>
864         <tr>
865           <th>Vendor</th>
866           <th>Invoice</th>
867           <th>Basket group</th>
868           <th>Basket</th>
869           <th>Order number</th>
870           <th>Creation date</th>
871           <th>Receive date</th>
872           <th>Status</th>
873           <th>Quantity</th>
874           <th title="Estimated cost tax incl. while pending, actual cost tax incl. once received">Price</th>
875           <th>Internal note</th>
876           <th>Subscription</th>
877           <th>Subscription call number</th>
878         </tr>
879       </thead>
880       <tbody>
881       [% FOR order IN orders %]
882         [% SET basket = order.basket %]
883         [% SET vendor = basket.bookseller %]
884           <tr>
885             <td>
886                 <a href="/cgi-bin/koha/acqui/supplier.pl?booksellerid=[% vendor.id | uri %]" title="Vendor detail page">[% vendor.name | html %]</a>
887             </td>
888             <td>
889             [% IF order.invoiceid %]
890                 [% IF CAN_user_acquisition %]
891                     <div><a href="/cgi-bin/koha/acqui/invoice.pl?invoiceid=[% order.invoiceid | uri %]"
892                        title="Invoice detail page">
893                        [% order.invoice.invoicenumber | html %]</a></div>
894                 [% ELSE %]
895                     <div>[% order.invoice.invoicenumber | html %]</div>
896                 [% END %]
897
898                 [% IF ( Koha.Preference('EDIFACT') && CAN_user_acquisition_edi_manage && order.invoice.message_id ) %]
899                     <div><a href="/cgi-bin/koha/acqui/edimsg.pl?id=[% order.invoice.message_id | uri %]" title="EDI INVOICE message">EDI message</a></div>
900                 [% END %]
901             [% END %]
902             </td>
903             <td>
904             [% IF basket.basketgroupid %]
905                 [% SET basket_group = basket.basket_group %]
906                 [% IF CAN_user_acquisition_group_manage %]
907                     <a href="/cgi-bin/koha/acqui/basketgroup.pl?op=add&booksellerid=[% vendor.id | uri %]&basketgroupid=[% basket_group.id | uri %]">[% basket_group.name | html%] ([% basket_group.id | html %])</a>
908                 [% ELSE %]
909                     [% basket_group.name | html %] ([% basket_group.id | html %])
910                 [% END %]
911             [% END %]
912             </td>
913             <td>[% IF CAN_user_acquisition_order_manage %]
914                 <a href="/cgi-bin/koha/acqui/basket.pl?basketno=[% basket.basketno | uri %]">[% basket.basketname | html %] ([% basket.basketno | html %])</a>
915             [% ELSE %]
916                 [% basket.basketname | html %] ([% basket.basketno | html %])
917             [% END %]</td>
918             <td>[% order.ordernumber | html %]</td>
919             <td data-order="[% basket.creationdate | uri %]">[% basket.creationdate | $KohaDates%]</td>
920             <td data-order="[% order.datereceived | uri %]">[% order.datereceived | $KohaDates%]</td>
921             <td>
922               [% SWITCH order.orderstatus %]
923                 [% CASE 'new' %]<span>New</span>
924                 [% CASE 'ordered' %]<span>Ordered</span>
925                 [% CASE 'partial' %]<span>Partial</span>
926                 [% CASE 'complete' %]<span>Complete</span>
927                 [% CASE 'cancelled' %]<span>Cancelled</span>
928               [% END %]
929             </td>
930             <td>[% order.quantity | html %]</td>
931             <td>[% IF ( order.orderstatus == "complete" ) %][% order.unitprice_tax_included | $Price %][% ELSE %][% order.ecost_tax_included | $Price %][% END %]
932             <td>[% order.order_internalnote | html %]</td>
933             <td>
934                 [% IF order.subscriptionid %]
935                     <a href="/cgi-bin/koha/serials/subscription-detail.pl?subscriptionid=[% order.subscriptionid | uri %]">[% order.subscriptionid | html %]</a>
936                 [% END %]
937             </td>
938             <td>
939                 [% IF order.subscriptionid %]
940                     [% order.subscription.callnumber | html %]
941                 [% END %]
942             </td>
943           </tr>
944       [% END %]
945       </tbody>
946     </table>
947   [% ELSE %]
948     <span class="noorder">There is no order for this bibliographic record.</span>
949   [% END %]
950 </div>
951 [% END %]
952
953 [% IF suggestions.count %]
954     <div role="tabpanel" class="tab-pane" id="suggestion_details">
955         [% IF nb_archived_suggestions > 0 %]
956             <p>[% tnpx('pluralization', 'There is one archived suggestion.', 'There are {count} archived suggestions.', nb_archived_suggestions, { count = nb_archived_suggestions }) | $raw  %]
957         [% END %]
958         <table id="suggestions" class="sorted">
959             <thead>
960                 <tr>
961                     <th class="NoSort">&nbsp;</th>
962                     <th class="anti-the">Suggestion</th>
963                     <th>Suggested by - on</th>
964                     <th>Managed by - on</th>
965                     <th>Last modification by - on</th>
966                     <th>Library</th>
967                     <th>Fund</th>
968                     <th>Status</th>
969                 </tr>
970             </thead>
971             <tbody>
972             [% FOREACH suggestion IN suggestions %]
973                 <tr>
974                     <td>[% suggestion.suggestionid | html %]</td>
975                     <td>
976                         <a href="/cgi-bin/koha/suggestion/suggestion.pl?suggestionid=[% suggestion.suggestionid | uri %]&amp;op=show" title="suggestion" >
977                             [% suggestion.title | html %][% IF ( suggestion.author ) %], by [% suggestion.author | html %][% END %]</a>
978                         <br />
979                         [% IF ( suggestion.copyrightdate ) %]&copy; [% suggestion.copyrightdate | html %] [% END %]
980                         [% IF ( suggestion.volumedesc ) %]; Volume:<em>[% suggestion.volumedesc | html %]</em> [% END %]
981                         [% IF ( suggestion.isbn ) %]; ISBN:<em>[% suggestion.isbn | html %]</em> [% END %][% IF ( suggestion.publishercode ) %]; Published by [% suggestion.publishercode | html %] [% END %][% IF ( suggestion.publicationyear ) %] in <em>[% suggestion.publicationyear | html %]</em> [% END %][% IF ( suggestion.place ) %] in <em>[% suggestion.place | html %]</em> [% END %][% IF ( suggestion.collectiontitle ) %]; [% suggestion.collectiontitle | html %] [% END %][% IF ( suggestion.itemtype ) %]; [% AuthorisedValues.GetByCode( 'SUGGEST_FORMAT', suggestion.itemtype, 0 ) | html %] [% END %]<br />[% IF ( suggestion.note ) %]<div class="suggestion_note"><i class="fa fa-comment"></i> [% suggestion.note | html %]</div>[% END %]
982                     </td>
983                     <td>
984                         <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% suggestion.suggestedby | uri %]">[% INCLUDE 'patron-title.inc' patron => suggestion.suggester %]</a>
985                         [% IF suggestion.suggesteddate %] - [% suggestion.suggesteddate | $KohaDates %][% END %]
986                     </td>
987                     <td>
988                         <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% suggestion.managedby | uri %]">[% INCLUDE 'patron-title.inc' patron => suggestion.manager %]</a>
989                         [% IF suggestion.manageddate %] - [% suggestion.manageddate | $KohaDates %][% END %]
990                     </td>
991                     <td>
992                         <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% suggestion.lastmodificationby | uri %]">[% INCLUDE 'patron-title.inc' patron => suggestion.last_modifier %]</a>
993                         [% IF suggestion.lastmodificationdate %] - [% suggestion.lastmodificationdate | $KohaDates %][% END %]
994                     </td>
995                     <td>
996                         [% Branches.GetName( suggestion.branchcode ) | html %]
997                     </td>
998                     <td>
999                         [% suggestion.fund.budget_name | html %]
1000                     </td>
1001                     <td>
1002                         [% IF    suggestion.STATUS == 'ASKED'     %]<span>Pending</span>
1003                         [% ELSIF suggestion.STATUS == 'ACCEPTED'  %]<span>Accepted</span>
1004                         [% ELSIF suggestion.STATUS == 'ORDERED'   %]<span>Ordered</span>
1005                         [% ELSIF suggestion.STATUS == 'REJECTED'  %]<span>Rejected</span>
1006                         [% ELSIF suggestion.STATUS == 'CHECKED'   %]<span>Checked</span>
1007                         [% ELSIF suggestion.STATUS == 'AVAILABLE' %]<span>Available</span>
1008                         [% ELSIF AuthorisedValues.GetByCode( 'SUGGEST_STATUS', suggestion.STATUS ) %]
1009                             [% AuthorisedValues.GetByCode( 'SUGGEST_STATUS', suggestion.STATUS ) | html %]
1010                         [% ELSE %]<span>Status unknown</span>
1011                         [% END %]
1012                         [% IF suggestion.reason %]
1013                             <br />([% suggestion.reason | html %])
1014                         [% END %]
1015                     </td>
1016                 </tr>
1017                 [% END %]
1018             </tbody>
1019         </table>
1020     </div>
1021 [% END %]
1022
1023 [% IF ( FRBRizeEditions ) %][% IF ( XISBNS ) %]
1024 <div role="tabpanel" class="tab-pane" id="editions"><h4>Editions</h4>
1025 <table>
1026 [% FOREACH XISBN IN XISBNS %]<tr>[% IF ( AmazonCoverImages ) %]<td><a href="http://www.amazon.com/gp/reader/[% XISBN.normalized_isbn | uri %][% AmazonAssocTag | uri %]#reader-link"><img src="https://images-na.ssl-images-amazon.com/images/P/[% XISBN.normalized_isbn | html %].01._AA75_PU_PU-5_.jpg" /></a></td>[% END %]
1027 [% IF ( !item_level_itypes || Koha.Preference('BiblioItemtypeInfo') ) %]<td>[% IF ( noItemTypeImages ) %]<span class="itypetext">[% XISBN.description | html %]</span>[% ELSE %]<img src="[% XISBN.imageurl | html %]" alt="[% XISBN.description | html %]" title="[% XISBN.description | html %]">[% END %]</td>[% END %]
1028 <td><a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% XISBN.biblionumber | uri %]">[% XISBN.title | html %]</a> <span>by</span> [% XISBN.author | html %] &copy;[% XISBN.copyrightdate | html %]
1029   [% IF ( XISBN.publishercode ) %]
1030 [% XISBN.publishercode | html %] [% IF ( XISBN.place ) %]([% XISBN.place | html %])[% END %] [% IF ( XISBN.publicationyear ) %], [% XISBN.publicationyear | html %][% END %] [% IF ( XISBN.editionstatement ) %][% XISBN.editionstatement | html %][% END %] [% IF ( XISBN.editionresponsibility ) %][% XISBN.editionresponsibility | html %][% END %]
1031     [% END %]
1032                 [% IF ( XISBN.pages ) %] [% END %][% XISBN.pages | html %] [% IF ( XISBN.illus ) %][% XISBN.illus | html %][% END %]
1033                 [% IF ( XISBN.size ) %], [% END %][% XISBN.size | html %]
1034 </td>
1035
1036 [% END %]
1037 </table></div>[% END %]
1038 [% END %]
1039
1040 [% IF ( ( Koha.Preference('CatalogConcerns') || Koha.Preference('OpacCatalogConcerns') ) && CAN_user_editcatalogue_edit_catalogue ) %]
1041 <div role="tabpanel" class="tab-pane" id="concerns">
1042     <fieldset class="action" style="cursor:pointer;">
1043         <a id="hideResolved"><i class="fa fa-minus-square"></i> Hide resolved</a>
1044         | <a id="showAll"><i class="fa fa-bars"></i> Show all</a>
1045     </fieldset>
1046
1047     <table id="table_concerns" width="100%">
1048         <thead>
1049             <tr>
1050                 <th>Reported</th>
1051                 <th>Details</th>
1052                 <th>Status</th>
1053                 <th data-class-name="actions noExport">Actions</th>
1054             </tr>
1055         </thead>
1056     </table>
1057 </div>
1058 [% END %]
1059
1060 [% IF ( LocalCoverImages ) %]
1061     <div role="tabpanel" class="tab-pane" id="images">
1062         [% IF localimages.count %]
1063             <p>Click on an image to view it in the image viewer</p>
1064             <ul class="thumbnails">
1065                 [% FOREACH image IN localimages %]
1066                     [% IF image %]
1067                         <li id="imagenumber-[% image.imagenumber | html %]" class="thumbnail">
1068                             <a href="/cgi-bin/koha/catalogue/imageviewer.pl?biblionumber=[% biblionumber | uri %]&amp;imagenumber=[% image.imagenumber | uri %]">
1069                                 <img src="/cgi-bin/koha/catalogue/image.pl?thumbnail=1&amp;imagenumber=[% image.imagenumber | uri %]" />
1070                             </a>
1071                             [% IF CAN_user_tools_upload_local_cover_images %]
1072                                 <a href="#" class="remove"><i class="fa fa-trash-can"></i> Delete image</a>
1073                             [% END %]
1074                         </li>
1075                     [% END %]
1076                 [% END %]
1077             </ul>
1078         [% ELSE # - No image passed JavaScript takes care %]
1079             <span class="noimagesuploaded">No images have been uploaded for this bibliographic record yet.</span>
1080         [% END %]
1081         [% IF ( CAN_user_tools_upload_local_cover_images ) %]
1082             <p>Upload an image file: <a class="btn btn-default btn-xs" href="/cgi-bin/koha/tools/upload-cover-image.pl?biblionumber=[% biblionumber | uri %]&amp;filetype=image"><i class="fa fa-upload" aria-hidden="true"></i> Upload</a>
1083             </p>
1084         [% END %]
1085     </div>
1086 [% END %]
1087
1088 [% IF ( HTML5MediaEnabled ) %]
1089 <div role="tabpanel" class="tab-pane" id="html5media">
1090           [% FOREACH HTML5MediaSet IN HTML5MediaSets %]
1091             <p>
1092                 [% IF HTML5MediaSet.is_youtube %]
1093                     <iframe id="player" width="640" height="360" src="[% HTML5MediaSet.srcblock | url %]"></iframe>
1094                 [% ELSE %]
1095                   <[% HTML5MediaParent | html %] controls preload=none>
1096                     <[% HTML5MediaSet.child | html %] src="[% HTML5MediaSet.srcblock | url %]"[% HTML5MediaSet.typeblock | html %] />
1097                     [[% HTML5MediaParent | html %] tag not supported by your browser.]
1098                   </[% HTML5MediaParent | html %]>
1099                 [% END %]
1100             </p>
1101           [% END %]
1102 </div>
1103 [% END %]
1104
1105
1106 [% IF ( Koha.Preference('NovelistSelectStaffEnabled') && Koha.Preference('NovelistSelectStaffProfile') && Koha.Preference('NovelistSelectStaffView') == 'tab' ) %]
1107     <div role="tabpanel" class="tab-pane" id="NovelistSelect" class="novelistSelect">
1108         <div data-novelist-novelistselect=[% normalized_isbn | html %]></div>
1109     </div>
1110 [% END %]
1111
1112 [% FOREACH plugins_intranet_catalog_biblio_tab IN plugins_intranet_catalog_biblio_tabs %]
1113     <div role="tabpanel" class="tab-pane" id="[% plugins_intranet_catalog_biblio_tab.id | html %]">
1114         [% plugins_intranet_catalog_biblio_tab.content | $raw %]
1115     </div>
1116 [% END %]
1117
1118 </div><!-- /tab-content -->
1119 </div><!-- /bibliodetails -->
1120
1121 <div id="export" style="margin-top: 1em;">
1122 <form method="get" action="/cgi-bin/koha/catalogue/export.pl">
1123 <table>  <tr>
1124       <th>Save record</th>   </tr>
1125     <tr><td> Select download format:    <select name="format">
1126         <option value="mods">MODS (XML)</option>
1127         <option data-toggle="modal" data-target="#exportModal_">Dublin Core</option>
1128         <option value="marcxml">MARCXML</option>
1129         <option value="marc8">MARC (non-Unicode/MARC-8)</option>
1130         <option value="utf8">MARC (Unicode/UTF-8)</option>    </select>
1131         <input type="submit" name="save" class="btn btn-primary" value="Download record" /></td>
1132   </tr>
1133   <tr><td>
1134     <input type="hidden" name="op" value="export" /><input type="hidden" name="bib" value="[% biblionumber | html %]" />
1135   </td></tr>
1136 </table>
1137 </form>
1138 </div>
1139
1140 <div id="marcPreview" class="modal" tabindex="-1" role="dialog" aria-labelledby="marcPreviewLabel" aria-hidden="true">
1141     <div class="modal-dialog modal-lg">
1142     <div class="modal-content">
1143     <div class="modal-header">
1144         <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button>
1145         <h3 id="marcPreviewLabel">MARC preview</h3>
1146     </div>
1147     <div class="modal-body">
1148         <div id="loading"> <img src="[% interface | html %]/[% theme | html %]/img/spinner-small.gif" alt="" /> Loading </div>
1149     </div>
1150     <div class="modal-footer">
1151         <button class="btn btn-default" data-dismiss="modal" aria-hidden="true">Close</button>
1152     </div>
1153     </div>
1154     </div>
1155 </div>
1156
1157 <div id="elasticPreview" class="modal" tabindex="-1" role="dialog" aria-labelledby="elasticPreviewLabel" aria-hidden="true">
1158     <div class="modal-dialog modal-lg">
1159     <div class="modal-content">
1160     <div class="modal-header">
1161         <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button>
1162         <h3 id="elasticPreviewLabel">Elasticsearch record</h3>
1163     </div>
1164     <div class="modal-body">
1165         <div id="loading"> <img src="[% interface | html %]/[% theme | html %]/img/spinner-small.gif" alt="" /> Loading </div>
1166     </div>
1167     <div class="modal-footer">
1168         <button class="btn btn-default" data-dismiss="modal" aria-hidden="true">Close</button>
1169     </div>
1170     </div>
1171     </div>
1172 </div>
1173
1174             </main>
1175         </div> <!-- /.col-sm-10.col-sm-push-2 -->
1176
1177         <div class="col-sm-2 col-sm-pull-10">
1178             <aside>
1179                 [% INCLUDE 'biblio-view-menu.inc' %]
1180             </aside>
1181         </div> <!-- /.col-sm-2.col-sm-pull-10 -->
1182      </div> <!-- /.row -->
1183
1184 [% END %]
1185
1186 <div class="modal fade" id="modal-item-group-create" tabindex="-1" role="dialog" aria-labelledby="modal-item-group-create-label">
1187     <div class="modal-dialog">
1188         <div class="modal-content">
1189             <div class="modal-header">
1190                 <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button>
1191                 <h3 id="modal-item-group-create-label"><i class="fa fa-plus"></i> Create a new item group</h3>
1192             </div>
1193             <form method="get" id="modal-item-group-create-form" class="validated">
1194                 <div class="modal-body">
1195                     <fieldset>
1196                         <p>
1197                             <label for="item_group_description" class="required">Name: </label>
1198                             <input name="description" id="modal-item-group-create-form-description" type="text" size="30" required="required" class="required" />
1199                             <span class="required">Required</span>
1200                         </p>
1201                         <p>
1202                             <label for="item_group_display_order" class="required">Display order: </label>
1203                             <input name="display_order" id="modal-item-group-create-form-display_order" value="0" size="5" required="required" class="required" />
1204                             <span class="required">Required</span>
1205                             <br/>
1206                             <span class="hint">Numbers only, item groups will be displayed in counting order</span>
1207                         </p>
1208                     </fieldset>
1209                 </div>
1210                 <div class="modal-footer">
1211                     <button id="modal-item-group-create-submit" class="btn btn-default"><i class="fa fa-plus"></i> Submit</button>
1212                     <button class="btn btn-link" data-dismiss="modal" aria-hidden="true">Cancel</button>
1213                 </div>
1214             </form>
1215         </div>
1216     </div>
1217 </div>
1218
1219 <div class="modal fade" id="modal-item-group-edit" tabindex="-1" role="dialog" aria-labelledby="modal-item-group-edit-label">
1220     <div class="modal-dialog">
1221         <div class="modal-content">
1222             <div class="modal-header">
1223                 <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button>
1224                 <h3 id="modal-item-group-edit-label"><i class="fa-solid fa-pencil" aria-hidden="true"></i> Edit item group</h3>
1225             </div>
1226             <form method="get" id="modal-item-group-edit-form" class="validated">
1227                 <div class="modal-body">
1228                     <fieldset>
1229                         <p>
1230                             <label for="item_group_description" class="required">Name: </label>
1231                             <input name="description" id="modal-item-group-edit-form-description" type="text" size="30" required="required" class="required" />
1232                             <span class="required">Required</span>
1233                         </p>
1234                         <p>
1235                             <label for="item_group_display_order" class="required">Sort order: </label>
1236                             <input name="display_order" id="modal-item-group-edit-form-display_order" size="5" />
1237                             <span class="hint">Numbers only, item groups will be displayed in counting order</span>
1238                         </p>
1239                     </fieldset>
1240                 </div>
1241                 <div class="modal-footer">
1242                     <button id="modal-item-group-edit-submit" class="btn btn-default"><i class="fa-solid fa-pencil" aria-hidden="true"></i> Submit</button>
1243                     <button class="btn btn-link" data-dismiss="modal" aria-hidden="true">Cancel</button>
1244                 </div>
1245             </form>
1246         </div>
1247     </div>
1248 </div>
1249
1250 <div class="modal fade" id="modal-item-group-delete" tabindex="-1" role="dialog" aria-labelledby="modal-item-group-delete-label">
1251     <div class="modal-dialog">
1252         <div class="modal-content">
1253             <div class="modal-header">
1254                 <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button>
1255                 <h3 id="modal-item-group-delete-label"><i class='fa fa-trash-can'></i> Delete item group</h3>
1256             </div>
1257             <div class="modal-body">
1258                 Are you sure you want to delete this item group?
1259             </div>
1260             <div class="modal-footer">
1261                 <button id="modal-item-group-delete-submit" class="btn btn-danger"><i class='fa fa-trash-can'></i> Delete</button>
1262                 <button class="btn btn-link" data-dismiss="modal" aria-hidden="true">Cancel</button>
1263             </div>
1264         </div>
1265     </div>
1266 </div>
1267
1268 <div class="modal fade" id="modal-item-group-set" tabindex="-1" role="dialog" aria-labelledby="modal-item-group-set-label">
1269     <div class="modal-dialog">
1270         <div class="modal-content">
1271             <div class="modal-header">
1272                 <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button>
1273                 <h3 id="modal-item-group-set-label"><i class='fa fa-book'></i> Set item group for items</h3>
1274             </div>
1275             <form method="get" id="modal-item-group-set-form" class="validated">
1276                 <div class="modal-body">
1277                     <fieldset>
1278                         <p>
1279                             <label for="item_group" class="required">Item group: </label>
1280                             <select name="item_group" id="item-group-add-form-select">
1281                                 [% FOREACH ig IN biblio.item_groups.search({}, {order_by => 'display_order'}) %]
1282                                     <option value="[% ig.id | html %]">[% ig.description | html %]</option>
1283                                 [% END %]
1284                             </select>
1285                             <span class="required">Required</span>
1286                         </p>
1287                     </fieldset>
1288                 </div>
1289                 <div class="modal-footer">
1290                     <button id="modal-item-group-set-submit" class="btn btn-default"><i class='fa fa-book'></i> Set item group</button>
1291                     <button class="btn btn-link" data-dismiss="modal" aria-hidden="true">Cancel</button>
1292                 </div>
1293             </form>
1294         </div>
1295     </div>
1296 </div>
1297
1298 <div class="modal fade" id="modal-item-group-unset" tabindex="-1" role="dialog" aria-labelledby="modal-item-group-unset-label">
1299     <div class="modal-dialog">
1300         <div class="modal-content">
1301             <div class="modal-header">
1302                 <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button>
1303                 <h3 id="modal-item-group-unset-label"><i class='fa fa-unlink'></i> Remove item from item group</h3>
1304             </div>
1305             <div class="modal-body">
1306                 Are you sure you want to remove these item(s) from their item group(s)?
1307             </div>
1308             <div class="modal-footer">
1309                 <button id="modal-item-group-unset-submit" class="btn btn-danger"><i class='fa fa-unlink'></i> Remove</button>
1310                 <button class="btn btn-link" data-dismiss="modal" aria-hidden="true">Cancel</button>
1311             </div>
1312         </div>
1313     </div>
1314 </div>
1315
1316     [% IF bundlesEnabled %]
1317     <div class="modal" id="addToBundleModal" tabindex="-1" role="dialog" aria-labelledby="addToBundleLabel">
1318         <form method="get" id="addToBundleForm" action="">
1319             <div class="modal-dialog" role="document">
1320                 <div class="modal-content">
1321                     <div class="modal-header">
1322                         <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button>
1323                         <h3 id="addToBundleLabel">Add to bundle</h3>
1324                     </div>
1325                     <div class="modal-body">
1326                         <div id="addResult"></div>
1327                         <fieldset class="rows">
1328                             <ol>
1329                                 <li>
1330                                     <label class="required" for="external_id">Item barcode: </label>
1331                                     <input type="text" id="external_id" name="external_id" required="required">
1332                                     <span class="required">Required</span>
1333                                 </li>
1334                             </ol>
1335                         </fieldset>
1336                     </div>
1337                     <div class="modal-footer">
1338                         <button type="submit" class="btn btn-default">Submit</button>
1339                         <button class="btn btn-default" data-dismiss="modal" aria-hidden="true">Close</button>
1340                     </div>
1341                 </div>
1342             </div>
1343         </form>
1344     </div>
1345
1346     <div class="modal" id="removeFromBundleModal" tabindex="-1" role="dialog" aria-labelledby="removeFromBundleLabel">
1347         <form method="get" id="removeFromBundleForm" action="">
1348             <div class="modal-dialog" role="document">
1349                 <div class="modal-content">
1350                     <div class="modal-header">
1351                         <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button>
1352                         <h3 id="removeFromBundleLabel">Remove from bundle</h3>
1353                     </div>
1354                     <div class="modal-body">
1355                         <div id="removeResult"></div>
1356                         <fieldset class="rows">
1357                             <ol>
1358                                 <li>
1359                                     <label class="required" for="external_id">Item barcode: </label>
1360                                     <input type="text" id="rm_external_id" name="external_id" required="required">
1361                                     <span class="required">Required</span>
1362                                 </li>
1363                             </ol>
1364                         </fieldset>
1365                     </div>
1366                     <div class="modal-footer">
1367                         <button type="submit" class="btn btn-default">Submit</button>
1368                         <button class="btn btn-default" data-dismiss="modal" aria-hidden="true">Close</button>
1369                     </div>
1370                 </div>
1371             </div>
1372         </form>
1373     </div>
1374     [% END %]
1375
1376     [% IF ( Koha.Preference('CatalogConcerns') ) %]
1377     [% INCLUDE 'modals/add_catalog_concern.inc' %]
1378     [% END %]
1379
1380     [% IF ( ( Koha.Preference('CatalogConcerns') || Koha.Preference('OpacCatalogConcerns') ) && CAN_user_editcatalogue_edit_catalogue ) %]
1381     [% INCLUDE 'modals/display_ticket.inc' %]
1382     [% END %]
1383
1384 [% MACRO jsinclude BLOCK %]
1385     [% INCLUDE 'catalog-strings.inc' %]
1386     [% INCLUDE 'calendar.inc' %]
1387     [% INCLUDE 'select2.inc' %]
1388     [% INCLUDE 'js-date-format.inc' %]
1389     [% Asset.js("js/catalog.js") | $raw %]
1390     [% Asset.js("js/recalls.js") | $raw %]
1391     [% Asset.js("js/coce.js") | $raw %]
1392     [% Asset.js("lib/Chocolat/js/chocolat.js") | $raw %]
1393     [% IF ( Koha.Preference('CatalogConcerns') ) %]
1394         <script>
1395             /* Set a variable needed by add_catalog_concern.js */
1396             var logged_in_user_borrowernumber = "[% logged_in_user.borrowernumber | html %]";
1397         </script>
1398         [% Asset.js("js/modals/add_catalog_concern.js") | $raw %]
1399      [% END %]
1400      [% IF ( ( Koha.Preference('CatalogConcerns') || Koha.Preference('OpacCatalogConcerns') ) && CAN_user_editcatalogue_edit_catalogue ) %]
1401          <script>
1402             $(document).ready(function() {
1403                 var table_settings = [% TablesSettings.GetTableSettings( 'cataloguing', 'concerns', 'table_concerns', 'json' ) | $raw %];
1404
1405                 var filtered = false;
1406                 let additional_filters = {
1407                     resolved_date: function(){
1408                         if ( filtered ) {
1409                             return { "=": null };
1410                         } else {
1411                             return;
1412                         }
1413                     },
1414                     biblio_id: [% biblionumber | uri %]
1415                 };
1416
1417                 var tickets_url = '/api/v1/tickets';
1418                 var tickets = $("#table_concerns").kohaTable({
1419                     "ajax": {
1420                         "url": tickets_url
1421                     },
1422                     "embed": [
1423                         "reporter",
1424                         "resolver",
1425                         "updates+count",
1426                     ],
1427                     'emptyTable': '<div class="dialog message">' + _("Congratulations, there are no catalog concerns.") + '</div>',
1428                     "columnDefs": [ {
1429                         "targets": [0,1,2],
1430                         "render": function (data, type, row, meta) {
1431                             if ( type == 'display' ) {
1432                                 if ( data != null ) {
1433                                     return data.escapeHtml();
1434                                 }
1435                                 else {
1436                                     return "";
1437                                 }
1438                             }
1439                             return data;
1440                         }
1441                     } ],
1442                     "columns": [
1443                         {
1444                             "data": "reported_date:reporter.firstname",
1445                             "render": function(data, type, row, meta) {
1446                                 let reported = '<span class="date clearfix">' + $datetime(row.reported_date) + '</span>';
1447                                 reported += '<span class="reporter clearfix">' + $patron_to_html(row.reporter, {
1448                                     display_cardnumber: false,
1449                                     url: true
1450                                 }) + '</span>';
1451                                 return reported;
1452                             },
1453                             "searchable": true,
1454                             "orderable": true
1455                         },
1456                         {
1457                             "data": "title:body",
1458                             "render": function(data, type, row, meta) {
1459                                 let resolved = ( row.resolved_date ) ? true : false;
1460                                 let result = '<a role="button" href="#" data-toggle="modal" data-target="#ticketDetailsModal" data-concern="' + encodeURIComponent(row.ticket_id) + '" data-resolved="' + resolved + '">' + row.title + '</a>';
1461                                 if (row.updates_count) {
1462                                     result += '<span class="pull-right"><a role="button" href="#" data-toggle="modal" data-target="#ticketDetailsModal" data-concern="' + encodeURIComponent(row.ticket_id) + '"><i class="fa fa-comment" aria-hidden="true"></i> ' + row.updates_count + '</a></span>';
1463                                 }
1464                                 result += '<div id="detail_' + row.ticket_id + '" class="hidden">' + row.body + '</div>';
1465                                 return result;
1466                             },
1467                             "searchable": true,
1468                             "orderable": true
1469                         },
1470                         {
1471                             "data": "resolved_date",
1472                             "render": function(data, type, row, meta) {
1473                                 let result = '';
1474                                 if (row.resolved_date) {
1475                                     result += _("Resolved by:") + ' <span>' + $patron_to_html(row.resolver, {
1476                                         display_cardnumber: false,
1477                                         url: true
1478                                     }) + '</span>';
1479                                     result += '<span class="clearfix">' + $datetime(row.resolved_date) + '</span>';
1480                                 } else {
1481                                     result += _("Open");
1482                                 }
1483                                 return result;
1484                             },
1485                             "searchable": true,
1486                             "orderable": true
1487                         },
1488                         {
1489                             "data": function(row, type, val, meta) {
1490                                 let resolved = ( row.resolved_date ) ? true : false;
1491                                 let result = '<a class="btn btn-default btn-xs" role="button" href="#" data-toggle="modal" data-target="#ticketDetailsModal" data-concern="' + encodeURIComponent(row.ticket_id) + '" data-resolved="' + resolved + '"><i class="fa-solid fa-eye" aria-hidden="true"></i> ' + _("Details") + '</a>';
1492                                 return result;
1493                             },
1494                             "searchable": false,
1495                             "orderable": false
1496                         },
1497                     ]
1498                 }, table_settings, 0, additional_filters);
1499
1500                 $('#hideResolved').on("click", function() {
1501                     filtered = true;
1502                     tickets.DataTable().draw();
1503                 });
1504
1505                 $('#showAll').on("click", function() {
1506                     filtered = false;
1507                     tickets.DataTable().draw();
1508                 });
1509             });
1510         </script>
1511         [% Asset.js("js/modals/display_ticket.js") | $raw %]
1512     [% END %]
1513     <script>
1514         var interface = "[% interface | html %]";
1515         var theme = "[% theme | html %]";
1516         // http://www.oreillynet.com/pub/a/javascript/2003/10/21/amazonhacks.html
1517         function verify_cover_images() {
1518             // Loop over each container in the template which contains covers
1519             $(".cover-slider").each(function(){
1520                 var lightbox_descriptions = [];
1521                 var first_shown = 0;
1522                 $(this).find(".cover-image").each( function( index ){
1523                 var div = $(this);
1524                 // Find the image in the container
1525                 var img = div.find("img")[0];
1526                 if( $(img).length > 0 ){
1527                     var description = "";
1528                         // All slides start hidden. If this is the first one, show it.
1529                         if( first_shown == 0 ){
1530                             div.show();
1531                             first_shown = 1;
1532                         }
1533                         // Check if Amazon image is present
1534                         if ( div.attr("id") == "amazon-bookcoverimg"  ) {
1535                             w = img.width;
1536                             h = img.height;
1537                             if ((w == 1) || (h == 1)) {
1538                                 // Amazon returned single-pixel placeholder
1539                                 // Remove the container
1540                                 div.remove();
1541                             } else {
1542                                 lightbox_descriptions.push(_("Amazon cover image (<a href='%s'>see the original image</a>)").format($(img).data('link')));
1543                             }
1544                         } else if( div.attr("id") == "custom-coverimg" ){
1545                             if ( (img.complete != null) && (!img.complete) || img.naturalHeight == 0 ) {
1546                                 // No image was loaded via the CustomCoverImages system preference
1547                                 // Remove the container
1548                                 div.remove();
1549                             } else {
1550                                 lightbox_descriptions.push( _("Custom cover image") );
1551                             }
1552                         } else if ( div.attr("id") == "syndetics-bookcoverimg" ){
1553                                 lightbox_descriptions.push(_("Syndetics cover image (<a href='%s'>see the original image</a>)").format($(img).data('link')));
1554                         }
1555                         else if( div.hasClass("coce-coverimg" ) ){
1556                             // Identify which service's image is being loaded by Coce
1557                             var coce_description;
1558                             if( $(img).attr("src").indexOf('amazon.com') >= 0 ){
1559                                 coce_description = _("Coce image from Amazon.com");
1560                             } else if( $(img).attr("src").indexOf('google.com') >= 0 ){
1561                                 coce_description = _("Coce image from Google Books");
1562                             } else if( $(img).attr("src").indexOf('openlibrary.org') >= 0 ){
1563                                 coce_description = _("Coce image from Open Library");
1564                             }
1565                             div.find(".hint").html(coce_description);
1566                             lightbox_descriptions.push(coce_description);
1567                         } else if ( div.attr("class") == "cover-image local-coverimg" ) {
1568                             lightbox_descriptions.push(_("Local cover image (<a href='%s'>edit</a>)").format($(img).data('link')));
1569                         } else {
1570                             lightbox_descriptions.push(_("Cover image source unknown"));
1571                         }
1572                     }
1573                 });
1574
1575                 // Lightbox for cover images
1576                 Chocolat(this.querySelectorAll('.cover-image a'), {
1577                     description: function(){
1578                         return lightbox_descriptions[this.settings.currentImageIndex];
1579                     }
1580                 });
1581
1582             });
1583
1584             $(".cover-slider").each(function(){
1585                 var coverSlide = this;
1586                 var coverImages = $(this).find(".cover-image");
1587                 if( coverImages.length > 1 ){
1588                     coverImages.each(function( index ){
1589                         // If more that one image is present, add a navigation link
1590                         // for activating the slide
1591                         var covernav = $("<a href=\"#\" data-num=\"" + index + "\" class=\"cover-nav\"></a>");
1592                         if( index == 0 ){
1593                             // Set the first navigation link as active
1594                             $(covernav).addClass("nav-active");
1595                         }
1596                         $(covernav).html("<i class=\"fa fa-circle\"></i>");
1597                         $(coverSlide).append( covernav );
1598                     });
1599                 }
1600
1601                 if( $(coverSlide).attr('id') == 'biblio-cover-slider' // Hide if not visible, but only for the biblio images. Images for items are only local cover images
1602                     && $(coverSlide).find(".cover-image:visible").length < 1 ){
1603                     $(coverSlide).remove();
1604                 } else {
1605                     $(coverSlide).addClass("cover-slides");
1606                     var img = $(coverSlide).find(".cover-image:visible").find("img")[0];
1607                     if( $(img).length > 0 && img.complete && img.naturalHeight > 0 ){
1608                         $(".cover-slides").css({"background-image":"none"});
1609                     }
1610                 }
1611             });
1612
1613             $("#editions img").each(function(i){
1614                 if ( this.src.indexOf('amazon.com') >= 0 ) {
1615                     w = this.width;
1616                     h = this.height;
1617                     if ((w == 1) || (h == 1)) {
1618                         this.src = 'https://images-na.ssl-images-amazon.com/images/G/01/x-site/icons/no-img-sm.gif';
1619                     } else if ( (this.complete != null) && (!this.complete) || this.naturalHeight == 0 ) {
1620                         this.src = 'https://images-na.ssl-images-amazon.com/images/G/01/x-site/icons/no-img-sm.gif';
1621                     }
1622                 }
1623             });
1624         }
1625
1626         function removeLocalImage(imagenumber) {
1627             var thumbnail = $("#imagenumber-" + imagenumber );
1628             var copy = thumbnail.html();
1629             thumbnail.find("img").css("opacity", ".2");
1630             thumbnail.find("a.remove").html("<img style='display:inline-block' src='" + interface + "/" + theme + "/img/spinner-small.gif' alt='' />");
1631             const client = APIClient.cover_image;
1632             client.cover_images.delete(imagenumber).then(
1633                 success => {
1634                     if ( success.deleted == 1 ) {
1635                         thumbnail.remove();
1636                     } else {
1637                         thumbnail.html( copy );
1638                         alert(_("An error occurred on deleting this image"));
1639                     }
1640                     if ( $('ul.thumbnails > li').length == 0 ) {
1641                         showNoImageMessage();
1642                     }
1643                 },
1644                 error => {
1645                     thumbnail.html( copy );
1646                     alert(_("An error occurred on deleting this image"));
1647                     console.warn("Something wrong happened: %s".format(error));
1648                 }
1649             );
1650         }
1651
1652         function showNoImageMessage() {
1653             var no_images_msg = _("No images have been uploaded for this bibliographic record yet.");
1654             no_images_msg = '<p>' + no_images_msg + '</p>';
1655             [% IF ( CAN_user_tools_upload_local_cover_images ) %]
1656                 var please_upload = _("Upload an image file: %sUpload%s").format("<a class='btn btn-default btn-xs' href='/cgi-bin/koha/tools/upload-cover-image.pl?biblionumber=" + biblionumber + "&amp;filetype=image'><i class='fa fa-upload' aria-hidden='true'></i> ","</a>");
1657                 no_images_msg += "<p id='upload_image'>" + please_upload + '</p>';
1658             [% END %]
1659             $('#images').html(no_images_msg);
1660         }
1661
1662         [% IF StaffDetailItemSelection %]
1663             function itemSelectionBuildDeleteLink(div) {
1664                 var itemnumbers = new Array();
1665                 $("input[name='itemnumber'][type='checkbox']:checked", div).each(function() {
1666                     itemnumbers.push($(this).val());
1667                 });
1668                 if (itemnumbers.length > 0) {
1669                     var url = '/cgi-bin/koha/tools/batchMod.pl?op=show&del=1';
1670                     url += '&itemnumber=' + itemnumbers.join('&itemnumber=');
1671                     url += '&biblionumber=[% biblionumber | uri %]';
1672                     url += '&src=CATALOGUING';
1673                     $('a.itemselection_action_delete').attr('href', url);
1674                 } else {
1675                     return false;
1676                 }
1677                 return true
1678             }
1679
1680             function itemSelectionBuildModifyLink(div) {
1681                 var itemnumbers = new Array();
1682                 $("input[name='itemnumber'][type='checkbox']:checked", div).each(function() {
1683                     itemnumbers.push($(this).val());
1684                 });
1685                 if (itemnumbers.length > 0) {
1686                     var url = '/cgi-bin/koha/tools/batchMod.pl?op=show';
1687                     url += '&itemnumber=' + itemnumbers.join('&itemnumber=');
1688                     url += '&biblionumber=[% biblionumber | uri %]';
1689                     url += '&src=CATALOGUING';
1690                     $('a.itemselection_action_modify').attr('href', url);
1691                 } else {
1692                     return false;
1693                 }
1694                 return true;
1695             }
1696
1697             function itemSelectionBuildActionLinks(tab) {
1698                 var div = $("#" + tab);
1699                 var delete_link_ok = itemSelectionBuildDeleteLink(div);
1700                 var modify_link_ok = itemSelectionBuildModifyLink(div);
1701                 if (modify_link_ok || delete_link_ok) {
1702                     $('.itemselection_actions', div).show();
1703                 } else {
1704                     $('.itemselection_actions', div).hide();
1705                 }
1706             }
1707
1708             $(document).ready(function() {
1709                 $('table.items_table').each(function() {
1710                     var div = $(this).parent().attr("id");
1711                     itemSelectionBuildActionLinks(div);
1712                 });
1713
1714                 $("input[name='itemnumber'][type='checkbox']").change(function() {
1715                     var div = $(this).parents('table').parent().parent().attr("id");
1716                     itemSelectionBuildActionLinks(div);
1717                 });
1718
1719                 $(".SelectAll").on("click",function(e){
1720                     e.preventDefault();
1721                     var tab = $(this).data("tab");
1722                     $("input[name='itemnumber'][type='checkbox']", $("#"+tab)).prop('checked', true);
1723                     itemSelectionBuildActionLinks(tab);
1724                 });
1725
1726                 $(".ClearAll").on("click",function(e){
1727                     e.preventDefault();
1728                     var tab = $(this).data("tab");
1729                     $("input[name='itemnumber'][type='checkbox']", $("#"+tab)).prop('checked', false);
1730                     itemSelectionBuildActionLinks(tab);
1731                 });
1732             });
1733         [% END %]
1734
1735         $(document).ready(function() {
1736             // Pick details tab to display by default
1737             [% IF count == 0 %]
1738                 [% IF ( Koha.Preference('HTML5MediaEnabled') == 'staff' or Koha.Preference('HTML5MediaEnabled') == 'both' ) && HTML5MediaSets.size %]
1739                     $(".nav-tabs a[href='#html5media']").tab("show");
1740                 [% ELSIF ComponentParts && ComponentParts.size %]
1741                     $(".nav-tabs a[href='#components']").tab("show");
1742                 [% ELSE %]
1743                     $(".nav-tabs a[href='#holdings']").tab("show");
1744                 [% END %]
1745             [% ELSE %]
1746                 $(".nav-tabs a[href='#holdings']").tab("show");
1747             [% END %]
1748             $('#search-form').focus();
1749             $('.thumbnails > li > .remove').click(function() {
1750                 var result = confirm(_("Are you sure you want to delete this cover image?"));
1751
1752                 if ( result == true ) {
1753                     var imagenumber = $(this).parent().attr('id').split('-')[1];
1754                     removeLocalImage(imagenumber);
1755                 }
1756
1757                 return false;
1758             });
1759             [% IF ( IntranetCoce && CoceProviders ) %]
1760                 KOHA.coce.getURL('[% CoceHost | html %]', '[% CoceProviders | html %]');
1761             [% END %]
1762
1763             $("body").on("click",".previewMARC", function(e){
1764                 e.preventDefault();
1765                 var page = $(this).attr("href");
1766                 $("#marcPreview .modal-body").load(page + " table");
1767                 $('#marcPreview').modal({show:true});
1768
1769             });
1770
1771            [% IF ( Koha.Preference('SearchEngine') == 'Elasticsearch' ) %]
1772             $("body").on("click",".previewElastic", function(e){
1773                 e.preventDefault();
1774                 var pageElastic = $(this).attr("href");
1775                 $("#elasticPreview .modal-body").load(pageElastic, function( response, status, xhr ) {
1776                     if( status == 'error' ){
1777                         $("#elasticPreview .modal-body").html("<h1>"+_("An error has occurred!")+"</h1><h2><em>"+_("Error 404")+"</em></h2><ul><li>"+_("An internal link in the staff interface is broken and the page does not exist")+"</li></ul><h3>"+_("What's next?")+"</h3><ul style='margin-bottom: 1em; padding-bottom: 1em; border-bottom: 1px solid #CCC;'><li>"+_("Use top menu bar to navigate to another part of Koha.")+"</li><li>"+_("To report a broken link or any other issue, please contact the Koha administrator.")+" <a href='mailto:[% Koha.Preference("KohaAdminEmailAddress") | uri %]'>"+_("Send email")+"</a></li></ul>");
1778                     }
1779                 });
1780                 $('#elasticPreview').modal({show:true});
1781             });
1782            [% END %]
1783
1784             [% IF ( Koha.Preference('NovelistSelectStaffEnabled') && Koha.Preference('NovelistSelectStaffProfile') && ( normalized_isbn || normalized_upc ) ) %]
1785                 novSelect.loadContentForQuery({
1786                     ClientIdentifier : '[% IF normalized_isbn %][% normalized_isbn | html %][% ELSE %][% normalized_upc | html %][% END %]',
1787                     ISBN : '[% IF normalized_isbn %][% normalized_isbn | html %][% ELSE %][% normalized_upc | html %][% END %]',
1788                     version : '2.1'
1789                 },
1790                 '[% Koha.Preference('NovelistSelectStaffProfile') | html %]',
1791                 '[% Koha.Preference('NovelistSelectPassword') | html %]',
1792                 function(d){
1793                     if ( d.length > 0 ){ //If no content
1794                         $(".NovelistSelect").show();
1795                     }
1796                  });
1797              [% END %]
1798              $(".print-label").on("click", function(e){
1799                 e.preventDefault();
1800                 link = $(this).attr("href");
1801                 openWindow(link,"Print spine label",400,400);
1802              });
1803              $(".cover-slider").on("click",".cover-nav", function(e){
1804                  e.preventDefault();
1805                 var cover_slider = $(this).parent();
1806                 // Adding click handler for cover image navigation links
1807                 var num = $(this).data("num");
1808                 $(cover_slider).find(".cover-nav").removeClass("nav-active");
1809                 $(this).addClass("nav-active");
1810                 $(cover_slider).find(".cover-image").hide();
1811                 $(cover_slider).find(".cover-image").eq( num ).show();
1812              });
1813         });
1814
1815
1816         [% IF ( IntranetCoce && CoceProviders ) %]
1817             let counter_wait = 0;
1818             function wait_for_images(cb){
1819
1820                 var loaded = 1;
1821                 counter_wait++;
1822
1823                 if ( loaded ) {
1824                     loaded = KOHA.coce.done;
1825                 }
1826
1827                 if (!loaded && counter_wait < 50) {// Do not wait more than 5 seconds
1828                     window.setTimeout(function(){wait_for_images(cb);}, 100);
1829                 } else {
1830                     if (counter_wait >= 50 ) {
1831                         console.log("Could not retrieve the images")
1832                     }
1833                     cb();
1834                 }
1835             }
1836
1837             $(window).load(function() {
1838                 wait_for_images(verify_cover_images);
1839             });
1840         [% ELSE %]
1841             $(window).load(function() {
1842                 verify_cover_images();
1843             });
1844         [% END %]
1845     </script>
1846     [% IF ( Koha.Preference('NovelistSelectStaffEnabled') && Koha.Preference('NovelistSelectStaffProfile') && ( normalized_isbn || normalized_upc ) ) %]
1847         <script src="https://imageserver.ebscohost.com/novelistselect/ns2init.js"></script>
1848     [% END %]
1849     [% INCLUDE 'datatables.inc' %]
1850     [% Asset.js("lib/jquery/plugins/jquery.dataTables.columnFilter.js") | $raw %]
1851     [% INCLUDE 'columns_settings.inc' %]
1852     [% INCLUDE 'js-date-format.inc' %]
1853     [% INCLUDE 'js-patron-format.inc' %]
1854     [% INCLUDE 'js-biblio-format.inc' %]
1855     [% Asset.js("js/browser.js") | $raw %]
1856     [% Asset.js("js/table_filters.js") | $raw %]
1857     [% Asset.js("js/place_booking_modal.js") | $raw %]
1858     <script>
1859         var browser;
1860         browser = KOHA.browser('[% searchid | html %]', parseInt(biblionumber, 10));
1861         browser.show();
1862
1863         [% IF bundlesEnabled %]
1864         var bundle_settings = [% TablesSettings.GetTableSettings('catalogue', 'detail','bundle_tables','json') | $raw %];
1865         var bundle_lost_value = [% Koha.Preference('BundleLostValue') | html %];
1866         [% END %]
1867         $(document).ready(function() {
1868
1869             [% IF bundlesEnabled %] // Bundle handling
1870             function createChild ( row, itemnumber, duedate ) {
1871
1872                 // Toolbar
1873                 var bundle_toolbar = $('<div id="toolbar" class="btn-toolbar"></div>');
1874                 bundle_toolbar.append('<a class="btn btn-default" data-toggle="modal" data-target="#addToBundleModal" data-item="' + itemnumber + '"><i class="fa fa-plus"></i> ' + _("Add to bundle") + '</a>');
1875                 bundle_toolbar.append('<a class="btn btn-default" data-toggle="modal" data-target="#removeFromBundleModal" data-item="' + itemnumber + '"><i class="fa fa-minus"></i> ' + _("Remove from bundle") + '</a>');
1876
1877                 // Disable management if there's a duedate
1878                 if(duedate) {
1879                     bundle_toolbar.children('.btn').addClass("disabled");
1880                     bundle_toolbar.attr("title", _("This bundle is checked out, it cannot be modified"));
1881                 }
1882
1883                 // This is the table we'll convert into a DataTable
1884                 var bundles_table = $('<table class="display tbundle" data-itemnumber="'+itemnumber+'" id="bundle_table_'+itemnumber+'" width="100%"/>');
1885
1886                 // Display it the child row
1887                 row.child( bundle_toolbar.add(bundles_table), 'bundle' ).show();
1888
1889                 // Initialise as a DataTable
1890                 var bundle_table_url = "/api/v1/items/" + itemnumber + "/bundled_items?";
1891                 var bundle_table = bundles_table.kohaTable({
1892                     "ajax": {
1893                         "url": bundle_table_url
1894                     },
1895                     "embed": [
1896                         "biblio",
1897                         "return_claim.patron"
1898                     ],
1899                     "order": [[ 1, "asc" ]],
1900                     "columnDefs": [ {
1901                         "targets": [0,1,2,3],
1902                         "render": function (data, type, row, meta) {
1903                             if ( data && type == 'display' ) {
1904                                 return data.escapeHtml();
1905                             }
1906                             return data;
1907                         }
1908                     } ],
1909                     "columns": [
1910                         {
1911                             "data": "biblio.title:biblio.subtitle:biblio.medium",
1912                             "title": _("Title"),
1913                             "searchable": true,
1914                             "orderable": true,
1915                             "render": function(data, type, row, meta) {
1916                                 return $biblio_to_html(row.biblio, { link: 1 });
1917                             }
1918                         },
1919                         {
1920                             "data": "biblio.author",
1921                             "title": _("Author"),
1922                             "searchable": true,
1923                             "orderable": true,
1924                         },
1925                         {
1926                             "data": "callnumber",
1927                             "title": _("Callnumber"),
1928                             "searchable": true,
1929                             "orderable": true,
1930                         },
1931                         {
1932                             "data": "external_id",
1933                             "title": _("Barcode"),
1934                             "searchable": true,
1935                             "orderable": true,
1936                         },
1937                         {
1938                             "data": "lost_status:last_seen_date:return_claim.patron",
1939                             "title": _("Status"),
1940                             "searchable": false,
1941                             "orderable": false,
1942                             "render": function(data, type, row, meta) {
1943                                 if ( row.lost_status == bundle_lost_value ) {
1944                                     let out = '<span class="lost">' + _("Last seen") + ': ' + $date(row.last_seen_date) + '</span>';
1945                                     if ( row.return_claim ) {
1946                                         out = out + '<span class="claims_return">' + _("Claims returned by") + ': ' + $patron_to_html( row.return_claim.patron, { display_cardnumber: false, url: true } ) + '</span>';
1947                                     }
1948                                     return out;
1949                                 }
1950                                 else if ( row.lost_status !== 0 ) {
1951                                     return '<span class="lost">' + _("Lost") + ': ' + row.lost_status + '</span>';
1952                                 }
1953                                 return '<span class="available">' + _("Present") + '</span>';
1954                             }
1955                         },
1956                         {
1957                             "data": function( row, type, val, meta ) {
1958                                 var result;
1959                                 if (duedate) {
1960                                     result = '<button class="btn btn-default btn-xs remove disabled" role="button" data-itemnumber="'+row.item_id+'" title="%s"><i class="fa fa-minus" aria-hidden="true"></i> %s</button>\n'.format(_("This bundle is checked out, it cannot be modified"), _("Remove"));
1961                                 } else {
1962                                     result = '<button class="btn btn-default btn-xs remove" role="button" data-itemnumber="'+row.item_id+'"><i class="fa fa-minus" aria-hidden="true"></i> '+_("Remove")+'</button>\n';
1963                                 }
1964                                 return result;
1965                             },
1966                             "title": _("Actions"),
1967                             "searchable": false,
1968                             "orderable": false,
1969                             "class": "noExport"
1970                         }
1971                     ]
1972                 }, bundle_settings, 1);
1973                 $(".tbundle").on("click", ".remove:not(.disabled)", function(){
1974                     var bundle_table = $(this).closest('table');
1975                     var host_itemnumber = bundle_table.data('itemnumber');
1976                     var component_itemnumber = $(this).data('itemnumber');
1977                     var unlink_item_url = "/api/v1/items/" + host_itemnumber + "/bundled_items/" + component_itemnumber;
1978                     $.ajax({
1979                         type: "DELETE",
1980                         url: unlink_item_url,
1981                         success: function(){
1982                             bundle_table.DataTable({ 'retrieve': true }).draw(false);
1983                         }
1984                     });
1985                 });
1986
1987                 return;
1988             }
1989
1990             var bundle_changed;
1991             var bundle_form_active;
1992             $("#addToBundleModal").on("shown.bs.modal", function(e){
1993                 var button = $(e.relatedTarget);
1994                 var item_id = button.data('item');
1995                 $("#addResult").replaceWith('<div id="addResult"></div>');
1996                 $("#addToBundleForm").attr('action', '/api/v1/items/' + item_id + '/bundled_items');
1997                 $("#external_id").focus();
1998                 bundle_changed = 0;
1999                 bundle_form_active = item_id;
2000             });
2001
2002             function addToBundle (url, data) {
2003                   /* Send the data using post with external_id */
2004                   var posting = $.post({
2005                       url: url,
2006                       data: JSON.stringify(data),
2007                       contentType: "application/json; charset=utf-8",
2008                       dataType: "json"
2009                   });
2010
2011                   const barcode = data.external_id;
2012
2013                   /* Report the results */
2014                   posting.done(function(data) {
2015                       $('#addResult').replaceWith('<div id="addResult" class="alert alert-success">'+_("Success: Added '%s'").format(barcode)+'</div>');
2016                       $('#external_id').val('').focus();
2017                       bundle_changed = 1;
2018                   });
2019                   posting.fail(function(data) {
2020                       if ( data.status === 409 ) {
2021                           var response = data.responseJSON;
2022                           if ( response.error_code === 'already_bundled' ) {
2023                               $('#addResult').replaceWith('<div id="addResult" class="alert alert-warning">'+_("Warning: Item '%s' already attached").format(barcode)+'</div>');
2024                           } else if (response.error_code === 'bundle_checkout_out') {
2025                               $('#addResult').replaceWith('<div id="addResult" class="alert alert-danger">'+_("Failure: Bundle is currently checked out")+'</div>');
2026                           } else if (response.error_code === 'checked_out') {
2027                               const button = $('<button type="button">')
2028                                 .addClass('btn btn-xs')
2029                                 .text(_("Check in and add to bundle"))
2030                                 .on('click', function () {
2031                                     addToBundle(url, { external_id: barcode, force_checkin: true });
2032                                 });
2033                               $('#addResult')
2034                                 .empty()
2035                                 .attr('class', 'alert alert-warning')
2036                                 .append(__x('Warning: Item {barcode} is checked out', { barcode }))
2037                                 .append(' ', button);
2038                           } else if (response.error_code === 'failed_checkin') {
2039                               $('#addResult')
2040                                 .empty()
2041                                 .attr('class', 'alert alert-danger')
2042                                 .append(__x('Failure: Item {barcode} cannot be checked in', { barcode }))
2043                           } else if (response.error_code === 'reserved') {
2044                               const button = $('<button type="button">')
2045                                 .addClass('btn btn-xs')
2046                                 .text(_("Ignore holds and add to bundle"))
2047                                 .on('click', function () {
2048                                     addToBundle(url, { external_id: barcode, ignore_holds: true });
2049                                 });
2050                               $('#addResult')
2051                                 .empty()
2052                                 .attr('class', 'alert alert-warning')
2053                                 .append(__x('Warning: Item {barcode} is on hold', { barcode }))
2054                                 .append(' ', button);
2055                           } else {
2056                               $('#addResult').replaceWith('<div id="addResult" class="alert alert-danger">'+_("Failure: Item '%s' belongs to another bundle").format(barcode)+'</div>');
2057                           }
2058                       } else if ( data.status === 404 ) {
2059                           $('#addResult').replaceWith('<div id="addResult" class="alert alert-danger">'+_("Failure: Item '%s' not found").format(barcode)+'</div>');
2060                       } else if ( data.status === 400 ) {
2061                           var response = data.responseJSON;
2062                           if ( response.error_code === "failed_nesting" ) {
2063                               $('#addResult').replaceWith('<div id="addResult" class="alert alert-danger">'+_("Failure: Item '%s' is a bundle and bundles cannot be nested").format(barcode)+'</div>');
2064                           } else {
2065                               $('#addResult').replaceWith('<div id="addResult" class="alert alert-danger">'+_("Failure: Check the logs for details.")+'</div>');
2066                           }
2067                       } else {
2068                           $('#addResult').replaceWith('<div id="addResult" class="alert alert-danger">'+_("Failure: Check the logs for details.")+'</div>');
2069                       }
2070                       $('#external_id').val('').focus();
2071                   });
2072             }
2073
2074             $("#addToBundleForm").submit(function(event) {
2075                   /* stop form from submitting normally */
2076                   event.preventDefault();
2077
2078                   const url = this.action;
2079                   const data = { external_id: this.elements.external_id.value };
2080
2081                   addToBundle(url, data);
2082             });
2083
2084             $("#addToBundleModal").on("hidden.bs.modal", function(e){
2085                 if ( bundle_changed ) {
2086                     $('#bundle_table_'+bundle_form_active).DataTable({ 'retrieve': true }).ajax.reload();
2087                 }
2088                 bundle_form_active = 0;
2089                 bundle_changed = 0;
2090             });
2091
2092             $("#removeFromBundleModal").on("shown.bs.modal", function(e){
2093                 var button = $(e.relatedTarget);
2094                 var item_id = button.data('item');
2095                 $("#removeResult").replaceWith('<div id="removeResult"></div>');
2096                 $("#removeFromBundleForm").attr('action', '/api/v1/items/' + item_id + '/bundled_items/');
2097                 $("#rm_external_id").focus();
2098                 bundle_changed = 0;
2099                 bundle_form_active = item_id;
2100             });
2101
2102             $("#removeFromBundleForm").submit(function(event) {
2103
2104                 /* stop form from submitting normally */
2105                 event.preventDefault();
2106
2107                 /* get the action attribute from the <form action=""> element */
2108                 var $form = $(this),
2109                 url = $form.attr('action');
2110
2111                 var barcode = $('#rm_external_id').val();
2112
2113                 /* Fetch itemnumber using rm_external_id */
2114                 var itemReq = $.get('/api/v1/items', { q: JSON.stringify({
2115                     external_id: barcode
2116                 }) }, null, "json");
2117
2118                 var itemnumber;
2119                 itemReq.done(function(data) {
2120                     if (data.length === 1) {
2121                         itemnumber = data[0].item_id;
2122
2123                         /* Remove link using fetch itemnumber */
2124                         var deleteReq = $.ajax( url + itemnumber, {
2125                             type : 'DELETE'
2126                         });
2127
2128                         /* Report the results */
2129                         deleteReq.done(function(data) {
2130                             var barcode = $('#rm_external_id').val();
2131                             $('#removeResult').replaceWith('<div id="removeResult" class="alert alert-success">'+_("Success: Removed '%s'").format(barcode)+'</div>');
2132                             $('#rm_external_id').val('').focus();
2133                             bundle_changed = 1;
2134                         });
2135                         deleteReq.fail(function(data) {
2136                             var barcode = $('#rm_external_id').val();
2137                             if ( data.status === 409 ) {
2138                                 var response = data.responseJSON;
2139                                 if (response.error_code === 'bundle_checkout_out') {
2140                                     $('#removeResult').replaceWith('<div id="removeResult" class="alert alert-danger">'+_("Failure: Bundle is currently checked out")+'</div>');
2141                                 } else if ( response.key === "PRIMARY" ) {
2142                                     $('#removeResult').replaceWith('<div id="removeResult" class="alert alert-warning">'+_("Warning: Item '%s' already attached").format(barcode)+'</div>');
2143                                 } else {
2144                                     $('#removeResult').replaceWith('<div id="removeResult" class="alert alert-danger">'+_("Failure: Item '%s' belongs to another bundle").format(barcode)+'</div>');
2145                                 }
2146                             } else if ( data.status === 404 ) {
2147                                 $('#addResult').replaceWith('<div id="addResult" class="alert alert-danger">'+_("Failure: Item '%s' not found").format(barcode)+'</div>');
2148                             } else {
2149                                 $('#removeResult').replaceWith('<div id="removeResult" class="alert alert-danger">'+_("Failure: Check the logs for details")+'</div>');
2150                             }
2151                             $('#rm_external_id').val('').focus();
2152                         });
2153                     } else {
2154                         $('#removeResult').replaceWith('<div id="removeResult" class="alert alert-danger">'+_("Failed: Barcode matched more than one item '%s'").format(barcode)+'</div>');
2155                     }
2156                 });
2157                 itemReq.fail(function(data) {
2158                      $('#removeResult').replaceWith('<div id="removeResult" class="alert alert-danger">'+_("Failed: Item not found '%s'").format(barcode)+'</div>');
2159                     $('#rm_external_id').val('').focus();
2160
2161                 });
2162             });
2163
2164             $("#removeFromBundleModal").on("hidden.bs.modal", function(e){
2165                 if ( bundle_changed ) {
2166                     $('#bundle_table_'+bundle_form_active).DataTable({ 'retrieve': true }).ajax.reload();
2167                 }
2168                 bundle_form_active = 0;
2169                 bundle_changed = 0;
2170             });
2171             // End bundle handling
2172             [% END %]
2173
2174             var table_names = [ 'holdings_table', 'otherholdings_table' ];
2175             var table_settings = [ [% TablesSettings.GetTableSettings('catalogue', 'detail','holdings_table','json') | $raw %], [% TablesSettings.GetTableSettings('catalogue', 'detail','otherholdings_table','json')  | $raw %] ];
2176             var has_images = [ "[% itemloop_has_images | html %]", "[% otheritemloop_has_images | html %]" ];
2177             table_names.forEach( function( table_name, index ) {
2178                 if ( !has_images[index] ) {
2179                     table_settings[index].columns.splice(1,1);
2180                 }
2181                 var dt_parameters = {
2182                     "dom": 't',
2183                     "paginate": false,
2184                     "autoWidth": false,
2185                     "bKohaColumnsUseNames": true,
2186                     "dom": 'C<"top pager"ilpfB><"#filter_c">tr<"bottom pager"ip>',
2187                 };
2188                 var table = KohaTable( table_name, dt_parameters, table_settings[index], 'with_filters' );
2189
2190                 [% IF bundlesEnabled %]
2191                 // Add event listener for opening and closing bundle details
2192                 $('#' + table_name + ' tbody').on('click', 'button.details-control', function () {
2193                     var button = $(this);
2194                     var tr = button.closest('tr');
2195                     var dTable = button.closest('table').DataTable({ 'retrieve': true });
2196
2197                     var itemnumber = tr.data('itemnumber');
2198                     var duedate = tr.data('duedate');
2199                     var row = dTable.row( tr );
2200
2201                     if ( row.child.isShown() ) {
2202                         // This row is already open - close it
2203                         row.child.hide();
2204                         tr.removeClass('shown');
2205                         button.removeClass('active');
2206                     }
2207                     else {
2208                         // Open this row
2209                         createChild(row, itemnumber, duedate);
2210                         tr.addClass('shown');
2211                         button.addClass('active');
2212                     }
2213                 } );
2214                 [% END %]
2215             });
2216
2217             [% IF Koha.Preference('AcquisitionDetails') %]
2218                 var table_settings = [% TablesSettings.GetTableSettings('catalogue', 'detail', 'acquisitiondetails-table', 'json') | $raw %];
2219                 var acquisitiondetails_table = KohaTable("orders", {
2220                     "dom": 'C<"top pager"ilpfB><"#filter_c">tr<"bottom pager"ip>',
2221                     "paginate": false,
2222                     "autoWidth": false,
2223                     "order": [[ 4, "desc" ]],
2224                 }, table_settings);
2225             [% END %]
2226
2227             [% IF suggestions.count %]
2228                 $(".sorted").dataTable($.extend(true, {}, dataTablesDefaults, {
2229                     "columnDefs": [
2230                         { "orderable": false, "searchable":  false, "targets": [ 'NoSort' ] },
2231                         { "type": "anti-the", "targets":  [ "anti-the" ] }
2232                     ],
2233                     "pagingType": "full"
2234                 }));
2235             [% END %]
2236
2237         });
2238
2239         [% IF found1 && Koha.Preference('RetainCatalogSearchTerms') %]
2240             $(document).ready(function() {
2241                 var search_index = localStorage.getItem("cat_search_pulldown_selection");
2242                 var search_value = localStorage.getItem("searchbox_value");
2243                 if ( search_index ){ $('#cat-search-block select.advsearch').val(search_index)};
2244                 if ( search_value ){ $('#cat-search-block #search-form').val(search_value)};
2245             });
2246         [% END %]
2247
2248         [% IF Koha.Preference('EnableItemGroups') %]
2249             // Load item groups table
2250             var itemGroupsTable = $("#items-group-table").kohaTable({
2251                 autoWidth: false,
2252                 dom: '<"top pager"ilp>t<"bottom pager"ip>r',
2253                 columns: [
2254                     {
2255                         data: "display_order",
2256                         title: _("Display order"),
2257                         searchable: true,
2258                         orderable: true,
2259                     },
2260                     {
2261                         data: "description",
2262                         title: _("Description"),
2263                         searchable: true,
2264                         orderable: true,
2265                     },
2266                     {
2267                         data: function( oObj ) {
2268                             [% IF CAN_user_editcatalogue_manage_item_groups %]
2269                                 return `<button class='item-group-edit btn btn-default btn-xs' data-item-group-id='${oObj.item_group_id}'>
2270                                     <i class="fa-solid fa-pencil" aria-hidden="true"></i> ${_("Edit")}
2271                                 </button>`
2272                                 + '&nbsp'
2273                                 + `<button class='item-group-delete btn btn-default btn-xs' data-item-group-id='${oObj.item_group_id}'>
2274                                     <i class='fa fa-trash-can'></i> ${('Delete')}
2275                                 </button>`;
2276                             [% ELSE %]
2277                                 return "";
2278                             [% END %]
2279                         },
2280                         searchable: false,
2281                         orderable: false,
2282                     },
2283                 ],
2284                 paginate: false,
2285                 ajax: { url: `/api/v1/biblios/${biblionumber}/item_groups?_per_page=-1` },
2286             });
2287
2288             // Create new item groups
2289             $('.item-group-create').on('click', function(){
2290                 $('#modal-item-group-create-form-description').val("");
2291                 $('#modal-item-group-create-submit').removeAttr('disabled');
2292                 $('#modal-item-group-create').modal('show');
2293             });
2294
2295             $("#modal-item-group-create-form").validate({
2296                 submitHandler: function(form) {
2297                     $.ajax({
2298                         url: `/api/v1/biblios/${biblionumber}/item_groups`,
2299                         headers: { "x-koha-embed": "items" },
2300                         success: function(item_groups){
2301                             $('#modal-item-group-create-submit').attr('disabled', 'disabled');
2302
2303                             var settings = {
2304                               "url": `/api/v1/biblios/${biblionumber}/item_groups`,
2305                               "method": "POST",
2306                               "headers": {
2307                                 "Content-Type": "application/json"
2308                               },
2309                               "data": JSON.stringify(
2310                                   {
2311                                       "description": $("#modal-item-group-create-form-description").val(),
2312                                       "display_order": $("#modal-item-group-create-form-display_order").val(),
2313                                   }
2314                               ),
2315                             };
2316
2317                             $.ajax(settings)
2318                             .done(function (response) {
2319                                 $('#item-group-add-form-select').append($('<option>', {
2320                                     value: response.item_group_id,
2321                                     text: response.description
2322                                 }));
2323
2324                                 $('#modal-item-group-create').modal('hide');
2325                                 if ( item_groups.length == 0 ) {
2326                                     // This bib has no previous item groups, reload the page
2327                                     window.location.replace(`/cgi-bin/koha/catalogue/detail.pl?biblionumber=${biblionumber}`);
2328                                 } else {
2329                                     // Has other item groups, just reload the table
2330                                     itemGroupsTable.api().ajax.reload();
2331                                 }
2332                             })
2333                             .fail(function(err) {
2334                                 var message = err.responseJSON.error;
2335                                 alert(message);
2336                             });
2337                         }
2338                     });
2339                 }
2340             });
2341
2342             $('#modal-item-group-create').on('shown.bs.modal', function () {
2343                 $('#modal-item-group-create-form-description').focus();
2344             })
2345
2346             // Edit existing item groups
2347             $('body').on( 'click', '.item-group-edit', function(){
2348                 const item_group_id = $(this).data('item-group-id');
2349                 const url = `/api/v1/biblios/${biblionumber}/item_groups/${item_group_id}`;
2350                 $.get( url, function( data ) {
2351                     $('#modal-item-group-edit-form-description').val( data.description );
2352                     $('#modal-item-group-edit-form-display_order').val( data.display_order );
2353                     $('#modal-item-group-edit-submit').data('item-group-id', item_group_id );
2354                     $('#modal-item-group-edit-submit').removeAttr('disabled');
2355                     $('#modal-item-group-edit').modal('show');
2356                 });
2357             });
2358
2359             $("#modal-item-group-edit-form").validate({
2360                 submitHandler: function(form) {
2361                     $('#modal-item-group-edit-submit').attr('disabled', 'disabled');
2362
2363                     const item_group_id = $('#modal-item-group-edit-submit').data('item-group-id');
2364                     const url = `/api/v1/biblios/${biblionumber}/item_groups/${item_group_id}`;
2365
2366                     var settings = {
2367                       "url": url,
2368                       "method": "PUT",
2369                       "headers": {
2370                         "Content-Type": "application/json"
2371                       },
2372                       "data": JSON.stringify(
2373                           {
2374                               "description": $("#modal-item-group-edit-form-description").val(),
2375                               "display_order": $("#modal-item-group-edit-form-display_order").val(),
2376                           }
2377                       ),
2378                     };
2379
2380                     $.ajax(settings)
2381                     .done(function (response) {
2382                         $('#modal-item-group-edit').modal('hide');
2383                         itemGroupsTable.api().ajax.reload();
2384                     })
2385                     .fail(function(err) {
2386                         var message = err.responseJSON.error;
2387                         alert(message);
2388                     });
2389                 }
2390             });
2391
2392             $('#modal-item-group-edit').on('shown.bs.modal', function () {
2393                 $('#modal-item-group-edit-form-description').focus();
2394             })
2395
2396             // Delete existing item groups
2397             $('body').on( 'click', '.item-group-delete', function(){
2398                 const item_group_id = $(this).data('item-group-id');
2399                 $('#modal-item-group-delete-submit').data('item-group-id', item_group_id );
2400                 $('#modal-item-group-delete-submit').removeAttr('disabled');
2401                 $('#modal-item-group-delete').modal('show');
2402             });
2403             $("#modal-item-group-delete-submit").on('click', function(){
2404                 $('#modal-item-group-delete-submit').attr('disabled', 'disabled');
2405                 const item_group_id = $("#modal-item-group-delete-submit").data('item-group-id');
2406
2407                 $.ajax({
2408                     url: `/api/v1/biblios/${biblionumber}/item_groups/${item_group_id}`,
2409                     headers: { "x-koha-embed": "items" },
2410                     success: function(item_group_data){
2411                         $.ajax({
2412                           "url": `/api/v1/biblios/${biblionumber}/item_groups/${item_group_id}`,
2413                           "method": "DELETE",
2414                         })
2415                         .done(function (response) {
2416                             $('#modal-item-group-delete').modal('hide');
2417                             $(`#item-group-add-form-select option[value='${item_group_id}']`).remove();
2418                             if ( item_group_data.items === null ) {
2419                                 // No items for this item group, we can just refresh the table
2420                                 itemGroupsTable.api().ajax.reload();
2421                             } else {
2422                                 // This item group had items attached to it, we need to reload the page
2423                                 window.location.replace(`/cgi-bin/koha/catalogue/detail.pl?biblionumber=${biblionumber}`);
2424                             }
2425                         })
2426                         .fail(function(err) {
2427                             var message = err.responseJSON.error;
2428                             alert(message);
2429                         });
2430                     }
2431                 });
2432             });
2433
2434             // Add item(s) to a item group
2435             $('.itemselection_action_item_group_set').on('click', function(){
2436                 $('#modal-item-group-set').modal('show');
2437             });
2438
2439             $("#modal-item-group-set-form").validate({
2440                 submitHandler: function(form) {
2441                     $('#modal-item-group-set-submit').attr('disabled', 'disabled');
2442
2443                     const item_group_id = $('#item-group-add-form-select').val();
2444
2445                     let itemnumbers = new Array();
2446                     $("input[name='itemnumber'][type='checkbox']:checked").each(function() {
2447                         const itemnumber = $(this).val();
2448                         itemnumbers.push( itemnumber );
2449                     });
2450                     if (itemnumbers.length > 0) {
2451                         let url = '/cgi-bin/koha/catalogue/detail.pl?op=set_item_group';
2452                         url += '&itemnumber=' + itemnumbers.join('&itemnumber=');
2453                         url += '&biblionumber=[% biblionumber | uri %]';
2454                         url += `&item_group_id=${item_group_id}`;
2455
2456                         window.location.replace(url);
2457                     }
2458
2459                     $('#modal-item-group-set').modal('hide');
2460                 }
2461             });
2462
2463             // Remove item(s) from an item group
2464             $('.itemselection_action_item_group_unset').on('click', function(){
2465                 $('#modal-item-group-unset').modal('show');
2466             });
2467
2468             $("#modal-item-group-unset-submit").on('click', function(){
2469                 $('#modal-item-group-unset-submit').attr('disabled', 'disabled');
2470
2471                 let itemnumbers = new Array();
2472                 $("input[name='itemnumber'][type='checkbox']:checked").each(function() {
2473                     const itemnumber = $(this).val();
2474                     itemnumbers.push( itemnumber );
2475                 });
2476                 if (itemnumbers.length > 0) {
2477                     let url = '/cgi-bin/koha/catalogue/detail.pl?op=unset_item_group';
2478                     url += '&itemnumber=' + itemnumbers.join('&itemnumber=');
2479                     url += '&biblionumber=[% biblionumber | uri %]';
2480
2481                     window.location.replace(url);
2482                 }
2483
2484                 $('#modal-item-group-unset').modal('hide');
2485
2486             });
2487         [% END %]
2488         const can_edit_items_from = [% To.json(can_edit_items_from || {}) | $raw %];
2489         const item_type_image_locations = [% To.json(item_type_image_locations) | $raw %];
2490         const av_loc = new Map([% To.json(AuthorisedValues.Get('LOC')) | $raw %].map( av => [av.authorised_value, av.lib]));
2491         const av_lost = new Map([% To.json(AuthorisedValues.GetDescriptionsByKohaField({ kohafield => 'items.itemlost' })) | $raw %].map( av => [av.authorised_value, av.lib]));
2492         const av_withdrawn = new Map([% To.json(AuthorisedValues.GetDescriptionsByKohaField({ kohafield => 'items.withdrawn' })) | $raw %].map( av => [av.authorised_value, av.lib]));
2493         const av_damaged = new Map([% To.json(AuthorisedValues.GetDescriptionsByKohaField({ kohafield => 'items.damaged' })) | $raw %].map( av => [av.authorised_value, av.lib]));
2494         const av_not_for_loan= new Map([% To.json(AuthorisedValues.GetDescriptionsByKohaField({ kohafield => 'items.notforloan' })) | $raw %].map( av => [av.authorised_value, av.lib]));
2495         const av_restricted = new Map([% To.json(AuthorisedValues.GetDescriptionsByKohaField({ kohafield => 'items.restricted' })) | $raw %].map( av => [av.authorised_value, av.lib]));
2496         [% IF Koha.Preference('URLLinkText') %]
2497             const url_link_text = "[% Koha.Preference('URLLinkText') | html %]";
2498         [% ELSE %]
2499             const url_link_text = _("Link to resource");
2500         [% END %]
2501         let table_url = "/api/v1/biblios/[% biblio.biblionumber | uri %]/items?";
2502         let embed = ["+strings,checkout,checkout.patron,transfer,first_hold,first_hold.patron,item_type"];
2503         [% IF Koha.Preference('LocalCoverImages') %]
2504             embed.push('cover_image_ids');
2505         [% END %]
2506         [% IF Koha.Preference('EnableItemGroups') %]
2507             embed.push('item_group_item.item_group.description');
2508         [% END %]
2509         [% IF biblio.serial %]
2510             embed.push('serialitem.serial');
2511         [% END %]
2512         [% IF Koha.Preference('UseRecalls') %]
2513             embed.push('recall', 'recall.patron')
2514         [% END %]
2515         embed.push('in_bundle', 'bundle_host');
2516         let table_settings = [% TablesSettings.GetTableSettings('catalogue', 'detail','holdings_table','json') | $raw %];
2517         var items_table = $("#table_items").kohaTable({
2518             ajax: { url: table_url },
2519             order: [[ 0, "asc" ]],
2520             embed,
2521             bAutoWidth: false,
2522             bKohaColumnsUseNames: true, // FIXME We should not need that now, do we?
2523             columns: [
2524             [% IF (StaffDetailItemSelection) %]
2525             {
2526                 data: "me.item_id",
2527                 searchable: false,
2528                 orderable: false,
2529                 render: function (data, type, row, meta) {
2530                     if ( can_edit_items_from[row.holding_library_id] ){
2531                         return '<input type="checkbox" value="%s" name="itemnumber" />'.format(row.item_id);
2532                     } else {
2533                         return ''
2534                     }
2535                 }
2536             },
2537             [% END %]
2538             [% IF Koha.Preference('LocalCoverImages') %]
2539             {
2540                 data: "",
2541                 className: "cover",
2542                 searchable: false,
2543                 orderable: false,
2544                 render: function (data, type, row, meta) {
2545                     if ( !row.cover_image_ids.length > 0 ) {
2546                         return '';
2547                     }
2548                     let node = '<div class="bookcoverimg">';
2549                     node += '<div class="cover-slider">';
2550                     row.cover_image_ids.forEach(id => {
2551                         node += '<div class="cover-image local-coverimg">';
2552                         node += '<a href="/cgi-bin/koha/catalogue/image.pl?itemnumber=%s&amp;imagenumber=%s" title="Local cover image">'.format(id, id);
2553                         node += '<img src="/cgi-bin/koha/catalogue/image.pl?thumbnail=1&amp;imagenumber=%s" alt="Local cover image" data-link="/cgi-bin/koha/catalogue/imageviewer.pl?itemnumber=[% item.itemnumber | uri %]&amp;imagenumber=%s" />'.format(id, id);
2554                         node += '</a>';
2555                         node += '</div>';
2556                     });
2557                     node += '</div>';
2558                     node += '</div>';
2559                     return node;
2560                 }
2561             },
2562             [% END %]
2563             [% IF ( item_level_itypes ) %]
2564             {
2565                 data: "me.itype:biblioitem.itemtype",
2566                 className: "itype",
2567                 searchable: true,
2568                 orderable: true,
2569                 render: function (data, type, row, meta) {
2570                     let node = '';
2571                     [% UNLESS noItemTypeImages %]
2572                         let image_location = item_type_image_locations[row.item_type_id];
2573                         let item_type_description = row._strings.item_type_id.str;
2574                         node += image_location
2575                             ? '<img src="%s" alt="%s" title="%s" /> '.format(image_location, item_type_description, item_type_description)
2576                             : '';
2577                     [% END %]
2578                     node += '<span class="itypedesc itypetext">%s</span>'.format(item_type_description);
2579                     return node;
2580                 }
2581             },
2582             [% END %]
2583             {
2584                 data: "me.holding_library_id",
2585                 className: "location",
2586                 searchable: true,
2587                 orderable: true,
2588                 render: function (data, type, row, meta) {
2589                     return row._strings.holding_library_id.str;
2590                 }
2591             },
2592             {
2593                 data: "me.home_library_id",
2594                 className: "homebranch",
2595                 searchable: true,
2596                 orderable: true,
2597                 render: function (data, type, row, meta) {
2598                     let nodes = '<span class="homebranchdesc">%s</span>'.format(row._strings.home_library_id.str);
2599                     nodes += '<span class="shelvingloc">'
2600                     [%# If permanent location is defined, show description or code and
2601                         display current location in parentheses. If not, display current location.
2602                         Note that permanent location is a code, and location may be an authval.
2603                     %]
2604
2605                     let loc_str = row._strings.location.str;
2606                     if ( row.permanent_location && row.permanent_location != row.location ) {
2607                         let permanent_loc_str = av_loc[row.permanent_location];
2608                         nodes += '%s (%s)'.format(permanent_loc_str, loc_str);
2609                     } else {
2610                         nodes += loc_str;
2611                     }
2612                     nodes += '</span>';
2613                     return nodes;
2614                 }
2615             },
2616             {
2617                 data: "me.collection_code",
2618                 searchable: true,
2619                 orderable: true,
2620                 render: function (data, type, row, meta) {
2621                     return row._strings.collection_code.str;
2622                 }
2623             },
2624             [% IF Koha.Preference('EnableItemGroups') %]
2625             {
2626                 data: "item_group_item.item_group.description",
2627                 className: "item_group",
2628                 searchable: true,
2629                 orderable: true,
2630                 render: function (data, type, row, meta) {
2631                     if ( row.item_group_item ) {
2632                         return row.item_group_item.item_group.description;
2633                     } else {
2634                         return "";
2635                     }
2636                 }
2637             },
2638             [% END %]
2639             {
2640                 data: "me.callnumber",
2641                 className: "itemcallnumber",
2642                 searchable: true,
2643                 orderable: true,
2644                 render: function (data, type, row, meta) {
2645                     return row.callnumber;
2646                 }
2647
2648             },
2649             {
2650                 data: "me.serial_issue_number",
2651                 className: "enumchron",
2652                 searchable: true,
2653                 orderable: true,
2654                 render: function (data, type, row, meta) {
2655                     let nodes = "";
2656                     [%# FIXME Previously we displayed the column if at least one item of the biblio had an enumchron/serial_issue_number. Now it's only if one item of the ones displayed on the current page, how is that bad? How can it be fixed in an elegant way? Should we display the column only if biblio.serial? %]
2657                     let serial = row.serialitem ? row.serialitem.serial : null;
2658                     if ( row.serial_issue_number && serial && serial.serialseq ) {
2659                         nodes += '<span class="enum">%s</span>'.format(row.serial_issue_number);
2660                         if ( serial.serialseq && row.serial_issue_number != serial.serialseq ) {
2661                             nodes += ' <span class="sep"> -- </span>'
2662                             nodes += ' <span class="serialseq">%s</span>'.format(serial.serialseq);
2663                         }
2664                     } else if ( row.serial_issue_number ) {
2665                         nodes += ' <span class="enum">%s</span>'.format(row.serial_issue_number);
2666                     } else if ( serial && serial.serialseq ) {
2667                         nodes += '<span class="serialseq">%s</span>'.format(serial.serialseq);
2668                     }
2669                     if ( serial && serial.publisheddate ) {
2670                         nodes += ' <span class="pubdate">(%s)</span>'.format($date(serial.publisheddate));
2671                     }
2672                     return nodes;
2673                 }
2674             },
2675             {
2676                 data: "me.lost_status",
2677                 className: "status",
2678                 searchable: false, // FIXME We are losing the ability to search on the status
2679                 orderable: false,
2680                 render: function (data, type, row, meta) {
2681                     let nodes = "";
2682                     if ( row.checkout ) {
2683                         nodes += '<span>';
2684                         if ( row.checkout.onsite_checkout ) {
2685                             if ( can_edit_items_from[row.holding_library_id] ){
2686                                 let patron_to_html = $patron_to_html(row.checkout.patron); [%# FIXME What about hide_patron_infos_if_needed?? %]
2687                                 nodes += _("Currently in local use by %s").format(patron_to_html);
2688                             } else {
2689                                 nodes += _("Currently in local use");
2690                             }
2691                         } else {
2692                             nodes += '<span class="datedue">';
2693                             if ( can_edit_items_from[row.holding_library_id] ){
2694                                 let patron_to_html = $patron_to_html(row.checkout.patron); [%# FIXME What about hide_patron_infos_if_needed?? %]
2695                                 nodes += _("Checked out to %s").format(patron_to_html);
2696                             } else {
2697                                 nodes += _("Checked out");
2698                             }
2699                         }
2700                         nodes += ': ';
2701                         nodes += _("due %s").format($date(row.checkout.due_date)); [%# FIXME Missing due date formatting here, $date do not have as_due_date option %]
2702                         nodes += "</span>"
2703                     } else if ( row.transfer ) {
2704                         if ( row.transfer.datesent ) {
2705                             nodes += '<span class="intransit">%s</span>'.format(_("In transit from %s to %s since %s").format(row.transfer.frombranch, row.transfer.tobranch, $date(row.transfer.datesent))); [%# FIXME display library names, not codes, do we use _strings here? %]
2706                         } else {
2707                             nodes += '<span class="transitrequested">%s</span>'.format(_("Transit pending from %s to %s since %s").format(row.transfer.frombranch, row.transfer.tobranch, $date(row.transfer.daterequested))); [%# FIXME See above %]
2708                         }
2709                     }
2710
2711                     if ( row.lost_status ) {
2712                         let lost_lib = av_lost.get(row.lost_status.toString()) || _("Unavailable (lost or missing");
2713                         nodes += '<span class="lost">%s</span>'.format(lost_lib);
2714                     }
2715
2716                     if ( row.withdrawn ) {
2717                         let withdrawn_lib = av_withdrawn.get(row.withdrawn.toString()) || _("Withdrawn");
2718                         nodes += '<span class="wdn">%s</span>'.format(withdrawn_lib);
2719                     }
2720
2721                     if ( row.damaged ) {
2722                         let damaged_lib = av_damaged.get(row.damaged.toString()) || _("Damaged");
2723                         nodes += '<span class="dmg">%s</span>'.format(damaged_lib);
2724                     }
2725
2726                     if ( row.not_for_loan_status || row.item_type.notforloan ) {
2727                         let not_for_loan_lib = av_not_for_loan.get(row.not_for_loan_status.toString());
2728                         nodes += '<span class="notforloan">%s'.format(_("Not for loan")) + ( not_for_loan_lib ? '<span class="reason"> (%s)</span>'.format(not_for_loan_lib) : '' ) + '</span>';
2729                     }
2730
2731                     if ( row.first_hold ) {
2732                         if ( row.first_hold.waiting_date ) {
2733                             [%# FIXME Display library names instead of codes %]
2734                             [%# FIXME We lost the desk name, we need an additional embed %]
2735                             nodes += '<span class="waitingat">%s</span>'.format(_("Waiting at %s since %s.".format(row.first_hold.pickup_library_id, $date(row.first_hold.waiting_date))));
2736                             [% IF Koha.Preference('canreservefromotherbranches') %]
2737                                 if ( row.first_hold.waiting_date || row.first_hold.priority == 1 ) {
2738                                     let patron_to_html = $patron_to_html(row.first_hold.patron); [%# FIXME What about hide_patron_infos_if_needed?? %]
2739                                     nodes += ' <span class="heldfor">%s</span>'.format(_("Hold for: %s").format(patron_to_html));
2740                                 }
2741                             [% END %]
2742                         } else {
2743                             nodes += '<span class="holdonitem">%s</span>'.format(_("There is an item level hold on this item (priority = %s).").format(row.first_hold.priority));
2744                         }
2745                     }
2746
2747                     [% IF Koha.Preference('UseRecalls') %]
2748                         if ( row.recall ) {
2749                             if ( row.recall.waiting_date ) {
2750                                 nodes += '<span>%s</span>'.format(_("Waiting at %s since %s").format(row.recall.pickup_library_id, $date(row.recall.waiting_date))); # FIXME Display library names instead of codes
2751                             } else {
2752                                 let patron_to_html = $patron_to_html(row.recall.patron);
2753                                 nodes += '<span>%s</span>'.format(_("recalled by %s on %s").format(patron_to_html, row.recall.created_date));
2754                             }
2755                         }
2756                     [% END %]
2757
2758                     if ( ! ( row.not_for_loan_status || row.item_type.notforloan || row.checked_out_date || row.lost_status || row.withdrawn || row.damaged || row.transfer || row.first_hold || row.recall ) ) {
2759                         nodes += ' <span>%s</span>'.format(_("Available"))
2760                     }
2761
2762                     if ( row.restricted_status ) {
2763                         nodes += '<span class="restricted">(%s)</span>'.format(av_restricted.get(row.restricted_status.toString()));
2764                     }
2765
2766                     if ( row.in_bundle ) {
2767                         nodes += '<span class="bundled">%s</span>'.format(_("In bundle: %s").format($biblio_to_html(row.bundle_host.biblio, { link: true })));
2768                     }
2769                     return nodes;
2770                 }
2771             },
2772             {
2773                 data: "me.last_seen_date",
2774                 className: "datelastseen",
2775                 searchable: true,
2776                 orderable: true,
2777                 render: function (data, type, row, meta) {
2778                     return $date(row.last_seen_date);
2779                 }
2780             },
2781             {
2782                 data: "me.checkouts_count",
2783                 className: "issues",
2784                 searchable: true,
2785                 orderable: true,
2786                 render: function (data, type, row, meta) {
2787                     return row.checkouts_count || 0;
2788                 }
2789             },
2790             {
2791                 data: "me.renewals_count",
2792                 className: "renewals",
2793                 searchable: true,
2794                 orderable: true,
2795                 render: function (data, type, row, meta) {
2796                     return row.renewals_count || 0;
2797                 }
2798             },
2799             {
2800                 data: "me.acquisition_date",
2801                 className: "dateaccessioned",
2802                 searchable: true,
2803                 orderable: true,
2804                 render: function (data, type, row, meta) {
2805                     return $date(row.acquisition_date);
2806                 }
2807             },
2808             {
2809                 data: "me.last_checkout_date",
2810                 className: "datelastborrowed",
2811                 searchable: true,
2812                 orderable: true,
2813                 render: function (data, type, row, meta) {
2814                     return $date(row.last_checkout_date);
2815                 }
2816             },
2817             {
2818                 data: "me.external_id",
2819                 className: "",
2820                 searchable: true,
2821                 orderable: true,
2822                 render: function (data, type, row, meta) {
2823                     return '<a href="/cgi-bin/koha/catalogue/moredetail.pl?biblionumber=%s#item%s">%s</a>'.format(row.biblio_id, row.item_id, row.external_id);
2824                 }
2825             },
2826             {
2827                 data: "me.uri",
2828                 className: "uri",
2829                 searchable: true,
2830                 orderable: true,
2831                 render: function (data, type, row, meta) {
2832                     if ( !row.uri ) return "";
2833
2834                     let nodes = '';
2835                     if ( row.uri.split(' \| ').length > 1 ) {
2836                         row.uri.split(' \| ').forEach((uri, i) => {
2837                             nodes += '<a href="%s">%s</a><br/>'.format(uri, uri);
2838                         });
2839                     } else {
2840                         nodes += '<a href="%s">%s</a><br/>'.format(row.uri, url_link_text);
2841                     }
2842                     return nodes;
2843                 }
2844             },
2845             {
2846                 data: "me.copy_number",
2847                 className: "copynumber",
2848                 searchable: true,
2849                 orderable: true,
2850                 render: function (data, type, row, meta) {
2851                     return row._strings.copy_number ? row._strings.copy_number.str : row.copy_number;
2852                 }
2853             },
2854             {
2855                 data: "me.inventory_number",
2856                 className: "stocknumber",
2857                 searchable: true,
2858                 orderable: true,
2859                 render: function (data, type, row, meta) {
2860                     return row.inventory_number;
2861                 }
2862             },
2863             {
2864                 data: "me.materials_notes",
2865                 className: "materials",
2866                 searchable: true,
2867                 orderable: true,
2868                 render: function (data, type, row, meta) {
2869                     return row.materials_notes;
2870                 }
2871             },
2872             {
2873                 data: "me.public_notes",
2874                 className: "itemnotes",
2875                 searchable: true,
2876                 orderable: true,
2877                 render: function (data, type, row, meta) {
2878                     return row.public_notes ? row.public_notes.replaceAll('\n', '<br />') : '';
2879                 }
2880             },
2881             {
2882                 data: "me.internal_notes",
2883                 className: "nonpublicnote",
2884                 searchable: true,
2885                 orderable: true,
2886                 render: function (data, type, row, meta) {
2887                     return row.internal_notes;
2888                 }
2889             },
2890             [% IF ( hostrecords ) %]
2891             {
2892                 data: "biblio.biblio_id",
2893                 searchable: false, // FIXME
2894                 orderable: true,
2895                 render: function (data, type, row, meta) {
2896                     if ( row.biblio_id == [% biblio.biblionumber %] ) return "";
2897                     return '<a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=%s>%s</a>'.format(row.biblio_id, row.biblio.title);
2898                 }
2899             },
2900             [% END %]
2901             [% IF ( analyze ) %]
2902             {
2903                 data: "",
2904                 searchable: false, // FIXME
2905                 orderable: true,
2906                 render: function (data, type, row, meta) {
2907                     return ""; // FIXME Display analytic count + link
2908                 }
2909             },
2910             [% END %]
2911             [% IF ( ShowCourseReserves ) %]
2912             {
2913                 data: "",
2914                 searchable: false, // FIXME
2915                 orderable: true,
2916                 render: function (data, type, row, meta) {
2917                     return ""; // FIXME Display course reserves
2918                 }
2919             },
2920             [% END %]
2921             [% IF ( SpineLabelShowPrintOnBibDetails ) %]
2922             {
2923                 data: "",
2924                 searchable: false,
2925                 orderable: false,
2926                 render: function (data, type, row, meta) {
2927                     return '<a class="btn btn-default btn-xs print-label" href="/cgi-bin/koha/labels/spinelabel-print.pl?barcode=%s"><i class="fa fa-print"></i> Print label</a>'.format(row.external_id);
2928                 }
2929             },
2930             [% END %]
2931             [% IF CAN_user_editcatalogue_edit_items %]
2932             {
2933                 data: function( row, type, val, meta ) {
2934                     let nodes = '';
2935                     if ( can_edit_items_from[row.holding_library_id] ){
2936                         [% IF Koha.Preference('LocalCoverImages') OR Koha.Preference('OPACLocalCoverImages') %]
2937                             nodes += '<div class="btn-group">';
2938                             nodes += ' <a class="btn btn-default btn-xs" href="/cgi-bin/koha/cataloguing/additem.pl?op=edititem&biblionumber=%s&itemnumber=%s#edititem"><i class="fa fa-pencil"></i> Edit</a><a class="btn btn-default btn-xs dropdown-toggle" data-toggle="dropdown"><span class="caret"></span></a>'.format(row.biblio_id, row.item_id);
2939                             nodes += ' <ul class="dropdown-menu pull-right">';
2940                             nodes += '  <li><a href="/cgi-bin/koha/tools/upload-cover-image.pl?itemnumber=%s&amp;filetype=image"><i class="fa fa-upload"></i> Upload image</a></li>'.format(row.item_id);
2941                             nodes += ' </ul>';
2942                             nodes += '</div>';
2943                         [% ELSE %]
2944                             nodes += '<a class="btn btn-default btn-xs" href="/cgi-bin/koha/cataloguing/additem.pl?op=edititem&biblionumber=%s&itemnumber=%s#edititem"><i class="fa fa-pencil"></i> Edit</a>'.format(row.biblio_id, row.item_id);
2945                         [% END %]
2946                     }
2947                     [% IF bundlesEnabled %]
2948                         // FIXME How do we handle that correctly?
2949                         //nodes += '<button class="btn btn-default btn-xs details-control"><i class="fa fa-folder"></i> Manage bundle (%s|%s)</button>'.format(row.bundled, row.bundled_lost);
2950                     [% END %]
2951
2952                     return nodes;
2953                 },
2954                 className: "actions",
2955                 searchable: false,
2956                 orderable: false
2957             }
2958             [% END %]
2959             ],
2960             initComplete: function( settings, json ){
2961                 let table = settings.oInstance.api();
2962                 table.columns().every(function(i){
2963                     let is_empty = true;
2964                     let nodes = this.nodes();
2965                     nodes.each((td, ii) => {
2966                         if ( $(td).html() !== '' ) {
2967                             is_empty = false;
2968                             return;
2969                         }
2970                     });
2971                     if ( is_empty ) {
2972                         table.columns(i).visible(false);
2973                     }
2974                 });
2975             },
2976         },
2977         table_settings,
2978         true);
2979     </script>
2980     [% CoverImagePlugins | $raw %]
2981 [% END %]
2982 [% INCLUDE 'intranet-bottom.inc' %]