Bugzilla – Attachment 191105 Details for
Bug 41566
Tidy kohaTable block - catalogue
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 41566: Tidy kohaTable - catalogue_detail.inc|catalogue/detail.tt
8f0e3ce.patch (text/plain), 42.33 KB, created by
Jonathan Druart
on 2026-01-09 14:46:08 UTC
(
hide
)
Description:
Bug 41566: Tidy kohaTable - catalogue_detail.inc|catalogue/detail.tt
Filename:
MIME Type:
Creator:
Jonathan Druart
Created:
2026-01-09 14:46:08 UTC
Size:
42.33 KB
patch
obsolete
>From 8f0e3ce4a032dedfc9fe76f50b20a8c9f245e7bd Mon Sep 17 00:00:00 2001 >From: Jonathan Druart <jonathan.druart@bugs.koha-community.org> >Date: Tue, 6 Jan 2026 16:22:10 +0100 >Subject: [PATCH] Bug 41566: Tidy kohaTable - > catalogue_detail.inc|catalogue/detail.tt > >This is a non-trivial one. > >* SpineLabelShowPrintOnBibDetails is removed from the controller and we > fetch it from the Koha.Preference TT plugin (because it is how it should be) >* A lot of JS variable instantiations are moved in a dedicated script tag: they all use TT plugins >* We are using stores to permissions and sysprefs > >That's a lot of changes but nothing complicated, just a move from TT >vars to JS vars > >To test this you will need to fully test the holdings tables. >--- > catalogue/detail.pl | 2 - > .../tables/items/catalogue_detail.inc | 289 ++++++++++-------- > .../prog/en/modules/catalogue/detail.tt | 102 +++++-- > 3 files changed, 228 insertions(+), 165 deletions(-) > >diff --git a/catalogue/detail.pl b/catalogue/detail.pl >index f8a1fe447ec..1834d154ce4 100755 >--- a/catalogue/detail.pl >+++ b/catalogue/detail.pl >@@ -173,8 +173,6 @@ my $fw = GetFrameworkCode($biblionumber); > my $showallitems = $query->param('showallitems'); > my $marcflavour = C4::Context->preference("marcflavour"); > >-$template->param( 'SpineLabelShowPrintOnBibDetails' => C4::Context->preference("SpineLabelShowPrintOnBibDetails") ); >- > $template->param( ocoins => !$invalid_marc_record ? $biblio->get_coins : undef ); > > # some useful variables for enhanced content; >diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/html_helpers/tables/items/catalogue_detail.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/html_helpers/tables/items/catalogue_detail.inc >index d74198bdaf0..5be8f2af20a 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/includes/html_helpers/tables/items/catalogue_detail.inc >+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/html_helpers/tables/items/catalogue_detail.inc >@@ -42,7 +42,7 @@ > [% IF Koha.Preference('EasyAnalyticalRecords') %]<th id="[% tab | html %]_hostrecord" data-colname="hostrecord">Host records</th>[% END %] > [% IF ( analyze ) %]<th id="[% tab | html %]_usedin" data-colname="usedin">Used in</th><th></th>[% END %] > [% IF Koha.Preference('UseCourseReserves') %]<th id="[% tab | html %]_course_reserves" data-colname="course_reserves">Course reserves</th>[% END %] >- [% IF ( SpineLabelShowPrintOnBibDetails ) %]<th id="[% tab | html %]_spinelabel" data-colname="spinelabel" class="no-sort">Spine label</th>[% END %] >+ [% IF Koha.Preference('SpineLabelShowPrintOnBibDetails') %]<th id="[% tab | html %]_spinelabel" data-colname="spinelabel" class="no-sort">Spine label</th>[% END %] > [% IF ( CAN_user_editcatalogue_edit_items ) %]<th id="[% tab | html %]_actions" data-colname="actions" class="no-sort no-export"> </th>[% END %] > </tr> > </thead> >@@ -95,7 +95,77 @@ > [% BLOCK build_items_table_js %] > <script> > let hide_patron_name = [% IF Koha.Preference('HidePatronName') %]true[% ELSE %]false[% END %]; >+ const all_libraries = [% To.json(Branches.all) | $raw %].map(e => { >+ e["_id"] = e["branchcode"]; >+ e["_str"] = e["branchname"]; >+ return e; >+ }); >+ const libraries_names = new Map(all_libraries.map( l => [l.branchcode, l.branchname] )); >+ const all_item_types = [% To.json(ItemTypes.Get) | $raw %].map(e => { >+ e["_id"] = e["itemtype"]; >+ e["_str"] = e["translated_description"]; >+ return e; >+ }); >+ const item_types_notforloan = new Map(all_item_types.map( it => [it.itemtype, it.notforloan] )); >+ >+ const can_edit_items_from = [% To.json(can_edit_items_from || []) | $raw %]; >+ const item_type_image_locations = [% To.json(item_type_image_locations) | $raw %]; >+ const av_loc = new Map([% To.json(AuthorisedValues.GetDescriptionsByKohaField({ kohafield => 'items.location' })) | $raw %].map( av => [av.lib, av.authorised_value])); >+ const av_lost = new Map([% To.json(AuthorisedValues.GetDescriptionsByKohaField({ kohafield => 'items.itemlost' })) | $raw %].map( av => [av.authorised_value, av.lib])); >+ const av_withdrawn = new Map([% To.json(AuthorisedValues.GetDescriptionsByKohaField({ kohafield => 'items.withdrawn' })) | $raw %].map( av => [av.authorised_value, av.lib])); >+ const av_damaged = new Map([% To.json(AuthorisedValues.GetDescriptionsByKohaField({ kohafield => 'items.damaged' })) | $raw %].map( av => [av.authorised_value, av.lib])); >+ const av_not_for_loan= new Map([% To.json(AuthorisedValues.GetDescriptionsByKohaField({ kohafield => 'items.notforloan' })) | $raw %].map( av => [av.authorised_value, av.lib])); >+ const av_restricted = new Map([% To.json(AuthorisedValues.GetDescriptionsByKohaField({ kohafield => 'items.restricted' })) | $raw %].map( av => [av.authorised_value, av.lib])); >+ [% IF Koha.Preference('UseCourseReserves') %] >+ const av_courses_term = new Map([% To.json(AuthorisedValues.Get('TERM')) | $raw %].map( av => [av.authorised_value, av.lib])); >+ [% END %] >+ const av_ccode = new Map([% To.json(AuthorisedValues.GetDescriptionsByKohaField({ kohafield => 'items.ccode' })) | $raw %].map( av => [av.lib, av.authorised_value])); >+ >+ [% IF Koha.Preference('URLLinkText') %] >+ const url_link_text = "[% Koha.Preference('URLLinkText') | html %]"; >+ [% ELSE %] >+ const url_link_text = _("Link to resource"); >+ [% END %] > >+ var biblionumber = [% biblio.biblionumber | html %]; >+ const is_serial = [% biblio.serial ? 1 : 0 | html %]; >+ const analyze = [% analyze ? 1 : 0 | html %]; >+ const hidden_count = [% hidden_count ? 1 : 0 | html %]; >+ const bundlesEnabled = [% bundlesEnabled ? 1 : 0 | html %]; >+ addPrefs({ >+ LocalCoverImages: [% Koha.Preference('LocalCoverImages') ? 1 : 0 | html %], >+ OPACLocalCoverImages: [% Koha.Preference('OPACLocalCoverImages') ? 1 : 0 | html %], >+ EnableItemGroups: [% Koha.Preference('EnableItemGroups') ? 1 : 0 | html %], >+ UseRecalls: [% Koha.Preference('UseRecalls') ? 1 : 0 | html %], >+ UseCourseReserves: [% Koha.Preference('UseCourseReserves') ? 1 : 0 | html %], >+ ClaimReturnedLostValue: [% Koha.Preference('ClaimReturnedLostValue') | html %], >+ EasyAnalyticalRecords: [% Koha.Preference('EasyAnalyticalRecords') ? 1 : 0| html %], >+ SeparateHoldings: [% Koha.Preference('SeparateHoldings') ? 1 : 0 | html %], >+ SeparateHoldingsBranch: "[% Koha.Preference('SeparateHoldingsBranch') || 'homebranch' | html %]", >+ item_level_itypes: [% item_level_itypes ? 1 : 0 | html %], >+ noItemTypeImages: [% Koha.Preference('noItemTypeImages') ? 1 : 0 | html %], >+ DisplayPublishedDate: [% Koha.Preference('DisplayPublishedDate') ? 1 : 0 | html %], >+ canreservefromotherbranches: [% Koha.Preference('canreservefromotherbranches') ? 1 : 0 | html %], >+ SpineLabelShowPrintOnBibDetails: [% Koha.Preference('SpineLabelShowPrintOnBibDetails') ? 1 : 0 | html %], >+ }); >+ addPermissions({ >+ CAN_user_editcatalogue_edit_items: [% CAN_user_editcatalogue_edit_items ? 1 : 0 | html %], >+ }); >+ const logged_in_branchcode = '[% Branches.GetLoggedInBranchcode() | html %]'; >+ >+ var items_table_settings = { >+ holdings: [% TablesSettings.GetTableSettings('catalogue', 'detail','holdings_table','json') | $raw %], >+ otherholdings: [% TablesSettings.GetTableSettings('catalogue', 'detail','otherholdings_table','json') | $raw %], >+ }; >+ >+ let table_nodes = { >+ holdings: "[% PROCESS 'build_table' tab="holdings" | collapse | $tojson %]", >+ otherholdings: "[% PROCESS 'build_table' tab="otherholdings" | collapse | $tojson %]", >+ }; >+ >+ </script> >+ >+ <script> > let items_selection = {}; > > function _itemSelectionBuildLink(tab_id, link_class) { >@@ -205,39 +275,14 @@ > }); > }); > >- const all_libraries = [% To.json(Branches.all) | $raw %].map(e => { >- e["_id"] = e["branchcode"]; >- e["_str"] = e["branchname"]; >- return e; >- }); >- const libraries_names = new Map(all_libraries.map( l => [l.branchcode, l.branchname] )); >- const all_item_types = [% To.json(ItemTypes.Get) | $raw %].map(e => { >- e["_id"] = e["itemtype"]; >- e["_str"] = e["translated_description"]; >- return e; >- }); >- const item_types_notforloan = new Map(all_item_types.map( it => [it.itemtype, it.notforloan] )); >- > const statuses = {checked_out: _("Checked out"), local_use: _("On-site checkout"), in_transit: _("In transit"), lost: _("Lost"), withdrawn: _("Withdrawn"), damaged:_("Damaged"), not_for_loan: _("Not for loan"), on_hold: _("On hold"), recalled: _("Recalled"), available: _("Available"), restricted: _("Restricted"), in_bundle: _("In bundle")}; > const all_statuses = Object.keys(statuses).map(k => {return {_id: k, _str: statuses[k]}}); > >- const can_edit_items_from = [% To.json(can_edit_items_from || []) | $raw %]; >- const item_type_image_locations = [% To.json(item_type_image_locations) | $raw %]; >- const av_loc = new Map([% To.json(AuthorisedValues.Get('LOC')) | $raw %].map( av => [av.authorised_value, av.lib])); >- const av_lost = new Map([% To.json(AuthorisedValues.GetDescriptionsByKohaField({ kohafield => 'items.itemlost' })) | $raw %].map( av => [av.authorised_value, av.lib])); >- const av_withdrawn = new Map([% To.json(AuthorisedValues.GetDescriptionsByKohaField({ kohafield => 'items.withdrawn' })) | $raw %].map( av => [av.authorised_value, av.lib])); >- const av_damaged = new Map([% To.json(AuthorisedValues.GetDescriptionsByKohaField({ kohafield => 'items.damaged' })) | $raw %].map( av => [av.authorised_value, av.lib])); >- const av_not_for_loan= new Map([% To.json(AuthorisedValues.GetDescriptionsByKohaField({ kohafield => 'items.notforloan' })) | $raw %].map( av => [av.authorised_value, av.lib])); >- const av_restricted = new Map([% To.json(AuthorisedValues.GetDescriptionsByKohaField({ kohafield => 'items.restricted' })) | $raw %].map( av => [av.authorised_value, av.lib])); >- [% IF Koha.Preference('UseCourseReserves') %] >- const av_courses_term = new Map([% To.json(AuthorisedValues.Get('TERM')) | $raw %].map( av => [av.authorised_value, av.lib])); >- [% END %] >- > var coded_values = { > library: new Map(all_libraries.map( l => [l.branchname, l.branchcode] )), > item_type: new Map(all_item_types.map( i => [i.translated_description, i.itemtype] )), >- collection_code: new Map([% To.json(AuthorisedValues.GetDescriptionsByKohaField({ kohafield => 'items.ccode' })) | $raw %].map( av => [av.lib, av.authorised_value])), >- location: new Map([% To.json(AuthorisedValues.GetDescriptionsByKohaField({ kohafield => 'items.location' })) | $raw %].map( av => [av.lib, av.authorised_value])), >+ collection_code: av_ccode, >+ location: av_loc, > }; > > let filters_options = { >@@ -247,55 +292,41 @@ > statuses: all_statuses, > }; > >- [% IF Koha.Preference('URLLinkText') %] >- const url_link_text = "[% Koha.Preference('URLLinkText') | html %]"; >- [% ELSE %] >- const url_link_text = _("Link to resource"); >- [% END %] >- [%# FIXME The X-Base-Total-Count will be the number of items of the biblios %] >- [%# In case or SeparateHoldings we may need to display the number of biblios in each tab %] >- [%# Do we need separate/new endpoints or do we hack the somewhere client-side? %] >- let item_table_url = "/api/v1/biblios/[% biblio.biblionumber | uri %]/items?"; >+ // FIXME The X-Base-Total-Count will be the number of items of the biblios >+ // In case or SeparateHoldings we may need to display the number of biblios in each tab >+ // Do we need separate/new endpoints or do we hack the somewhere client-side? >+ let item_table_url = `/api/v1/biblios/${biblionumber}/items?`; > let embed = ["+strings,_status,home_library,holding_library,checkout,checkout.patron,transfer,transfer+strings,first_hold,first_hold+strings,first_hold.patron,first_hold.desk"]; >- [% IF Koha.Preference('LocalCoverImages') %] >+ if (prefs.LocalCoverImages){ > embed.push('cover_image_ids'); >- [% END %] >- [% IF Koha.Preference('EnableItemGroups') %] >+ } >+ if (prefs.EnableItemGroups){ > embed.push('item_group_item.item_group.description'); >- [% END %] >- [% IF biblio.serial %] >+ } >+ if (is_serial){ > embed.push('serial_item.serial'); >- [% END %] >- [% IF Koha.Preference('UseRecalls') %] >+ } >+ if (prefs.UseRecalls){ > embed.push('recall', 'recall+strings', 'recall.patron') >- [% END %] >+ } > embed.push('in_bundle', 'bundle_host', 'bundle_host.biblio', 'bundle_items_lost+count', 'bundle_items_not_lost+count'); >- [% IF Koha.Preference('UseCourseReserves') %] >+ if (prefs.UseCourseReserves){ > embed.push('course_item.course_reserves.course'); >- [% END %] >- [% IF Koha.Preference('ClaimReturnedLostValue') %] >+ } >+ if (prefs.ClaimReturnedLostValue){ > embed.push('return_claims'); >- [% END %] >+ } > >- [% IF Koha.Preference('EasyAnalyticalRecords') %] >+ if (prefs.EasyAnalyticalRecords){ > // For host records > embed.push('biblio.title'); >- [% END %] >+ } > >- [% IF analyze %] >+ if (analyze){ > embed.push('analytics_count'); >- [% END %] >- >- var items_table_settings = { >- holdings: [% TablesSettings.GetTableSettings('catalogue', 'detail','holdings_table','json') | $raw %], >- otherholdings: [% TablesSettings.GetTableSettings('catalogue', 'detail','otherholdings_table','json') | $raw %], >- }; >+ } > > let user_colvis = {holdings: {}, otherholdings: {}}; >- let table_nodes = { >- holdings: "[% PROCESS 'build_table' tab="holdings" | collapse | $tojson %]", >- otherholdings: "[% PROCESS 'build_table' tab="otherholdings" | collapse | $tojson %]", >- }; > function build_items_table (tab_id, add_filters, dt_options, drawcallback) { > > let table_dt; >@@ -311,19 +342,18 @@ > user_colvis[tab_id] = user_colvis_bak; > } > let default_filters = {}; >- [% IF Koha.Preference('SeparateHoldings') %] >- [% SET SeparateHoldingsBranch = Koha.Preference('SeparateHoldingsBranch') || 'homebranch' %]; >- let branch = '[% IF SeparateHoldingsBranch == 'homebranch' %]me.home_library_id[% ELSE %]me.holding_library_id[% END %]'; >+ if (prefs.SeparateHoldings){ >+ let branch = prefs.SeparateHoldingsBranch == 'homebranch' ? 'me.home_library_id' : 'me.holding_library_id'; > if ( tab_id == 'holdings' ) { >- default_filters[branch] = '[% Branches.GetLoggedInBranchcode() | html %]'; >+ default_filters[branch] = logged_in_branchcode; > } else { >- default_filters[branch] = { '!=': '[% Branches.GetLoggedInBranchcode() | html %]' }; >+ default_filters[branch] = { '!=': logged_in_branchcode }; > } >- [% END %] >+ } > >- [% IF hidden_count %] >+ if (hidden_count){ > default_filters.lost_status = "0"; >- [% END %] >+ } > if ( !items_selection.hasOwnProperty(tab_id) ){ > items_selection[tab_id] = []; > } >@@ -332,13 +362,7 @@ > return $("#" + tab_id + "_status select").val(); > }; > >- var items_table = $("#" + tab_id + '_table').kohaTable({ >- ajax: { url: item_table_url }, >- order: [], >- embed, >- autoWidth: false, >- bKohaColumnsUseNames: true, >- columns: [ >+var columns = [ > { > data: "me.item_id", > searchable: false, >@@ -355,8 +379,8 @@ > } > } > }, >- [% IF Koha.Preference('LocalCoverImages') %] >- { >+ ...(prefs.LocalCoverImages ? >+ [{ > data: "", > className: "cover", > searchable: false, >@@ -378,10 +402,9 @@ > node += '</div>'; > return node; > } >- }, >- [% END %] >- [% IF ( item_level_itypes ) %] >- { >+ }] : []), >+ ...(prefs.item_level_itypes ? >+ [{ > data: "me.item_type_id", // FIXME Cannot filter by biblioitem.itemtype > datatype: "coded_value:item_type", > dataFilter: "item_types", >@@ -391,17 +414,16 @@ > render: function (data, type, row, meta) { > let node = ''; > let item_type_description = row._strings.item_type_id ? row._strings.item_type_id.str : row.item_type_id; >- [% UNLESS noItemTypeImages %] >+ if (prefs.noItemTypeImages){ > let image_location = item_type_image_locations[row.item_type_id]; > node += image_location > ? '<img class="itemtype-image" src="%s" alt="" /> '.format(escape_str(image_location), escape_str(item_type_description), escape_str(item_type_description)) > : ''; >- [% END %] >+ } > node += '<span class="itypedesc itypetext">%s</span>'.format(escape_str(item_type_description)); > return node; > } >- }, >- [% END %] >+ }] : []), > { > data: "me.holding_library_id", > datatype: "coded_value:library", >@@ -431,9 +453,9 @@ > orderable: true, > render: function (data, type, row, meta) { > let nodes = '<span class="shelvingloc">'; >- [%# If permanent location is defined, show description or code and %] >- [%# display current location in parentheses. If not, display current location. %] >- [%# Note that permanent location is a code, and location may be an authval. %] >+ // If permanent location is defined, show description or code and >+ // display current location in parentheses. If not, display current location. >+ // Note that permanent location is a code, and location may be an authval. > let loc_str = row._strings.location ? row._strings.location.str : row.location; > if ( row.permanent_location && row.permanent_location != row.location ) { > let permanent_loc_str = av_loc.get(row.permanent_location); >@@ -454,8 +476,8 @@ > return escape_str(row._strings.collection_code ? row._strings.collection_code.str : row.collection_code); > } > }, >- [% IF Koha.Preference('EnableItemGroups') %] >- { >+ ...(prefs.EnableItemGroups ? >+ [{ > data: "item_group_item.item_group.description", > className: "item_group", > searchable: true, >@@ -467,8 +489,7 @@ > return ""; > } > } >- }, >- [% END %] >+ }] : []), > { > data: "me.callnumber", > className: "itemcallnumber", >@@ -486,7 +507,7 @@ > orderable: true, > render: function (data, type, row, meta) { > let nodes = ""; >- [%# 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? %] >+ // 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? > let serial = row.serial_item ? row.serial_item.serial : null; > if ( row.serial_issue_number && serial && serial.serialseq ) { > nodes += '<span class="enum">%s</span>'.format(escape_str(row.serial_issue_number)); >@@ -499,11 +520,11 @@ > } else if ( serial && serial.serialseq ) { > nodes += '<span class="serialseq">%s</span>'.format(escape_str(serial.serialseq)); > } >- [% IF Koha.Preference('DisplayPublishedDate') %] >+ if (prefs.DisplayPublishedDate){ > if ( serial && serial.publisheddate ) { > nodes += ' <span class="pubdate">(%s)</span>'.format($date(serial.publisheddate)); > } >- [% END %] >+ } > return nodes; > } > }, >@@ -519,7 +540,7 @@ > if ( status == 'checked_out' || status == 'local_use') { > nodes += '<span>'; > >- [%# Hacky for patron_to_html in case we simply want to display the patron's library name %] >+ // Hacky for patron_to_html in case we simply want to display the patron's library name > row.checkout.patron.library = { name: libraries_names.get(row.checkout.patron.library_id) }; > let patron_to_html = $patron_to_html(row.checkout.patron, { url: true, display_cardnumber: true, hide_patron_name }); > >@@ -574,33 +595,33 @@ > } else { > nodes += '<span class="waitingat">%s</span>'.format(_("Waiting at %s since %s.".format(row.first_hold._strings.pickup_library_id.str, $date(row.first_hold.waiting_date)))); > } >- [% IF Koha.Preference('canreservefromotherbranches') %] >+ if (prefs.canreservefromotherbranches){ > if ( row.first_hold.waiting_date || row.first_hold.priority == 1 ) { >- [%# Hacky for patron_to_html in case we simply want to display the patron's library name %] >+ // Hacky for patron_to_html in case we simply want to display the patron's library name > row.first_hold.patron.library = { name: libraries_names.get(row.first_hold.patron.library_id) }; > > let patron_to_html = $patron_to_html(row.first_hold.patron, { url: true, display_cardnumber: true, hide_patron_name }); > nodes += ' <span class="heldfor">%s</span>'.format(_("Hold for: %s").format(patron_to_html)); > } >- [% END %] >+ } > } else { > nodes += ' <span class="holdonitem">%s</span>'.format(_("There is an item level hold on this item (priority = %s).").format(row.first_hold.priority)); > } > } > >- [% IF Koha.Preference('UseRecalls') %] >+ if (prefs.UseRecalls){ > if ( row.recall && ( row.item_id === row.recall.item_id ) ) { > if ( row.recall.waiting_date ) { > nodes += '<span class="holding_status recallwaiting">%s</span>'.format(_("Waiting recall at %s since %s").format(escape_str(row.recall._strings.pickup_library_id.str), $date(row.recall.waiting_date))); > } else { >- [%# Hacky for patron_to_html in case we simply want to display the patron's library name %] >+ // Hacky for patron_to_html in case we simply want to display the patron's library name > row.recall.patron.library = { name: libraries_names.get(row.recall.patron.library_id) }; > > let patron_to_html = $patron_to_html(row.recall.patron, {url: true, display_cardnumber: true, hide_patron_name }); > nodes += '<span class="holding_status recalledby">%s</span>'.format(_("Recalled by %s on %s").format(patron_to_html, $date(row.recall.created_date))) > } > } >- [% END %] >+ } > if ( status == 'available' ) { > nodes += ' <span>%s</span>'.format(_("Available")) > } >@@ -759,19 +780,18 @@ > return escape_str(row.internal_notes); > } > }, >- [% IF Koha.Preference('EasyAnalyticalRecords') %] >- { >+ ...(prefs.EasyAnalyticalRecords? >+ [{ > data: "biblio.title", > searchable: false, > orderable: true, > render: function (data, type, row, meta) { >- if ( row.biblio_id == [% biblio.biblionumber | html %] ) return ""; >+ if ( row.biblio_id == biblionumber ) return ""; > return '<a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=%s">%s</a>'.format(row.biblio_id, row.biblio.title); > } >- }, >- [% END %] >- [% IF analyze %] >- { >+ }]:[]), >+ ...(analyze ? >+ [{ > data: "analytics_count", > searchable: false, > orderable: false, >@@ -787,10 +807,9 @@ > render: function (data, type, row, meta) { > return '<a href="/cgi-bin/koha/cataloguing/addbiblio.pl?hostbiblionumber=%s&hostitemnumber=%s">%s</a>'.format(row.biblio_id, row.item_id, _("Create analytics")); > } >- }, >- [% END %] >- [% IF Koha.Preference('UseCourseReserves') %] >- { >+ }]:[]), >+ ...(prefs.UseCourseReserves? >+ [{ > data: "course_item.course_reserves.course.course_name", > searchable: true, > orderable: true, >@@ -813,46 +832,50 @@ > }); > return nodes; > } >- }, >- [% END %] >- [% IF ( SpineLabelShowPrintOnBibDetails ) %] >- { >+ }]:[]), >+ ...(prefs.SpineLabelShowPrintOnBibDetails? >+ [{ > data: "", > searchable: false, > orderable: false, > render: function (data, type, row, meta) { > 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(escape_str(row.external_id)); > } >- }, >- [% END %] >- [% IF CAN_user_editcatalogue_edit_items %] >- { >+ }]:[]), >+ ...(permissions.CAN_user_editcatalogue_edit_items ? >+ [{ > data: function( row, type, val, meta ) { > let nodes = ''; > if ( can_edit_items_from.includes(row.home_library_id) || !can_edit_items_from.length ){ >- [% IF Koha.Preference('LocalCoverImages') OR Koha.Preference('OPACLocalCoverImages') %] >+ if (prefs.LocalCoverImages || prefs.OPACLocalCoverImages){ > nodes += '<div class="btn-group dropup">'; > 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-solid fa-pencil"></i> %s</a><a class="btn btn-default btn-xs dropdown-toggle" data-bs-toggle="dropdown"><span class="caret"></span></a>'.format(row.biblio_id, row.item_id, _("Edit")); > nodes += ' <ul class="dropdown-menu">'; > nodes += ' <li><a class="dropdown-item" href="/cgi-bin/koha/tools/upload-cover-image.pl?itemnumber=%s&filetype=image"><i class="fa fa-upload"></i> %s</a></li>'.format(row.item_id, _("Upload image")); > nodes += ' </ul>'; > nodes += '</div>'; >- [% ELSE %] >+ } else { > 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-solid fa-pencil"></i> %s</a>'.format(row.biblio_id, row.item_id, _("Edit")); >- [% END %] >+ } > } >- [% IF bundlesEnabled %] >+ if (bundlesEnabled){ > nodes += '<button class="btn btn-default btn-xs details-control"><i class="fa fa-folder"></i> %s</button>'.format(_("Manage bundle (%s|%s)").format(row.bundle_items_not_lost_count, row.bundle_items_lost_count)); >- [% END %] >+ } > > return nodes; > }, > className: "actions", > searchable: false, > orderable: false >- } >- [% END %] >- ], >+ }]:[]) >+ ]; >+ var items_table = $("#" + tab_id + '_table').kohaTable({ >+ ajax: { url: item_table_url }, >+ order: [], >+ embed, >+ autoWidth: false, >+ bKohaColumnsUseNames: true, >+ columns, > initComplete: function( settings, json ){ > itemSelectionBuildActionLinks(tab_id); > }, >@@ -885,13 +908,13 @@ > container.find(".bottom.pager").remove(); > } > >- [% IF ( SpineLabelShowPrintOnBibDetails ) %] >+ if (prefs.SpineLabelShowPrintOnBibDetails){ > $(".print-label").on("click", function(e){ > e.preventDefault(); > link = $(this).attr("href"); > openWindow(link,"Print spine label",400,400); > }); >- [% END %] >+ } > > if ( api.data().length ) { > update_columns_visibility(api, items_table_settings[tab_id], user_colvis[tab_id]); >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt >index 3e75b635e9a..7e67e92507a 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt >@@ -1277,10 +1277,14 @@ > [% Asset.js("js/modals/add_catalog_concern.js") | $raw %] > [% END %] > [% IF ( ( Koha.Preference('CatalogConcerns') || Koha.Preference('OpacCatalogConcerns') ) && CAN_user_editcatalogue_edit_catalogue ) %] >+ <script> >+ var table_settings = [% TablesSettings.GetTableSettings( 'catalogue', 'concerns', 'table_concerns', 'json' ) | $raw %]; >+ const biblio_id = "[% biblionumber | html %]"; >+ </script> >+ > <script> > $(document).ready(function() { > $("#bibliodetails a:first").tab("show"); >- var table_settings = [% TablesSettings.GetTableSettings( 'catalogue', 'concerns', 'table_concerns', 'json' ) | $raw %]; > > let additional_filters = { > resolved_date: function(){ >@@ -1291,7 +1295,7 @@ > } > }, > source: 'catalog', >- biblio_id: [% biblionumber | uri %] >+ biblio_id, > }; > let external_filter_nodes = { > hide_resolved_concerns: "#hide_resolved_concerns", >@@ -1724,6 +1728,7 @@ > [% IF Koha.Preference('EnableBooking') %] > [% Asset.js("js/modals/place_booking.js") | $raw %] > [% END %] >+ > <script> > var browser; > browser = KOHA.browser("[% searchid | html %]", parseInt(biblionumber, 10)); >@@ -1731,21 +1736,32 @@ > > [% IF bundlesEnabled %] > var bundle_settings = [% TablesSettings.GetTableSettings('catalogue', 'detail','bundle_tables','json') | $raw %]; >- var bundle_lost_value = [% Koha.Preference('BundleLostValue') | html %]; > [% END %] > >+ addPrefs({ >+ AlwaysShowHoldingsTableFilters: [% Koha.Preference('AlwaysShowHoldingsTableFilters') ? 1 : 0 | html %], >+ bundlesEnabled: [% Koha.Preference('bundlesEnabled') ? 1 : 0 | html %], >+ BundleLostValue: "[% Koha.Preference('BundleLostValue') | html %]", >+ }); >+ >+ addPermissions({ >+ CAN_user_editcatalogue_manage_item_groups: [% CAN_user_editcatalogue_manage_item_groups ? 1 : 0 | html %], >+ }); >+ </script> >+ >+ <script> > let items_tab_ids = [ 'holdings', 'otherholdings' ]; > items_tab_ids.forEach( function( tab_id, index ) { > > // Early return if the tab is not shown (ie. no table) > if (!$("#%s_table".format(tab_id)).length) return; >- [% IF Koha.Preference('AlwaysShowHoldingsTableFilters') %] >+ if (prefs.AlwaysShowHoldingsTableFilters){ > build_items_table(tab_id, true, {}, build_items_table_drawncallback); >- [% ELSE %] >+ } else { > build_items_table(tab_id, false, {}, build_items_table_drawncallback); >- [% END %] >+ } > >- [% IF bundlesEnabled %] >+ if (prefs.bundlesEnabled){ > // Add event listener for opening and closing bundle details > $('#' + tab_id + '_table tbody').on('click', 'button.details-control', function () { > var button = $(this); >@@ -1769,10 +1785,10 @@ > button.addClass('active'); > } > }); >- [% END # /IF bundlesEnabled %] >+ } > }); > >- [% IF bundlesEnabled %] // Bundle handling >+ if (bundlesEnabled){ // Bundle handling > function createChild ( row, itemnumber, duedate ) { > // Toolbar > var bundle_toolbar = $('<div id="toolbar" class="btn-toolbar"></div>'); >@@ -1850,7 +1866,7 @@ > "searchable": false, > "orderable": false, > "render": function(data, type, row, meta) { >- if ( row.lost_status == bundle_lost_value ) { >+ if ( row.lost_status == prefs.BundleLostValue ) { > let out = '<span class="lost">' + _("Last seen") + ': ' + $date(row.last_seen_date) + '</span>'; > if ( row.return_claim ) { > out = out + '<span class="claims_return">' + _("Claims returned by") + ': ' + $patron_to_html( row.return_claim.patron, { display_cardnumber: false, url: true } ) + '</span>'; >@@ -2080,11 +2096,16 @@ > bundle_changed = 0; > }); > // End bundle handling >- [% END # /IF bundlesEnabled %] >+ } >+ </script> > >- $(document).ready(function() { >- [% IF Koha.Preference('AcquisitionDetails') %] >- var table_settings = [% TablesSettings.GetTableSettings('catalogue', 'detail', 'acquisitiondetails-table', 'json') | $raw %]; >+ [% IF Koha.Preference('AcquisitionDetails') %] >+ <script> >+ var table_settings = [% TablesSettings.GetTableSettings('catalogue', 'detail', 'acquisitiondetails-table', 'json') | $raw %]; >+ </script> >+ >+ <script> >+ $(document).ready(function() { > var acquisitiondetails_table = $("#orders").kohaTable( > { > dom: 'C<"top pager"ilpfB><"#filter_c">tr<"bottom pager"ip>', >@@ -2094,16 +2115,28 @@ > }, > table_settings > ); >- [% END %] >+ }); >+ </script> >+ [% END %] > >- [% IF suggestions.count %] >+ [% IF suggestions.count %] >+ <script> >+ $(document).ready(function() { > $("#suggestions").kohaTable({ > pagingType: "full", > }); >- [% END %] >+ }); >+ </script> >+ [% END %] >+ >+ [% IF ( reviews ) %] >+ <script> >+ var comment_table_settings = [% TablesSettings.GetTableSettings('catalogue', 'detail', 'comments-table', 'json') | $raw %]; >+ </script> >+ >+ <script> >+ $(document).ready(function() { > >- [% IF ( reviews ) %] >- var comment_table_settings = [% TablesSettings.GetTableSettings('catalogue', 'detail', 'comments-table', 'json') | $raw %]; > var comments_table = $("#comments_table").kohaTable( > { > paging: false, >@@ -2112,19 +2145,25 @@ > }, > comment_table_settings > ); >- [% END %] >- }); >+ }); >+ </script> >+ [% END %] > >- [% IF found1 && Koha.Preference('RetainCatalogSearchTerms') %] >+ [% IF found1 && Koha.Preference('RetainCatalogSearchTerms') %] >+ <script> > $(document).ready(function() { > var search_index = localStorage.getItem("cat_search_pulldown_selection"); > var search_value = localStorage.getItem("searchbox_value"); > if ( search_index ){ $('#cat-search-block select.advsearch').val(search_index)}; > if ( search_value ){ $('#cat-search-block #search-form').val(search_value)}; > }); >- [% END %] >+ </script> >+ [% END %] >+ >+ [% IF Koha.Preference('EnableItemGroups') %] >+ <script> >+ $(document).ready(function() { > >- [% IF Koha.Preference('EnableItemGroups') %] > // Load item groups table > var itemGroupsTable = $("#items-group-table").kohaTable({ > autoWidth: false, >@@ -2144,7 +2183,7 @@ > }, > { > data: function( oObj ) { >- [% IF CAN_user_editcatalogue_manage_item_groups %] >+ if (permissions.CAN_user_editcatalogue_manage_item_groups){ > return `<button class='item-group-edit btn btn-default btn-xs' data-item-group-id='${oObj.item_group_id}'> > <i class="fa-solid fa-pencil" aria-hidden="true"></i> ${_("Edit")} > </button>` >@@ -2152,9 +2191,9 @@ > + `<button class='item-group-delete btn btn-default btn-xs' data-item-group-id='${oObj.item_group_id}'> > <i class='fa fa-trash-can'></i> ${('Delete')} > </button>`; >- [% ELSE %] >+ } else { > return ""; >- [% END %] >+ } > }, > searchable: false, > orderable: false, >@@ -2329,7 +2368,7 @@ > if (itemnumbers.length > 0) { > let url = '/cgi-bin/koha/catalogue/detail.pl?op=set_item_group'; > url += '&itemnumber=' + itemnumbers.join('&itemnumber='); >- url += '&biblionumber=[% biblionumber | uri %]'; >+ url += '&biblionumber=' + biblionumber; > url += `&item_group_id=${item_group_id}`; > > window.location.replace(url); >@@ -2355,7 +2394,7 @@ > if (itemnumbers.length > 0) { > let url = '/cgi-bin/koha/catalogue/detail.pl?op=unset_item_group'; > url += '&itemnumber=' + itemnumbers.join('&itemnumber='); >- url += '&biblionumber=[% biblionumber | uri %]'; >+ url += '&biblionumber=' + biblionumber; > > window.location.replace(url); > } >@@ -2363,8 +2402,11 @@ > $('#modal-item-group-unset').modal('hide'); > }); > >- [% END # /IF EnableItemGroups %] >+ }); >+ </script> >+ [% END # /IF EnableItemGroups %] > >+ <script> > $(".delete-comment").on("click", function(){ > return confirm( _("Are you sure you want to delete this comment?") ); > }); >-- >2.43.0 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 41566
:
191103
|
191104
| 191105 |
191106