From 51489ab0362444ddeb7379bfdf425bbc4ac57212 Mon Sep 17 00:00:00 2001
From: Jake Deery
Date: Mon, 1 Dec 2025 14:45:40 +0000
Subject: [PATCH] Bug 14962: On Display code for Intranet scripts & templates
This patch makes the necessary changes to the Intranet to make sure effective locations, collection codes, and branches are correctly displayed.
Please see the test files commit for instructions on how to test this bundle of patches.
Sponsored-by: ByWater Solutions
Signed-of-by: Martin Renvoize
---
admin/library_groups.pl | 4 +
basket/basket.pl | 19 +-
catalogue/itemsearch.pl | 7 +
catalogue/moredetail.pl | 39 +-
catalogue/search.pl | 1 +
cataloguing/additem.pl | 15 +
circ/overdue.pl | 65 +--
circ/pendingreserves.pl | 26 +-
circ/returns.pl | 2 +
circ/view_holdsqueue.pl | 28 +-
display/display-home.pl | 54 +++
.../prog/css/src/staff-global.scss | 5 +
.../prog/en/includes/action-logs.inc | 10 +
.../prog/en/includes/cat-toolbar.inc | 70 +++
.../catalogue/itemsearch_item.csv.inc | 2 +-
.../catalogue/itemsearch_item.json.inc | 11 +-
.../prog/en/includes/display-search.inc | 35 ++
.../intranet-tmpl/prog/en/includes/header.inc | 3 +
.../tables/items/catalogue_detail.inc | 222 +++++++++-
.../prog/en/includes/permissions.inc | 24 +
.../prog/en/includes/waiting_holds.inc | 2 +-
.../prog/en/modules/admin/library_groups.tt | 24 +-
.../admin/preferences/circulation.pref | 7 +
.../en/modules/admin/preferences/logs.pref | 6 +
.../prog/en/modules/basket/basket.tt | 4 +-
.../prog/en/modules/catalogue/detail.tt | 413 ++++++++++++++++++
.../prog/en/modules/catalogue/moredetail.tt | 17 +-
.../prog/en/modules/catalogue/results.tt | 10 +
.../prog/en/modules/cataloguing/additem.tt | 267 ++++++-----
.../prog/en/modules/circ/article-requests.tt | 12 +-
.../prog/en/modules/circ/branchtransfers.tt | 2 +-
.../prog/en/modules/circ/on-site_checkouts.tt | 2 +-
.../prog/en/modules/circ/overdue.tt | 2 +-
.../prog/en/modules/circ/pendingbookings.tt | 10 +-
.../prog/en/modules/circ/pendingreserves.tt | 22 +-
.../prog/en/modules/circ/returns.tt | 9 +-
.../prog/en/modules/circ/view_holdsqueue.tt | 34 +-
.../prog/en/modules/display/display-home.tt | 36 ++
.../prog/en/modules/intranet-main.tt | 6 +
.../en/modules/recalls/recalls_to_pull.tt | 4 +-
.../prog/en/modules/reports/itemslost.tt | 2 +-
.../prog/en/modules/tags/list.tt | 2 +-
.../prog/en/modules/tools/viewlog.tt | 2 +-
.../prog/en/modules/virtualshelves/shelves.tt | 4 +-
.../prog/js/fetch/display-api-client.js | 6 +-
.../prog/js/fetch/item-api-client.js | 11 +-
.../Display/DisplaysBatchAddItems.vue | 47 +-
.../Display/DisplaysBatchRemoveItems.vue | 38 +-
.../components/Display/DisplaysResource.vue | 174 ++++----
.../prog/js/vue/components/Display/Main.vue | 26 +-
.../prog/js/vue/fetch/api-client.js | 4 +-
.../prog/js/vue/routes/display.js | 8 +-
recalls/recalls_to_pull.pl | 2 +-
reserve/request.pl | 5 +
54 files changed, 1492 insertions(+), 370 deletions(-)
create mode 100755 display/display-home.pl
create mode 100644 koha-tmpl/intranet-tmpl/prog/en/includes/display-search.inc
create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/display/display-home.tt
diff --git a/admin/library_groups.pl b/admin/library_groups.pl
index 5cf759928d9..0f5c50f6255 100755
--- a/admin/library_groups.pl
+++ b/admin/library_groups.pl
@@ -52,6 +52,7 @@ if ( $op eq 'cud-add' ) {
my $ft_search_groups_staff = $cgi->param('ft_search_groups_staff') || 0;
my $ft_local_hold_group = $cgi->param('ft_local_hold_group') || 0;
my $ft_local_float_group = $cgi->param('ft_local_float_group') || 0;
+ my $ft_display_group = $cgi->param('ft_display_group') || 0;
if ( !$branchcode && Koha::Library::Groups->search( { title => $title } )->count() ) {
$template->param( error_duplicate_title => $title );
@@ -68,6 +69,7 @@ if ( $op eq 'cud-add' ) {
ft_local_hold_group => $ft_local_hold_group,
ft_limit_item_editing => $ft_limit_item_editing,
ft_local_float_group => $ft_local_float_group,
+ ft_display_group => $ft_display_group,
branchcode => $branchcode,
}
)->store();
@@ -88,6 +90,7 @@ if ( $op eq 'cud-add' ) {
my $ft_search_groups_staff = $cgi->param('ft_search_groups_staff') || 0;
my $ft_local_hold_group = $cgi->param('ft_local_hold_group') || 0;
my $ft_local_float_group = $cgi->param('ft_local_float_group') || 0;
+ my $ft_display_group = $cgi->param('ft_display_group') || 0;
if ($id) {
my $group = Koha::Library::Groups->find($id);
@@ -102,6 +105,7 @@ if ( $op eq 'cud-add' ) {
ft_search_groups_staff => $ft_search_groups_staff,
ft_local_hold_group => $ft_local_hold_group,
ft_local_float_group => $ft_local_float_group,
+ ft_display_group => $ft_display_group,
}
)->store();
diff --git a/basket/basket.pl b/basket/basket.pl
index 49d98371f4c..1ff5c4d7937 100755
--- a/basket/basket.pl
+++ b/basket/basket.pl
@@ -17,6 +17,7 @@
use Modern::Perl;
use CGI qw ( -utf8 );
+use C4::Context;
use C4::Koha;
use C4::Biblio qw(
GetMarcSeries
@@ -29,6 +30,7 @@ use C4::Output qw( output_html_with_http_headers );
use Koha::AuthorisedValues;
use Koha::Biblios;
use Koha::CsvProfiles;
+use Koha::Items;
my $query = CGI->new;
@@ -87,7 +89,15 @@ foreach my $biblionumber (@bibs) {
$num++;
$dat->{biblionumber} = $biblionumber;
- $dat->{ITEM_RESULTS} = $biblio->items->search_ordered;
+ my $items = $biblio->items->search_ordered;
+
+ # Add effective_location for display module support
+ if ( C4::Context->preference('UseDisplayModule') ) {
+ foreach my $item ( $items->as_list ) {
+ $item->{effective_location} = $item->effective_location;
+ }
+ }
+ $dat->{ITEM_RESULTS} = $items;
$dat->{MARCNOTES} = $marcnotesarray;
$dat->{MARCSUBJCTS} = $marcsubjctsarray;
$dat->{MARCAUTHORS} = $marcauthorsarray;
@@ -107,9 +117,10 @@ my $resultsarray = \@results;
# my $itemsarray=\@items;
$template->param(
- BIBLIO_RESULTS => $resultsarray,
- csv_profiles => Koha::CsvProfiles->search( { type => 'marc', used_for => 'export_records' } ),
- bib_list => $bib_list,
+ BIBLIO_RESULTS => $resultsarray,
+ csv_profiles => Koha::CsvProfiles->search( { type => 'marc', used_for => 'export_records' } ),
+ bib_list => $bib_list,
+ UseDisplayModule => C4::Context->preference('UseDisplayModule'),
);
output_html_with_http_headers $query, $cookie, $template->output;
diff --git a/catalogue/itemsearch.pl b/catalogue/itemsearch.pl
index ae8dd8241d6..6ac30c47d71 100755
--- a/catalogue/itemsearch.pl
+++ b/catalogue/itemsearch.pl
@@ -30,6 +30,7 @@ use C4::Koha qw( GetAuthorisedValues );
use Koha::AuthorisedValues;
use Koha::Biblios;
use Koha::Item::Search::Field qw(GetItemSearchFields);
+use Koha::Items;
use Koha::ItemTypes;
use Koha::Libraries;
@@ -292,6 +293,12 @@ if ( defined $format and $format ne 'shareable' ) {
$item->{biblioitem} = $biblio->biblioitem->unblessed;
my $checkout = Koha::Checkouts->find( { itemnumber => $item->{itemnumber} } );
$item->{checkout} = $checkout;
+
+ # Add effective_location for display module support
+ if ( C4::Context->preference('UseDisplayModule') ) {
+ my $item_obj = Koha::Items->find( $item->{itemnumber} );
+ $item->{effective_location} = $item_obj ? $item_obj->effective_location : $item->{location};
+ }
}
}
diff --git a/catalogue/moredetail.pl b/catalogue/moredetail.pl
index cdd6c09be08..3806f6c0d30 100755
--- a/catalogue/moredetail.pl
+++ b/catalogue/moredetail.pl
@@ -158,10 +158,10 @@ foreach my $item (@items) {
my $item_info = $item->unblessed;
$item_info->{object} = $item;
- $item_info->{itype} = $itemtypes->{ $item->itype }->{'translated_description'}
- if exists $itemtypes->{ $item->itype };
- $item_info->{effective_itemtype} = $itemtypes->{ $item->effective_itemtype };
- $item_info->{'ccode'} = $ccodes->{ $item->ccode } if $ccodes && $item->ccode && exists $ccodes->{ $item->ccode };
+ $item_info->{itype} = $itemtypes->{ $item->effective_itemtype }->{'translated_description'}
+ if exists $itemtypes->{ $item->effective_itemtype };
+ $item_info->{'ccode'} = $ccodes->{ $item->effective_collection_code }
+ if $ccodes && $item->effective_collection_code && exists $ccodes->{ $item->effective_collection_code };
if ( defined $item->copynumber ) {
$item_info->{'displaycopy'} = 1;
if ( defined $copynumbers->{ $item_info->{'copynumber'} } ) {
@@ -256,6 +256,37 @@ foreach my $item (@items) {
$item_info->{nomod} = !$patron->can_edit_items_from( $item->homebranch );
+ if ( C4::Context->preference('UseDisplayModule') ) {
+ my @displays;
+ my @display_items = Koha::DisplayItems->search(
+ { itemnumber => $item->itemnumber },
+ {
+ order_by => { '-desc' => 'date_added' },
+ }
+ )->as_list;
+
+ foreach my $display_item (@display_items) {
+ push @displays, $display_item->display;
+ }
+
+ $item_info->{display_items} = \@display_items if @display_items;
+ $item_info->{displays} = \@displays if @displays;
+ }
+
+ if ( C4::Context->preference('UseDisplayModule') && $item->effective_homebranch ) {
+ my $effective_homebranch = $item->effective_homebranch;
+ my $effective_homebranch_id = $item->effective_homebranch->branchcode;
+
+ $item_info->{homebranch} = $effective_homebranch_id;
+ }
+
+ if ( C4::Context->preference('UseDisplayModule') && $item->effective_holdingbranch ) {
+ my $effective_holdingbranch = $item->effective_holdingbranch;
+ my $effective_holdingbranch_id = $item->effective_holdingbranch->branchcode;
+
+ $item_info->{holdingbranch} = $effective_holdingbranch_id;
+ }
+
push @item_data, $item_info;
}
diff --git a/catalogue/search.pl b/catalogue/search.pl
index 957a9f9dcfc..aa38fc5824a 100755
--- a/catalogue/search.pl
+++ b/catalogue/search.pl
@@ -708,6 +708,7 @@ if ($hits) {
sort_by => \@sort_by
}
);
+
$template->param( hits_to_paginate => $hits_to_paginate );
$template->param( SEARCH_RESULTS => \@newresults );
diff --git a/cataloguing/additem.pl b/cataloguing/additem.pl
index 5c3e2005124..784be908f7b 100755
--- a/cataloguing/additem.pl
+++ b/cataloguing/additem.pl
@@ -165,6 +165,11 @@ if ( $op eq 'edititem' || $op eq 'dupeitem' ) {
if ( !$item ) {
$template->param( biblio => $biblio, item_doesnt_exist => 1 );
output_and_exit( $input, $cookie, $template, 'unknown_item' );
+ } else {
+ my $ondisplay = $item->active_display ? 1 : undef;
+ my $nomod = $ondisplay;
+
+ $template->param( ondisplay => $ondisplay, nomod => $nomod );
}
}
@@ -698,6 +703,16 @@ my @items;
for my $item ( $biblio->items->as_list, $biblio->host_items->as_list ) {
my $i = $item->columns_to_str;
$i->{nomod} = 1 unless $patron->can_edit_items_from( $item->homebranch );
+
+ if ( C4::Context->preference('UseDisplayModule') ) {
+ if ( $item->active_display ) {
+ $i->{active_display_id} = $item->active_display->display_id;
+ $i->{active_display_name} = $item->active_display->display_name;
+ $i->{ondisplay} = 1;
+ $i->{nomod} = 1;
+ }
+ }
+
push @items, $i;
}
diff --git a/circ/overdue.pl b/circ/overdue.pl
index 2d58dd27ee4..9d91eb9ab45 100755
--- a/circ/overdue.pl
+++ b/circ/overdue.pl
@@ -28,6 +28,7 @@ use Koha::DateUtils qw( dt_from_string );
use Koha::Patron::Attribute::Types;
use DateTime;
use DateTime::Format::MySQL;
+use Koha::Items;
my $input = CGI->new;
my $showall = $input->param('showall');
@@ -349,36 +350,40 @@ if ($noreport) {
}
push @overduedata, {
- patron => Koha::Patrons->find( $data->{borrowernumber} ),
- duedate => $data->{date_due},
- borrowernumber => $data->{borrowernumber},
- cardnumber => $data->{cardnumber},
- borrowertitle => $data->{borrowertitle},
- surname => $data->{surname},
- firstname => $data->{firstname},
- streetnumber => $data->{streetnumber},
- streettype => $data->{streettype},
- address => $data->{address},
- address2 => $data->{address2},
- city => $data->{city},
- zipcode => $data->{zipcode},
- country => $data->{country},
- phone => $data->{phone},
- email => $data->{email},
- branchcode => $data->{branchcode},
- barcode => $data->{barcode},
- datelastborrowed => $data->{datelastborrowed},
- itemnum => $data->{itemnumber},
- issuedate => $data->{issuedate},
- biblionumber => $data->{biblionumber},
- title => $data->{title},
- subtitle => $data->{subtitle},
- part_number => $data->{part_number},
- part_name => $data->{part_name},
- author => $data->{author},
- homebranchcode => $data->{homebranch},
- holdingbranchcode => $data->{holdingbranch},
- location => $data->{location},
+ patron => Koha::Patrons->find( $data->{borrowernumber} ),
+ duedate => $data->{date_due},
+ borrowernumber => $data->{borrowernumber},
+ cardnumber => $data->{cardnumber},
+ borrowertitle => $data->{borrowertitle},
+ surname => $data->{surname},
+ firstname => $data->{firstname},
+ streetnumber => $data->{streetnumber},
+ streettype => $data->{streettype},
+ address => $data->{address},
+ address2 => $data->{address2},
+ city => $data->{city},
+ zipcode => $data->{zipcode},
+ country => $data->{country},
+ phone => $data->{phone},
+ email => $data->{email},
+ branchcode => $data->{branchcode},
+ barcode => $data->{barcode},
+ datelastborrowed => $data->{datelastborrowed},
+ itemnum => $data->{itemnumber},
+ issuedate => $data->{issuedate},
+ biblionumber => $data->{biblionumber},
+ title => $data->{title},
+ subtitle => $data->{subtitle},
+ part_number => $data->{part_number},
+ part_name => $data->{part_name},
+ author => $data->{author},
+ homebranchcode => $data->{homebranch},
+ holdingbranchcode => $data->{holdingbranch},
+ location => $data->{location},
+ effective_location => do {
+ my $item = Koha::Items->find( $data->{itemnumber} );
+ $item ? $item->effective_location : '';
+ },
itemcallnumber => $data->{itemcallnumber},
replacementprice => $data->{replacementprice},
itemnotes_nonpublic => $data->{itemnotes_nonpublic},
diff --git a/circ/pendingreserves.pl b/circ/pendingreserves.pl
index 140b7b0bd11..1457dec5a60 100755
--- a/circ/pendingreserves.pl
+++ b/circ/pendingreserves.pl
@@ -260,7 +260,7 @@ foreach my $bibnum (@biblionumbers) {
# get available item types for each biblio
my @res_itemtypes;
if ( C4::Context->preference('item-level_itypes') ) {
- @res_itemtypes = uniq map { defined $_->itype ? $_->itype : () } @$items;
+ @res_itemtypes = uniq map { defined $_->effective_itemtype ? $_->effective_itemtype : () } @$items;
} else {
@res_itemtypes = Koha::Biblioitems->search(
{ biblionumber => $bibnum, itemtype => { '!=', undef } },
@@ -270,19 +270,20 @@ foreach my $bibnum (@biblionumbers) {
}
)->get_column('itemtype');
}
+
$hold_info->{itemtypes} = \@res_itemtypes;
my $res_info = $all_holds->{$bibnum};
# get available values for each biblio
my $fields = {
- collections => 'ccode',
- locations => 'location',
+ collections => 'effective_collection_code',
+ locations => 'effective_location',
callnumbers => 'itemcallnumber',
enumchrons => 'enumchron',
copynumbers => 'copynumber',
barcodes => 'barcode',
- holdingbranches => 'holdingbranch'
+ holdingbranches => 'effective_holdingbranch_id'
};
while ( my ( $key, $field ) = each %$fields ) {
@@ -316,6 +317,23 @@ foreach my $bibnum (@biblionumbers) {
$hold_info->{hold} = $res_info;
$hold_info->{item_group} = $res_info->item_group;
+ if ( C4::Context->preference('UseDisplayModule') ) {
+ my @displays;
+ my @display_items = Koha::DisplayItems->search(
+ { itemnumber => $hold_info->{item}->itemnumber },
+ {
+ order_by => { '-desc' => 'date_added' },
+ }
+ )->as_list;
+
+ foreach my $display_item (@display_items) {
+ push @displays, $display_item->display;
+ }
+
+ $hold_info->{display_items} = \@display_items if @display_items;
+ $hold_info->{displays} = \@displays if @displays;
+ }
+
push @holds_info, $hold_info;
}
diff --git a/circ/returns.pl b/circ/returns.pl
index 97b23534900..24206f53a48 100755
--- a/circ/returns.pl
+++ b/circ/returns.pl
@@ -759,6 +759,8 @@ foreach my $code ( keys %$messages ) {
;
} elsif ( $code eq 'InBundle' ) {
$template->param( InBundle => $messages->{InBundle} );
+ } elsif ( $code eq 'RemovedFromDisplay' ) {
+ $template->param( RemovedFromDisplay => $messages->{RemovedFromDisplay} );
} elsif ( $code eq 'UpdateLastSeenError' ) {
$err{UpdateLastSeenError} = $messages->{UpdateLastSeenError};
} else {
diff --git a/circ/view_holdsqueue.pl b/circ/view_holdsqueue.pl
index 460c5d6ba90..ef2d6c9e09f 100755
--- a/circ/view_holdsqueue.pl
+++ b/circ/view_holdsqueue.pl
@@ -27,6 +27,7 @@ use C4::Auth qw( get_template_and_user );
use C4::Output qw( output_html_with_http_headers );
use C4::HoldsQueue qw( GetHoldsQueueItems );
use Koha::BiblioFrameworks;
+use Koha::Items;
use Koha::ItemTypes;
my $query = CGI->new;
@@ -59,13 +60,38 @@ if ($run_report) {
}
);
+ my @itemsloop;
+ foreach my $item ( $items->as_list ) {
+ my $itemsloo = $item->unblessed;
+ $itemsloo->{object} = $item;
+
+ if ( C4::Context->preference('UseDisplayModule') ) {
+ my @displays;
+ my @display_items = Koha::DisplayItems->search(
+ { itemnumber => $item->itemnumber },
+ {
+ order_by => { '-desc' => 'date_added' },
+ }
+ )->as_list;
+
+ foreach my $display_item (@display_items) {
+ push @displays, $display_item->display;
+ }
+
+ $itemsloo->{display_items} = \@display_items if @display_items;
+ $itemsloo->{displays} = \@displays if @displays;
+ }
+
+ push @itemsloop, $itemsloo;
+ }
+
$template->param(
branchlimit => $branchlimit,
itemtypeslimit => $itemtypeslimit,
ccodeslimit => $ccodeslimit,
locationslimit => $locationslimit,
total => $items->count,
- itemsloop => $items,
+ itemsloop => \@itemsloop,
run_report => $run_report,
);
}
diff --git a/display/display-home.pl b/display/display-home.pl
new file mode 100755
index 00000000000..798e7f5ec7c
--- /dev/null
+++ b/display/display-home.pl
@@ -0,0 +1,54 @@
+#!/usr/bin/perl
+
+# Copyright 2025-2026 Open Fifth Ltd
+#
+# This file is part of Koha.
+#
+# Koha is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# Koha is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Koha; if not, see .
+
+use Modern::Perl;
+
+use CGI qw ( -utf8 );
+use C4::Auth qw( get_template_and_user );
+use C4::Output qw( output_html_with_http_headers );
+
+use Koha::Database::Columns;
+
+my $query = CGI->new;
+my ( $template, $loggedinuser, $cookie, $userflags ) = get_template_and_user(
+ {
+ template_name => 'display/display-home.tt',
+ query => $query,
+ type => 'intranet',
+ flagsrequired => { displays => '*' },
+ }
+);
+
+my $columns = Koha::Database::Columns::columns;
+$template->param(
+ db_columns => {
+ map {
+ my $table = $_;
+ map { ( $table . '.' . $_ => $columns->{$table}->{$_} ) }
+ keys %{ $columns->{$table} }
+ } qw( biblio biblioitems items )
+ },
+ api_mappings => {
+ items => Koha::Item->to_api_mapping,
+ biblioitems => Koha::Biblioitem->to_api_mapping,
+ biblio => Koha::Biblio->to_api_mapping,
+ },
+);
+
+output_html_with_http_headers $query, $cookie, $template->output;
diff --git a/koha-tmpl/intranet-tmpl/prog/css/src/staff-global.scss b/koha-tmpl/intranet-tmpl/prog/css/src/staff-global.scss
index fc2cf1f12f2..327e053395a 100644
--- a/koha-tmpl/intranet-tmpl/prog/css/src/staff-global.scss
+++ b/koha-tmpl/intranet-tmpl/prog/css/src/staff-global.scss
@@ -2028,6 +2028,11 @@ i {
font-style: italic;
}
+// style for displays in catalogsearch
+.displays {
+ display: block;
+}
+
#closewindow {
margin-top: 2em;
text-align: center;
diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/action-logs.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/action-logs.inc
index 867173a69c7..cb2f44cbe3f 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/includes/action-logs.inc
+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/action-logs.inc
@@ -24,6 +24,8 @@
Circulation [% UNLESS Koha.Preference('IssueLog') %] [% END %]
[% CASE 'CLAIMS' %]
Claims [% UNLESS Koha.Preference('ClaimsLog') %] [% END %]
+ [% CASE 'DISPLAYS' %]
+ Displays [% UNLESS Koha.Preference('DisplayItemsLog') %] [% END %]
[% CASE 'FINES' %]
Fines [% UNLESS Koha.Preference('FinesLog') %] [% END %]
[% CASE 'SYSTEMPREFERENCE' %]
@@ -159,6 +161,14 @@
Modify cardnumber
[% CASE 'RESET 2FA' %]
Reset 2FA
+ [% CASE 'ENABLE' %]
+ Enable
+ [% CASE 'DISABLE' %]
+ Disable
+ [% CASE 'ADD_ITEM' %]
+ Add item
+ [% CASE 'REMOVE_ITEM' %]
+ Remove item
[% CASE %]
[% action | html %]
[% END %]
diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/cat-toolbar.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/cat-toolbar.inc
index 68b4c24e45c..18476132ae2 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/includes/cat-toolbar.inc
+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/cat-toolbar.inc
@@ -308,11 +308,81 @@
[% END %]
[% END %]
+ [% IF Koha.Preference('UseDisplayModule') && CAN_user_displays %]
+
+ Add to display
+
+
+ [% END %]
+
[% FOREACH p IN plugins %]
[% p.intranet_catalog_biblio_enhancements_toolbar_button | $raw %]
[% END %]
+
+[% IF Koha.Preference('UseDisplayModule') && CAN_user_displays %]
+
+[% END %]
+
diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/catalogue/itemsearch_item.csv.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/catalogue/itemsearch_item.csv.inc
index 9dd823445ee..be021dd5e30 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/includes/catalogue/itemsearch_item.csv.inc
+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/catalogue/itemsearch_item.csv.inc
@@ -8,4 +8,4 @@
[%- SET biblioitem = item.biblioitem -%]
[%- SET delimiter = Koha.CSVDelimiter() -%]
"[% biblio.title | replace('"', '""') | $raw %]
-[% IF ( Koha.Preference( 'marcflavour' ) == 'UNIMARC' && biblio.author ) %]by[% END %][% biblio.author | replace('"', '""') | $raw %]"[%- delimiter | $raw -%]"[% (biblioitem.publicationyear || biblio.copyrightdate) | replace('"', '""') | $raw %]"[%- delimiter | $raw -%]"[% biblioitem.publishercode | replace('"', '""') | $raw %]"[%- delimiter | $raw -%]"[% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.ccode', authorised_value => item.ccode ) | replace('"', '""') | $raw %]"[%- delimiter | $raw -%]"[% item.barcode | replace('"', '""') | $raw %]"[%- delimiter | $raw -%]"[% item.itemnumber | replace('"', '""') | $raw %]"[%- delimiter | $raw -%]"[% item.enumchron | replace('"', '""') | $raw %]"[%- delimiter | $raw -%]"[% item.itemcallnumber | replace('"', '""') | $raw %]"[%- delimiter | $raw -%]"[% Branches.GetName(item.homebranch) | replace('"', '""') | $raw %]"[%- delimiter | $raw -%]"[% Branches.GetName(item.holdingbranch) | replace('"', '""') | $raw %]"[%- delimiter | $raw -%]"[% AuthorisedValues.GetDescriptionByKohaField(frameworkcode => biblio.frameworkcode, kohafield => 'items.location', authorised_value => item.location) | replace('"', '""') | $raw %]"[%- delimiter | $raw -%]"[% ItemTypes.GetDescription(item.itype) | replace('"', '""') | $raw %]"[%- delimiter | $raw -%]"[% item.stocknumber | replace('"', '""') | $raw %]"[%- delimiter | $raw -%]"[% AuthorisedValues.GetDescriptionByKohaField(frameworkcode => biblio.frameworkcode, kohafield => 'items.notforloan', authorised_value => item.notforloan) | replace('"', '""') | $raw %]"[%- delimiter | $raw -%]"[% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.itemlost', authorised_value => item.itemlost ) || "" | replace('"', '""') | $raw %]"[%- delimiter | $raw -%]"[% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.withdrawn', authorised_value => item.withdrawn ) || "" | replace('"', '""') | $raw %]"[%- delimiter | $raw -%]"[% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.damaged', authorised_value => item.damaged ) || "" | replace('"', '""') | $raw %]"[%- delimiter | $raw -%]"[% item.dateaccessioned | $KohaDates | $raw %]"[%- delimiter | $raw -%]"[% (item.issues || 0) | $raw %]"[%- delimiter | $raw -%]"[% item.datelastborrowed | $KohaDates | $raw %]"[%- delimiter | $raw -%]"[% IF item.checkout %][% item.checkout.date_due | $KohaDates | $raw %][% END %]"
+[% IF ( Koha.Preference( 'marcflavour' ) == 'UNIMARC' && biblio.author ) %]by[% END %][% biblio.author | replace('"', '""') | $raw %]"[%- delimiter | $raw -%]"[% (biblioitem.publicationyear || biblio.copyrightdate) | replace('"', '""') | $raw %]"[%- delimiter | $raw -%]"[% biblioitem.publishercode | replace('"', '""') | $raw %]"[%- delimiter | $raw -%]"[% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.ccode', authorised_value => item.effective_collection_code ) | replace('"', '""') | $raw %]"[%- delimiter | $raw -%]"[% item.barcode | replace('"', '""') | $raw %]"[%- delimiter | $raw -%]"[% item.itemnumber | replace('"', '""') | $raw %]"[%- delimiter | $raw -%]"[% item.enumchron | replace('"', '""') | $raw %]"[%- delimiter | $raw -%]"[% item.itemcallnumber | replace('"', '""') | $raw %]"[%- delimiter | $raw -%]"[% Branches.GetName(item.effective_homebranch) | replace('"', '""') | $raw %]"[%- delimiter | $raw -%]"[% Branches.GetName(item.effective_holdingbranch) | replace('"', '""') | $raw %]"[%- delimiter | $raw -%]"[% AuthorisedValues.GetDescriptionByKohaField(frameworkcode => biblio.frameworkcode, kohafield => 'items.location', authorised_value => item.effective_location) | replace('"', '""') | $raw %]"[%- delimiter | $raw -%]"[% ItemTypes.GetDescription(item.effective_itemtype) | replace('"', '""') | $raw %]"[%- delimiter | $raw -%]"[% item.stocknumber | replace('"', '""') | $raw %]"[%- delimiter | $raw -%]"[% AuthorisedValues.GetDescriptionByKohaField(frameworkcode => biblio.frameworkcode, kohafield => 'items.notforloan', authorised_value => item.notforloan) | replace('"', '""') | $raw %]"[%- delimiter | $raw -%]"[% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.itemlost', authorised_value => item.itemlost ) || "" | replace('"', '""') | $raw %]"[%- delimiter | $raw -%]"[% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.withdrawn', authorised_value => item.withdrawn ) || "" | replace('"', '""') | $raw %]"[%- delimiter | $raw -%]"[% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.damaged', authorised_value => item.damaged ) || "" | replace('"', '""') | $raw %]"[%- delimiter | $raw -%]"[% item.dateaccessioned | $KohaDates | $raw %]"[%- delimiter | $raw -%]"[% (item.issues || 0) | $raw %]"[%- delimiter | $raw -%]"[% item.datelastborrowed | $KohaDates | $raw %]"[%- delimiter | $raw -%]"[% IF item.checkout %][% item.checkout.date_due | $KohaDates | $raw %][% END %]"
diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/catalogue/itemsearch_item.json.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/catalogue/itemsearch_item.json.inc
index 2367c59f1b2..ec69e8f0149 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/includes/catalogue/itemsearch_item.json.inc
+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/catalogue/itemsearch_item.json.inc
@@ -20,7 +20,16 @@
[% item.barcode | html | $To %]
[%~ END %]",
"[% item.itemnumber | html %]", "[% item.enumchron | html | $To %]", "[% item.itemcallnumber | html | $To %]", "[% Branches.GetName(item.homebranch) | html %]", "[% Branches.GetName(item.holdingbranch) | html %]",
-"[% AuthorisedValues.GetDescriptionByKohaField( frameworkcode => biblio.frameworkcode, kohafield => 'items.location', authorised_value => item.location) | html %]", "[% ItemTypes.GetDescription(item.itype) | html %]",
+[% IF Koha.Preference('UseDisplayModule') && item.effective_location %]
+ [% SET effective_loc = item.effective_location %]
+ [% IF effective_loc.match('^DISPLAY:') %]
+ "[% effective_loc | html %]", "[% ItemTypes.GetDescription(item.itype) | html %]",
+ [% ELSE %]
+ "[% AuthorisedValues.GetDescriptionByKohaField( frameworkcode => biblio.frameworkcode, kohafield => 'items.location', authorised_value => effective_loc) | html %]", "[% ItemTypes.GetDescription(item.itype) | html %]",
+ [% END %]
+[% ELSE %]
+ "[% AuthorisedValues.GetDescriptionByKohaField( frameworkcode => biblio.frameworkcode, kohafield => 'items.location', authorised_value => item.location) | html %]", "[% ItemTypes.GetDescription(item.itype) | html %]",
+[% END %]
"[% item.stocknumber | html | $To %]", "[% AuthorisedValues.GetDescriptionByKohaField( frameworkcode => biblio.frameworkcode, kohafield => 'items.notforloan', authorised_value => item.notforloan) | html %]",
"[% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.itemlost', authorised_value => item.itemlost ) || "" | html %]",
"[% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.withdrawn', authorised_value => item.withdrawn ) || "" | html %]",
diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/display-search.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/display-search.inc
new file mode 100644
index 00000000000..dfd9014b355
--- /dev/null
+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/display-search.inc
@@ -0,0 +1,35 @@
+[% USE raw %]
+[% USE Koha %]
+[% PROCESS 'html_helpers.inc' %]
+
+[% WRAPPER tabs id="header_search" %]
+ [% WRAPPER tab_panels %]
+ [% IF ( CAN_user_circulate_circulate_remaining_permissions ) %]
+ [% INCLUDE 'patron-search-box.inc' bs_tab_active= 1 %]
+ [% INCLUDE 'checkin-search-box.inc' %]
+ [% INCLUDE 'renew-search-box.inc' %]
+ [% END %]
+ [% IF ( CAN_user_catalogue ) %]
+ [% INCLUDE 'catalogue-search-box.inc' %]
+ [% END %]
+ [% END # /tab_panels %]
+ [% WRAPPER tabs_nav %]
+ [% IF ( CAN_user_circulate_circulate_remaining_permissions ) %]
+ [% WRAPPER tab_item tabname="circ_search" bt_active= 1 %]
+
Check out
+ [% END %]
+ [% WRAPPER tab_item tabname= "checkin_search" %]
+
Check in
+ [% END %]
+ [% WRAPPER tab_item tabname= "renew_search" %]
+
Renew
+ [% END %]
+ [% END %]
+ [% IF ( CAN_user_catalogue ) %]
+ [% WRAPPER tab_item tabname= "catalog_search" %]
+
Search catalog
+ [% END %]
+ [% END %]
+ [% END # /tabs_nav %]
+[% END # /WRAPPER tabs %]
+
diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/header.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/header.inc
index 5b00a098c0d..bfa6e3df5c9 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/includes/header.inc
+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/header.inc
@@ -70,6 +70,9 @@
[% IF Koha.Preference('PreservationModule') && CAN_user_preservation %]
Preservation
[% END %]
+ [% IF Koha.Preference('UseDisplayModule') && CAN_user_displays %]
+
Displays
+ [% END %]
[% IF ( CAN_user_reports ) %]
Reports
[% END %]
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 9a1a3eaf65c..53dd6d781cc 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
@@ -25,6 +25,7 @@
Call number
Serial enumeration / chronology
Status
+
Displays
Last seen
Checkouts
Renewals
@@ -175,7 +176,6 @@
$("input[name='itemnumber'][type='checkbox']", tab).prop('checked', false);
itemSelectionBuildActionLinks(tab_id);
});
-
});
let filters_shown = false;
@@ -256,7 +256,7 @@
[%# 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?";
- 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"];
+ let embed = ["+strings,_status,effective_home_library,effective_holding_library,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') %]
embed.push('cover_image_ids');
[% END %]
@@ -332,6 +332,21 @@
return $("#" + tab_id + "_status select").val();
};
+ [% IF Koha.Preference('UseDisplayModule') %]
+ const displaysFetch = $.ajax({
+ url: '/api/v1/displays',
+ async: false,
+ method: 'GET',
+ headers: { 'x-koha-embed': 'display_items' },
+ error: error => {
+ console.error(error);
+ },
+ });
+ const displays = displaysFetch.responseJSON || [];
+ [% ELSE %]
+ const displays = [];
+ [% END %]
+
var items_table = $("#" + tab_id + '_table').kohaTable({
ajax: { url: item_table_url },
order: [],
@@ -382,14 +397,30 @@
[% END %]
[% IF ( item_level_itypes ) %]
{
+ [% IF Koha.Preference('UseDisplayModule') %]
+ data: "me.effective_item_type_id", // FIXME Cannot filter by biblioitem.itemtype
+ searchable: false,
+ orderable: false,
+ [% ELSE %]
data: "me.item_type_id", // FIXME Cannot filter by biblioitem.itemtype
datatype: "coded_value:item_type",
dataFilter: "item_types",
className: "itype",
searchable: true,
orderable: true,
+ [% END %]
render: function (data, type, row, meta) {
let node = '';
+ [% IF Koha.Preference('UseDisplayModule') %]
+ let effective_item_type_description = row._strings.effective_item_type_id ? row._strings.effective_item_type_id.str : row.effective_item_type_id;
+ [% UNLESS noItemTypeImages %]
+ let image_location = item_type_image_locations[row.effective_item_type_id];
+ node += image_location
+ ? '
'.format(escape_str(image_location), escape_str(effective_item_type_description), escape_str(effective_item_type_description))
+ : '';
+ [% END %]
+ node += '
%s '.format(escape_str(effective_item_type_description));
+ [% ELSE %]
let item_type_description = row._strings.item_type_id ? row._strings.item_type_id.str : row.item_type_id;
[% UNLESS noItemTypeImages %]
let image_location = item_type_image_locations[row.item_type_id];
@@ -398,60 +429,132 @@
: '';
[% END %]
node += '
%s '.format(escape_str(item_type_description));
+ [% END %]
+
return node;
}
},
[% END %]
{
+ [% IF Koha.Preference('UseDisplayModule') %]
+ data: "me.effective_holding_library_id",
+ searchable: false,
+ orderable: false,
+ [% ELSE %]
data: "holding_library.name:me.holding_library_id",
datatype: "coded_value:library",
- dataFilter: "libraries",
- className: "location",
searchable: true,
orderable: true,
+ dataFilter: "libraries",
+ className: "location",
+ [% END %]
render: function (data, type, row, meta) {
- return escape_str(row._strings.holding_library_id ? row._strings.holding_library_id.str : row.holding_library_id);
+ let nodes = "";
+ let effective_holding_library_id_str = row._strings.effective_holding_library_id ? row._strings.effective_holding_library_id.str : row.effective_holding_library_id;
+ let holding_library_id_str = row._strings.holding_library_id ? row._strings.holding_library_id.str : row.holding_library_id;
+
+ [% IF Koha.Preference('UseDisplayModule') %]
+ if (holding_library_id_str != effective_holding_library_id_str) {
+ nodes += '
';
+ nodes += ' ';
+ nodes += ' ';
+ }
+ [% END %]
+
+ nodes += escape_str(effective_holding_library_id_str || '');
+
+ nodes = '
' + nodes + ' ';
+ return nodes;
}
},
{
+ [% IF Koha.Preference('UseDisplayModule') %]
+ data: "me.effective_home_library_id",
+ searchable: false,
+ orderable: false,
+ [% ELSE %]
data: "home_library.name:me.home_library_id",
datatype: "coded_value:library",
- dataFilter: "libraries",
- className: "homebranch",
searchable: true,
orderable: true,
+ dataFilter: "libraries",
+ className: "location",
+ [% END %]
render: function (data, type, row, meta) {
- return escape_str(row._strings.home_library_id ? row._strings.home_library_id.str : row.home_library_id);
+ let nodes = "";
+ let effective_home_library_id_str = row._strings.effective_home_library_id ? row._strings.effective_home_library_id.str : row.effective_home_library_id;
+ let home_library_id_str = row._strings.home_library_id ? row._strings.home_library_id.str : row.home_library_id;
+
+ [% IF Koha.Preference('UseDisplayModule') %]
+ if (home_library_id_str != effective_home_library_id_str) {
+ nodes += '
';
+ nodes += ' ';
+ nodes += ' ';
+ }
+ [% END %]
+
+ nodes += escape_str(effective_home_library_id_str || '');
+
+ nodes = '
' + nodes + ' ';
+ return nodes;
}
},
{
+ [% IF Koha.Preference('UseDisplayModule') %]
+ data: "me.effective_location",
+ searchable: false,
+ orderable: false,
+ [% ELSE %]
data: "me.location",
- datatype: "coded_value:location",
searchable: true,
orderable: true,
+ [% END %]
render: function (data, type, row, meta) {
- let nodes = '
';
- [%# 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 nodes = "";
+ let effective_loc_str = row._strings.effective_location ? row._strings.effective_location.str : row.effective_location;
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);
- nodes += '%s (%s)'.format(escape_str(permanent_loc_str), escape_str(loc_str));
- } else {
- nodes += escape_str(loc_str);
- }
- nodes += ' ';
+
+ [% IF Koha.Preference('UseDisplayModule') %]
+ if (loc_str != effective_loc_str) {
+ nodes += '
';
+ nodes += ' ';
+ nodes += ' ';
+ }
+ [% END %]
+
+ nodes += escape_str(effective_loc_str || '');
+
+ nodes = '
' + nodes + ' ';
return nodes;
}
},
{
+ [% IF Koha.Preference('UseDisplayModule') %]
+ data: "me.effective_collection_code",
+ searchable: false,
+ orderable: false,
+ [% ELSE %]
data: "me.collection_code",
- datatype: "coded_value:collection_code",
searchable: true,
orderable: true,
+ [% END %]
render: function (data, type, row, meta) {
- return escape_str(row._strings.collection_code ? row._strings.collection_code.str : row.collection_code);
+ let nodes = "";
+ let effective_ccode_str = row._strings.effective_collection_code ? row._strings.effective_collection_code.str : row.effective_collection_code;
+ let ccode_str = row._strings.collection_code ? row._strings.collection_code.str : row.collection_code;
+
+ [% IF Koha.Preference('UseDisplayModule') %]
+ if (ccode_str != effective_ccode_str) {
+ nodes += '
';
+ nodes += ' ';
+ nodes += ' ';
+ }
+ [% END %]
+
+ nodes += escape_str(effective_ccode_str || '');
+
+ nodes = '
' + nodes + ' ';
+ return nodes;
}
},
[% IF Koha.Preference('EnableItemGroups') %]
@@ -601,6 +704,7 @@
}
}
[% END %]
+
if ( status == 'available' ) {
nodes += '
%s '.format(_("Available"))
}
@@ -615,6 +719,28 @@
return nodes;
}
},
+ {
+ data: "me.displays",
+ searchable: false,
+ orderable: false,
+ render: function (data, type, row, meta) {
+ let nodes = "";
+
+ [% IF Koha.Preference('UseDisplayModule') && CAN_user_displays %]
+ displays.forEach(display => {
+ display.display_items.forEach(display_item => {
+ if (display_item.itemnumber === row.item_id)
+ nodes += '
%s '.format(display.display_id, display.display_name);
+ });
+ });
+
+ if (nodes != "")
+ nodes = '
';
+ [% END %]
+
+ return nodes;
+ }
+ },
{
data: "me.last_seen_date",
type: "date",
@@ -744,19 +870,55 @@
{
data: "me.public_notes",
className: "itemnotes",
+ [% IF Koha.Preference('UseDisplayModule') %]
+ searchable: false,
+ orderable: false,
+ [% ELSE %]
searchable: true,
orderable: true,
+ [% END %]
render: function (data, type, row, meta) {
- return row.public_notes ? escape_str(row.public_notes).replaceAll('\n', '
') : '';
+ let nodes = "";
+
+ nodes = row.public_notes ? escape_str(row.public_notes).replaceAll('\n', '
') : '';
+
+ [% IF Koha.Preference('UseDisplayModule') %]
+ displays.forEach(display => {
+ display.display_items.forEach(display_item => {
+ if ((display_item.itemnumber === row.item_id) && (display.public_note))
+ nodes += '
%s
'.format(display.public_note);
+ });
+ });
+ [% END %]
+
+ return nodes;
}
},
{
data: "me.internal_notes",
className: "nonpublicnote",
+ [% IF Koha.Preference('UseDisplayModule') %]
+ searchable: false,
+ orderable: false,
+ [% ELSE %]
searchable: true,
orderable: true,
+ [% END %]
render: function (data, type, row, meta) {
- return escape_str(row.internal_notes);
+ let nodes = "";
+
+ nodes = row.internal_notes ? escape_str(row.internal_notes) : '';
+
+ [% IF Koha.Preference('UseDisplayModule') %]
+ displays.forEach(display => {
+ display.display_items.forEach(display_item => {
+ if ((display_item.itemnumber === row.item_id) && (display.staff_note))
+ nodes += '
%s
'.format(display.staff_note);
+ });
+ });
+ [% END %]
+
+ return nodes;
}
},
[% IF Koha.Preference('EasyAnalyticalRecords') %]
@@ -920,6 +1082,18 @@
});
return items_table;
}
+
+ const handlePermanentLocation = ((element) => {
+ const header = $(element).attr('data-header');
+ const body = $(element).attr('data-body');
+
+ $('#permanant_location_modal_label').text(header);
+ $('#permanant_location_modal_body').html('
');
+ $('#permanant_location_modal').modal('show');
+
+ return false;
+ });
+
function safe_link(uri,link_text) {
let node = document.createElement('a');
let url_str = '#';
diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/permissions.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/permissions.inc
index 535d6da6914..b7e5103831c 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/includes/permissions.inc
+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/permissions.inc
@@ -51,6 +51,9 @@
[%- CASE 'coursereserves' -%]
Course reserves
([% name | html %])
+ [%- CASE 'displays' -%]
+
Display module
+
([% name | html %])
[%- CASE 'plugins' -%]
Koha plugins
([% name | html %])
@@ -520,6 +523,27 @@
[%- CASE 'manage_courses' -%]
Add, edit and delete courses
([% name | html %])
+ [%- CASE 'view_display' -%]
+
View displays
+
([% name | html %])
+ [%- CASE 'add_display' -%]
+
Add displays
+
([% name | html %])
+ [%- CASE 'edit_display' -%]
+
Edit displays
+
([% name | html %])
+ [%- CASE 'delete_display' -%]
+
Delete displays
+
([% name | html %])
+ [%- CASE 'add_items_to_display' -%]
+
Add items to displays
+
([% name | html %])
+ [%- CASE 'add_items_to_display_from_any_libraries' -%]
+
Add items to displays from any libraries
+
([% name | html %])
+ [%- CASE 'remove_items_from_display' -%]
+
Remove items from displays
+
([% name | html %])
[%- CASE 'configure' -%]
Configure plugins
([% name | html %])
diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/waiting_holds.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/waiting_holds.inc
index 2ba57981f4f..4df1eff7fbb 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/includes/waiting_holds.inc
+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/waiting_holds.inc
@@ -83,7 +83,7 @@
[% Branches.GetName( reserveloo.item.homebranch ) | html %]
[% Branches.GetName( reserveloo.item.holdingbranch ) | html %][% IF (reserveloo.desk_id ) %], [% reserveloo.desk.desk_name | html %][% END %]
-
[% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.location', authorised_value => reserveloo.item.location) | html %]
+
[% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.location', authorised_value => reserveloo.item.effective_location ) | html %]
[% reserveloo.item.itemcallnumber | html %]
[% reserveloo.item.copynumber | html %]
[% reserveloo.item.enumchron | html %]
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/library_groups.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/library_groups.tt
index 059b66b9b04..d935408a52d 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/library_groups.tt
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/library_groups.tt
@@ -152,6 +152,12 @@
Is local float group
+
+
+
+ Is display group
+
+
@@ -235,6 +241,12 @@
Is local float group
+
+
+
+ Is display group
+
+
@@ -331,7 +343,8 @@
var ft_search_groups_staff = $(this).data("groupFt_search_groups_staff");
var ft_local_hold_group = $(this).data("groupFt_local_hold_group");
var ft_local_float_group = $(this).data("groupFt_local_float_group");
- edit_group(id, parent_id, title, description, ft_hide_patron_info, ft_search_groups_opac, ft_search_groups_staff, ft_local_hold_group, ft_limit_item_editing, ft_local_float_group);
+ var ft_display_group = $(this).data("groupFt_display_group");
+ edit_group(id, parent_id, title, description, ft_hide_patron_info, ft_search_groups_opac, ft_search_groups_staff, ft_local_hold_group, ft_limit_item_editing, ft_local_float_group, ft_display_group);
});
$(".delete-group").on("click", function (e) {
@@ -368,6 +381,7 @@
$("#add-group-modal-ft_search_groups_staff").prop("checked", false);
$("#add-group-modal-ft_local_hold_group").prop("checked", false);
$("#add-group-modal-ft_local_float_group").prop("checked", false);
+ $("#add-group-modal-ft_display_group").prop("checked", false);
if (parent_id) {
$("#root-group-features-add").hide();
} else {
@@ -376,7 +390,7 @@
$("#add-group-modal").modal("show");
}
- function edit_group(id, parent_id, title, description, ft_hide_patron_info, ft_search_groups_opac, ft_search_groups_staff, ft_local_hold_group, ft_limit_item_editing, ft_local_float_group) {
+ function edit_group(id, parent_id, title, description, ft_hide_patron_info, ft_search_groups_opac, ft_search_groups_staff, ft_local_hold_group, ft_limit_item_editing, ft_local_float_group, ft_display_group) {
$("#edit-group-modal-id").val(id);
$("#edit-group-modal-title").val(title);
$("#edit-group-modal-description").val(description);
@@ -387,6 +401,7 @@
$("#edit-group-modal-ft_search_groups_staff").prop("checked", false);
$("#edit-group-modal-ft_local_hold_group").prop("checked", false);
$("#edit-group-modal-ft_local_float_group").prop("checked", false);
+ $("#edit-group-modal-ft_display_group").prop("checked", false);
$("#root-group-features-edit").hide();
} else {
$("#edit-group-modal-ft_hide_patron_info").prop("checked", ft_hide_patron_info ? true : false);
@@ -395,6 +410,7 @@
$("#edit-group-modal-ft_search_groups_staff").prop("checked", ft_search_groups_staff ? true : false);
$("#edit-group-modal-ft_local_hold_group").prop("checked", ft_local_hold_group ? true : false);
$("#edit-group-modal-ft_local_float_group").prop("checked", ft_local_float_group ? true : false);
+ $("#edit-group-modal-ft_display_group").prop("checked", ft_display_group ? true : false);
$("#root-group-features-edit").show();
}
@@ -455,6 +471,9 @@
[% IF group.ft_local_float_group %]
Is local float group
[% END %]
+ [% IF group.ft_display_group %]
+ Is display group
+ [% END %]
[% END %]
@@ -486,6 +505,7 @@
data-group-ft_local_hold_group="[% group.ft_local_hold_group | html %]"
data-group-ft_limit_item_editing="[% group.ft_limit_item_editing | html %]"
data-group-ft_local_float_group="[% group.ft_local_float_group | html %]"
+ data-group-ft_display_group="[% group.ft_display_group | html %]"
>
Edit
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref
index 29d80b0e20b..10d3e98a840 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref
@@ -1375,6 +1375,13 @@ Circulation:
1: Use
0: "Don't use"
- "course reserves."
+ Display module:
+ -
+ - pref: UseDisplayModule
+ choices:
+ 1: Use
+ 0: "Don't use"
+ - "the display module for managing item displays."
Batch checkout:
-
- pref: BatchCheckouts
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/logs.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/logs.pref
index 1861a0de4e6..c05dc2f8022 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/logs.pref
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/logs.pref
@@ -90,6 +90,12 @@ Logging:
1: Log
0: "Don't log"
- information from cron jobs.
+ -
+ - pref: DisplayItemsLog
+ choices:
+ 1: Log
+ 0: "Don't log"
+ - when displays are created, edited, deleted, or when items are added to or removed from displays.
-
- pref: ReportsLog
choices:
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/basket/basket.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/basket/basket.tt
index c8a76b2f961..7ec0e402302 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/basket/basket.tt
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/basket/basket.tt
@@ -243,7 +243,7 @@
[% FOREACH ITEM_RESULT IN BIBLIO_RESULT.ITEM_RESULTS %]
[% Branches.GetName(ITEM_RESULT.holdingbranch) | html %]
- [% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.location', authorised_value => ITEM_RESULT.location ) | html %]
+ [% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.location', authorised_value => ITEM_RESULT.effective_location ) | html %]
[% IF ( ITEM_RESULT.itemcallnumber ) %]
([% ITEM_RESULT.itemcallnumber | html %])
[% END %]
@@ -337,7 +337,7 @@
[% ITEM_RESULT.itemcallnumber | html %]
[% Branches.GetName(ITEM_RESULT.holdingbranch) | html %]
- [% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.location', authorised_value => ITEM_RESULT.location ) | html %]
+ [% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.location', authorised_value => ITEM_RESULT.effective_location ) | html %]
[% END %]
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 763cda06baf..2fd7eca2b20 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt
@@ -1046,6 +1046,27 @@
[% END %]
+
+
@@ -1188,6 +1209,27 @@
+
+
+
+
[% IF bundlesEnabled %]
@@ -2383,7 +2425,378 @@
});
specific_dt_errors = _("Have a look at the 'Audit' button in the toolbar");
+
+ [% IF Koha.Preference('UseDisplayModule') && CAN_user_displays %]
+ // Display functionality
+ let availableDisplays = [];
+ let displayItemsTable = null;
+ let selectedDisplayItems = [];
+
+ // Load displays on page load
+ $(document).ready(function() {
+ // Load available displays for dropdown
+ $.ajax({
+ url: '/api/v1/displays',
+ method: 'GET',
+ headers: { 'x-koha-embed': 'display_items' },
+ success: function(displays) {
+ availableDisplays = displays.filter(display => display.enabled);
+ updateDisplayDropdown();
+ updateDisplaySelect();
+ },
+ error: function() {
+ $('#display-dropdown').html('
Failed to load displays ');
+ }
+ });
+ });
+
+ function updateDisplayDropdown() {
+ const dropdown = $('#display-dropdown');
+ if (availableDisplays.length === 0) {
+ dropdown.html('
No active displays available ');
+ return;
+ }
+
+ let html = '';
+ availableDisplays.forEach(display => {
+ html += `
${display.display_name} `;
+ });
+ dropdown.html(html);
+ }
+
+ function updateDisplaySelect() {
+ // Update display select
+ const displaySelect = $('#display-select');
+ let selectHtml = '
Select a display ';
+ availableDisplays.forEach(display => {
+ selectHtml += `
${display.display_name} `;
+ });
+ displaySelect.html(selectHtml);
+ }
+
+ function initializeDisplayItemsTable() {
+ if (displayItemsTable && displayItemsTable.DataTable) {
+ displayItemsTable.DataTable().destroy();
+ displayItemsTable = null;
+ }
+
+ selectedDisplayItems = [];
+
+ // Use the same API endpoint and embed options as the main items table
+ let item_table_url = "/api/v1/biblios/[% biblionumber | uri %]/items?";
+ let embed = ["+strings,_status,effective_home_library,effective_holding_library,home_library,holding_library"];
+
+ displayItemsTable = $("#display-items-table").kohaTable({
+ ajax: { url: item_table_url },
+ embed: embed,
+ order: [[1, 'asc']], // Sort by barcode
+ autoWidth: false,
+ paging: false,
+ searching: true,
+ info: false,
+ columns: [
+ {
+ data: "me.item_id",
+ searchable: false,
+ orderable: false,
+ render: function (data, type, row, meta) {
+ return `
`;
+ }
+ },
+ {
+ data: "me.external_id",
+ searchable: true,
+ orderable: true,
+ render: function (data, type, row, meta) {
+ return escape_str(row.external_id || 'No barcode');
+ }
+ },
+ {
+ [% IF Koha.Preference('UseDisplayModule') %]
+ data: "me.effective_holding_library_id",
+ searchable: false,
+ orderable: false,
+ [% ELSE %]
+ data: "holding_library.name:me.holding_library_id",
+ datatype: "coded_value:library",
+ searchable: true,
+ orderable: true,
+ dataFilter: "libraries",
+ className: "location",
+ [% END %]
+ render: function (data, type, row, meta) {
+ let nodes = "";
+ let effective_holding_library_id_str = row._strings.effective_holding_library_id ? row._strings.effective_holding_library_id.str : row.effective_holding_library_id;
+ let holding_library_id_str = row._strings.holding_library_id ? row._strings.holding_library_id.str : row.holding_library_id;
+
+ nodes += escape_str(effective_holding_library_id_str || '');
+
+ [% IF Koha.Preference('UseDisplayModule') %]
+ if (holding_library_id_str != effective_holding_library_id_str) {
+ nodes += '
';
+ nodes += ' ';
+ nodes += ' ';
+ }
+ [% END %]
+
+ nodes = '
' + nodes + ' ';
+ return nodes;
+ }
+ },
+ {
+ [% IF Koha.Preference('UseDisplayModule') %]
+ data: "me.effective_home_library_id",
+ searchable: false,
+ orderable: false,
+ [% ELSE %]
+ data: "me.home_library_id",
+ searchable: true,
+ orderable: true,
+ [% END %]
+ render: function (data, type, row, meta) {
+ [% IF Koha.Preference('UseDisplayModule') %]
+ let effective_home_library_id_str = row._strings.effective_home_library_id ? row._strings.effective_home_library_id.str : row.effective_home_library_id;
+ return escape_str(effective_home_library_id_str || '');
+ [% ELSE %]
+ let home_library_id_str = row._strings.home_library_id ? row._strings.home_library_id.str : row.home_library_id;
+ return escape_str(home_library_id_str || '');
+ [% END %]
+ }
+ },
+ {
+ [% IF Koha.Preference('UseDisplayModule') %]
+ data: "me.effective_location",
+ searchable: false,
+ orderable: false,
+ [% ELSE %]
+ data: "me.location",
+ searchable: true,
+ orderable: true,
+ [% END %]
+ render: function (data, type, row, meta) {
+ [% IF Koha.Preference('UseDisplayModule') %]
+ let loc_str = row._strings.effective_location ? row._strings.effective_location.str : row.effective_location;
+ return escape_str(effective_loc_str || '');
+ [% ELSE %]
+ let loc_str = row._strings.location ? row._strings.location.str : row.location;
+ return escape_str(loc_str || '');
+ [% END %]
+ }
+ },
+ {
+ [% IF Koha.Preference('UseDisplayModule') %]
+ data: "me.effective_collection_code",
+ searchable: false,
+ orderable: false,
+ [% ELSE %]
+ data: "me.collection_code",
+ searchable: true,
+ orderable: true,
+ [% END %]
+ render: function (data, type, row, meta) {
+ [% IF Koha.Preference('UseDisplayModule') %]
+ let effective_ccode_str = row._strings.effective_collection_code ? row._strings.effective_collection_code.str : row.effective_collection_code;
+ return escape_str(effective_ccode_str || '');
+ [% ELSE %]
+ let ccode_str = row._strings.collection_code ? row._strings.collection_code.str : row.collection_code;
+ return escape_str(ccode_str || '');
+ [% END %]
+ }
+ },
+ {
+ data: "me.callnumber",
+ searchable: true,
+ orderable: true,
+ render: function (data, type, row, meta) {
+ return escape_str(row.callnumber || '');
+ }
+ },
+ {
+ data: "",
+ searchable: false,
+ orderable: false,
+ render: function (data, type, row, meta) {
+ let status = '';
+ if (row._status && row._status.length > 0) {
+ status = row._status.map(s => s.replace(/_/g, ' ')).join(', ');
+ } else {
+ status = 'Available';
+ }
+ return escape_str(status);
+ }
+ }
+ ],
+ [% IF Koha.Preference('UseDisplayModule') %]
+ rowCallback: function(row, data) {
+ // Hide items that are already on displays (effective_location starts with "DISPLAY:")
+ if (data.effective_location && data.effective_location.startsWith && data.effective_location.startsWith('DISPLAY:')) {
+ $(row).hide();
+ return;
+ }
+ $(row).show();
+ },
+ [% END %]
+ drawCallback: function(settings) {
+ // Handle individual checkbox changes
+ $('.display-item-checkbox').off('change').on('change', function() {
+ const itemId = parseInt($(this).val());
+ if ($(this).is(':checked')) {
+ if (!selectedDisplayItems.includes(itemId)) {
+ selectedDisplayItems.push(itemId);
+ }
+ } else {
+ selectedDisplayItems = selectedDisplayItems.filter(id => id !== itemId);
+ }
+ updateSelectAllState();
+ });
+
+ // Handle select all checkbox
+ $('#select-all-display-items').off('change').on('change', function() {
+ const isChecked = $(this).is(':checked');
+ $('.display-item-checkbox').prop('checked', isChecked);
+
+ if (isChecked) {
+ selectedDisplayItems = [];
+ $('.display-item-checkbox').each(function() {
+ selectedDisplayItems.push(parseInt($(this).val()));
+ });
+ } else {
+ selectedDisplayItems = [];
+ }
+ });
+ }
+ });
+ }
+
+ function updateSelectAllState() {
+ const totalCheckboxes = $('.display-item-checkbox').length;
+ const checkedCheckboxes = $('.display-item-checkbox:checked').length;
+
+ if (checkedCheckboxes === 0) {
+ $('#select-all-display-items').prop('indeterminate', false).prop('checked', false);
+ } else if (checkedCheckboxes === totalCheckboxes) {
+ $('#select-all-display-items').prop('indeterminate', false).prop('checked', true);
+ } else {
+ $('#select-all-display-items').prop('indeterminate', true);
+ }
+ }
+
+ function openDisplayModal(displayId = null) {
+ if (displayId) {
+ $('#display-select').val(displayId);
+ }
+ // Initialize the DataTable when the modal is opened
+ initializeDisplayItemsTable();
+ $('#addToDisplayModal').modal('show');
+ }
+
+ // Clear date button functionality
+ $('#clear-date').on('click', function() {
+ $('#date-remove').val('');
+ });
+
+ // Form submission
+ $('#addToDisplayForm').on('submit', function(e) {
+ e.preventDefault();
+
+ const displayId = $('#display-select').val();
+ const removeDate = $('#date-remove').val();
+
+ if (!displayId) {
+ alert('Please select a display');
+ return;
+ }
+
+ if (selectedDisplayItems.length === 0) {
+ alert('Please select at least one item');
+ return;
+ }
+
+ $('#add-to-display-btn').prop('disabled', true).text('Adding...');
+
+ // Add each item to the display
+ let promises = selectedDisplayItems.map(itemId => {
+ const data = {
+ display_id: parseInt(displayId),
+ itemnumber: parseInt(itemId),
+ biblionumber: [% biblionumber | html %],
+ date_added: new Date().toISOString().split('T')[0]
+ };
+ if (removeDate) {
+ data.date_remove = removeDate;
+ }
+
+ return $.ajax({
+ url: '/api/v1/display/items',
+ method: 'POST',
+ contentType: 'application/json',
+ data: JSON.stringify(data)
+ });
+ });
+
+ Promise.all(promises).then(() => {
+ alert(`Successfully added ${selectedDisplayItems.length} item(s) to display`);
+ $('#addToDisplayModal').modal('hide');
+ $('#addToDisplayForm')[0].reset();
+ selectedDisplayItems = [];
+
+ // Safely refresh modal table
+ try {
+ if (displayItemsTable && displayItemsTable.DataTable) {
+ displayItemsTable.DataTable().draw();
+ }
+ } catch (e) {
+ // Modal table refresh failed - not critical
+ }
+
+ // Safely refresh the main items table to show updated locations
+ try {
+ if (typeof build_items_table === 'function') {
+ $('.items_table').each(function() {
+ let table_id = $(this).attr('id').replace('_table', '');
+ build_items_table(table_id, false, { destroy: true });
+ });
+ }
+ } catch (e) {
+ // Main table refresh failed - reload page as fallback
+ window.location.reload();
+ }
+ }).catch((error) => {
+ console.error('Error adding items to display:', error);
+ alert('Failed to add some items to display. Please try again.');
+ }).finally(() => {
+ $('#add-to-display-btn').prop('disabled', false).text('Add to display');
+ });
+ });
+
+ // Clean up when modal is hidden
+ $('#addToDisplayModal').on('hidden.bs.modal', function() {
+ if (displayItemsTable && displayItemsTable.DataTable) {
+ displayItemsTable.DataTable().destroy();
+ displayItemsTable = null;
+ }
+ selectedDisplayItems = [];
+ $('#addToDisplayForm')[0].reset();
+ });
+ [% END %]
[% CoverImagePlugins | $raw %]
[% END # /jsinclude %]
+
+[% BLOCK cssinclude %]
+
+[% END %]
[% INCLUDE 'intranet-bottom.inc' %]
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/moredetail.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/moredetail.tt
index f9313d0dd20..6b52cf975bc 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/moredetail.tt
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/moredetail.tt
@@ -187,10 +187,23 @@
[% IF ( ITEM_DAT.displaycopy ) %]
Copy number: [% ITEM_DAT.copyvol | html %]
[% END %]
- [% IF ( ITEM_DAT.location ) %]
+ [% IF ( ITEM_DAT.effective_location ) %]
Shelving location:
- [% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.location', authorised_value => ITEM_DAT.location ) | html %]
+ [% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.location', authorised_value => ITEM_DAT.effective_location ) | html %]
+
+ [% END %]
+ [% IF ( ITEM_DAT.displays ) %]
+
+ [% IF ITEM_DAT.displays.size > 1 %]
+ In displays:
+ [% ELSE %]
+ In display:
+ [% END %]
+ [% FOR display IN ITEM_DAT.displays %]
+ [% display.display_name | html %]
+ [% UNLESS loop.last %],[% END %]
+ [% END %]
[% END %]
[% IF ( ITEM_DAT.replacementprice ) %]
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/results.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/results.tt
index 6ac67649634..f8a00a21080 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/results.tt
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/results.tt
@@ -860,6 +860,16 @@
[% END %]
[% items_loo.count | html %]
+ [% IF ( items_loo.displays ) %]
+
In display(s):
+
+
+ [% END %]
[% IF status_count == "onloancount" %]
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/additem.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/additem.tt
index 58c47c37ce3..266f7e52577 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/additem.tt
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/additem.tt
@@ -5,6 +5,7 @@
[% USE KohaDates %]
[% USE Price %]
[% USE Item %]
+[% USE AuthorisedValues %]
[% USE TablesSettings %]
[% PROCESS 'i18n.inc' %]
[% INCLUDE 'doc-head-open.inc' %]
@@ -86,6 +87,19 @@
go to the records holdings .
[% END %]
+ [% IF ( items ) %]
+ [% FOREACH item IN items %]
+ [% IF item.ondisplay %]
+
+
Item(s) on display: The following item is currently on display, and cannot be modified:
+
+
The permanent location for these item(s) is found below. To modify these details, edit the display, or remove the item from the display.
+
+ [% END %]
+ [% END %]
+ [% END %]
Items for [% biblio.title | html %] [% IF ( biblio.author ) %]by [% biblio.author | html %][% END %] (Record #[% biblio.biblionumber | html %])
Jump to form
@@ -104,7 +118,7 @@
[% IF item_not_found %]
Cannot delete : Item not found.
[% END %]
- [% IF items %]
+ [% IF ( items ) %]
[% SET date_fields = [ 'dateaccessioned', 'onloan', 'datelastseen', 'datelastborrowed', 'replacementpricedate' ] %]
@@ -118,7 +132,7 @@
[% FOREACH item IN items %]
- [% SET can_be_edited = ! ( Koha.Preference('IndependentBranches') && ! logged_in_user.is_superlibrarian && item.homebranch != Branches.GetLoggedInBranchname() ) %]
+ [% SET can_be_edited = ! ( ( Koha.Preference('IndependentBranches') && ! logged_in_user.is_superlibrarian && item.homebranch != Branches.GetLoggedInBranchname() ) || ( item.nomod ) ) %]
[% SET tr_class = [] %]
[% SET tr_title = "" %]
[% IF item.itemnumber == itemnumber %]
@@ -135,7 +149,18 @@
[% END %]
[% UNLESS can_be_edited %]
-
+ [% IF ( item.ondisplay ) %]
+
+ Item on display:
+
+
+ [% ELSE %]
+
+ [% END %]
[% ELSE %]
@@ -218,6 +243,8 @@
[% item.$attribute | $Price %]
[% ELSIF item.$attribute && attribute == 'itemcallnumber' %]
[% item.$attribute | html %]
+ [% ELSIF attribute == 'location' %]
+ [% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.location', authorised_value => item.location ) | html %]
[% ELSE %]
[% item.$attribute | html %]
[% END %]
@@ -295,128 +322,138 @@
[% END %]
- [% PROCESS subfields_for_item subfields => subfields %]
- [% IF op != 'cud-additem' %]
-
- [% END %]
+ [% UNLESS ( nomod ) %]
+ [% PROCESS subfields_for_item subfields => subfields %]
+ [% IF op != 'cud-additem' %]
+
+ [% END %]
- [% IF item_groups.size && op != 'cud-saveitem' && CAN_user_editcatalogue_manage_item_groups %]
-
- Add to item group
- [% FOREACH ig IN item_groups %]
-
- [% END %]
-
-
- Options:
-
-
- [% FOREACH ig IN biblio.item_groups.search({}, {order_by => 'display_order'}) %]
- [% ig.description | html %]
- [% END %]
-
-
- Do not add to item group
- Create new item group
-
-
-
-
-
-
- [% END %]
-
-
- [% IF op != 'cud-saveitem' %]
-
-
-
-
-
-
-
-
-
-
- Number of copies of this item to add:
-
-
- Cancel
- Maximum currently set to 1000. The barcode you enter will be incremented for each additional item.
+
+
+ [% END %]
-
-
-
-
- Save template
-
-
- Save as new template
-
- [% FOREACH t IN item_templates.owned %]
- [% t.name | html %][% IF t.is_shared %](shared)[% END %]
- [% END %]
- [% IF CAN_user_editcatalogue_manage_item_editor_templates && item_templates.shared.count %]
-
- [% FOREACH t IN item_templates.shared %]
- [% t.name | html %][% IF t.is_shared %](shared)[% END %]
- [% END %]
-
- [% END %]
-
-
-
+
+ [% IF op != 'cud-saveitem' %]
+
+
+
+
+
+
+
+
+
+
+ Number of copies of this item to add:
+
+
+ Cancel
+ Maximum currently set to 1000. The barcode you enter will be incremented for each additional item.
+
-
-
- Template name:
-
- Required
-
-
+
+
+
+
+ Save template
+
+
+ Save as new template
+
+ [% FOREACH t IN item_templates.owned %]
+ [% t.name | html %][% IF t.is_shared %](shared)[% END %]
+ [% END %]
+ [% IF CAN_user_editcatalogue_manage_item_editor_templates && item_templates.shared.count %]
+
+ [% FOREACH t IN item_templates.shared %]
+ [% t.name | html %][% IF t.is_shared %](shared)[% END %]
+ [% END %]
+
+ [% END %]
+
+
+
-
-
-
- Share template
-
-
+
+
+ Template name:
+
+ Required
+
+
-
-
- [% ELSE %]
- [% IF op != 'add_item' %]
-
- [% END %]
- [% IF Item.HasSerialItem(itemnumber) == 0 %]
-
+
+
+
+ Share template
+
+
+
+
+
[% ELSE %]
-
-
+ [% IF op != 'add_item' %]
+
+ [% END %]
+ [% IF Item.HasSerialItem(itemnumber) == 0 %]
+
+ [% ELSE %]
+
+
+ [% END %]
+
+ Cancel
[% END %]
-
- Cancel
- [% END %]
+
+ [% ELSE %]
+ This item is not presently editable. Please check the alert dialog above for details.
+ [% END %]
[%# Fields for fast cataloging %]
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/article-requests.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/article-requests.tt
index cfb47daa5c4..6c5e89c3427 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/article-requests.tt
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/article-requests.tt
@@ -273,8 +273,8 @@
[% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.ccode', authorised_value => ar.item.ccode ) | html %]
[% ItemTypes.GetDescription( ar.item.effective_itemtype ) | html %]
- [% IF ar.item.location %]
- [% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.location', authorised_value => ar.item.location ) | html %]
+ [% IF ar.item.effective_location %]
+ [% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.location', authorised_value => ar.item.effective_location ) | html %]
[% END %]
[% ar.item.itemcallnumber | html %]
@@ -380,8 +380,8 @@
[% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.ccode', authorised_value => ar.item.ccode ) | html %]
[% ItemTypes.GetDescription( ar.item.effective_itemtype ) | html %]
- [% IF ar.item.location %]
- [% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.location', authorised_value => ar.item.location ) | html %]
+ [% IF ar.item.effective_location %]
+ [% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.location', authorised_value => ar.item.effective_location ) | html %]
[% END %]
[% ar.item.itemcallnumber | html %]
@@ -484,8 +484,8 @@
[% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.ccode', authorised_value => ar.item.ccode ) | html %]
[% ItemTypes.GetDescription( ar.item.effective_itemtype ) | html %]
- [% IF ar.item.location %]
- [% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.location', authorised_value => ar.item.location ) | html %]
+ [% IF ar.item.effective_location %]
+ [% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.location', authorised_value => ar.item.effective_location ) | html %]
[% END %]
[% ar.item.itemcallnumber | html %]
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/branchtransfers.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/branchtransfers.tt
index c03e8ee439c..63ac4df702a 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/branchtransfers.tt
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/branchtransfers.tt
@@ -274,7 +274,7 @@
>[% trsfitemloo.item.barcode | html %]
- [% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.location', authorised_value => trsfitemloo.item.location ) | html %]
+ [% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.location', authorised_value => trsfitemloo.item.effective_location ) | html %]
[% trsfitemloo.item.itemcallnumber | html %]
[% ItemTypes.GetDescription( trsfitemloo.item.effective_itemtype ) | html %]
[% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.ccode', authorised_value => trsfitemloo.item.ccode ) | html %]
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/on-site_checkouts.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/on-site_checkouts.tt
index bb315fd622f..14b5b7fe7c7 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/on-site_checkouts.tt
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/on-site_checkouts.tt
@@ -63,7 +63,7 @@
[% item.barcode | html %]
[% Branches.GetName(item.branchcode) | html %]
- [% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.location', authorised_value => item.location ) | html %]
+ [% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.location', authorised_value => (item.effective_location || item.location) ) | html %]
[% END %]
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/overdue.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/overdue.tt
index 1bc2b58b50d..1f62dcc3163 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/overdue.tt
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/overdue.tt
@@ -144,7 +144,7 @@
>
[% Branches.GetName( overdueloo.homebranchcode ) | html %]
[% Branches.GetName( overdueloo.holdingbranchcode ) | html %]
- [% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.location', authorised_value => overdueloo.location ) | html %]
+ [% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.location', authorised_value => overdueloo.effective_location ) | html %]
[% overdueloo.datelastborrowed | $KohaDates %]
Available item types
Available locations
Available collections
+ Displays
Earliest hold date
Hold notes
Pickup location
@@ -196,6 +197,15 @@
[% END %]
+
+ [% IF ( hold_info.displays.size ) %]
+
+ [% END %]
+
[% hold.reservedate | $KohaDates %] in [% Branches.GetName ( hold.branchcode ) | html %]
[% hold.reservenotes | html %]
[% Branches.GetName ( hold.branchcode ) | html %]
@@ -322,8 +332,17 @@
pickup_locations : (table_dt) => get_options(table_dt.column(15)),
};
-
var table_settings = [% TablesSettings.GetTableSettings('circ', 'holds', 'holds-to-pull', 'json') | $raw %];
+
+ [% UNLESS Koha.Preference('UseDisplayModule') %]
+ table_settings.columns = table_settings.columns.map((element, idx) => {
+ if(element.columnname == "displays")
+ element.is_hidden = 1;
+
+ return element;
+ });
+ [% END %]
+
var holdst = $("#holdst").kohaTable(
{
pagingType: "full_numbers",
@@ -341,6 +360,7 @@
{name: "itemtypes", dataFilter: "item_types" },
{name: "locations", dataFilter: "locations" },
{name: "collection" },
+ {name: "displays" },
{name: "hold_date" },
{name: "reserve_nodes" },
{name: "pickup_location", dataFilter: "pickup_locations" },
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/returns.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/returns.tt
index 872667c2825..69e9ad838cd 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/returns.tt
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/returns.tt
@@ -269,6 +269,13 @@
[% END %]
+ [% IF RemovedFromDisplay %]
+
+
Item removed from display
+
This item has been removed from the display: [% RemovedFromDisplay.display_name | html %]
+
+ [% END %]
+
[% IF ( errmsgloop ) %]
Check in message
@@ -1385,7 +1392,7 @@
[%- END -%]
- [% checkin.item_location | html %]
+ [% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.location', authorised_value => checkin.item.effective_location ) | html %]
[% checkin.item.itemcallnumber | html %]
[% checkin.item.dateaccessioned | $KohaDates %]
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/view_holdsqueue.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/view_holdsqueue.tt
index facdba84331..a9e40cc1c3d 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/view_holdsqueue.tt
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/view_holdsqueue.tt
@@ -113,6 +113,9 @@
Collection
Shelving location
Item type
+ [% IF Koha.Preference('UseDisplayModule') %]
+
Displays
+ [% END %]
Call number
Copy number
Enumeration
@@ -164,6 +167,13 @@
+ [% IF Koha.Preference('UseDisplayModule') %]
+
+
+
+
+
+ [% END %]
@@ -211,8 +221,11 @@
-
[% FOREACH itemsloo IN itemsloop %]
+
+ [% FOREACH itemsloo IN itemsloop %]
+ [% SET displays = itemsloo.displays %]
+ [% SET display_items = itemsloo.display_items %]
+ [% SET itemsloo = itemsloo.object %]
[% INCLUDE 'biblio-title.inc' biblio=itemsloo.biblio link = 1 %]
@@ -237,11 +250,20 @@
[% IF ( itemsloo.biblio.biblioitem.isbn ) %]ISBN: [% itemsloo.biblio.biblioitem.isbn | html %] [% END %]
- [% Branches.GetName( itemsloo.holdingbranch ) | html %]
- [% Branches.GetName( itemsloo.item.homebranch ) | html %]
- [% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.ccode', authorised_value => itemsloo.item.ccode ) | html %]
- [% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.location', authorised_value => itemsloo.item.location ) | html %]
+ [% itemsloo.item.effective_holdingbranch.branchname | html %]
+ [% itemsloo.item.effective_homebranch.branchname | html %]
+ [% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.ccode', authorised_value => itemsloo.item.effective_collection_code ) | html %]
+ [% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.location', authorised_value => itemsloo.item.effective_location ) | html %]
[% ItemTypes.GetDescription( itemsloo.item.effective_itemtype ) | html %]
+ [% IF Koha.Preference('UseDisplayModule') %]
+
+
+
+ [% END %]
[% itemsloo.item.itemcallnumber | html %]
[% itemsloo.item.copynumber | html %]
[% itemsloo.item.enumchron | html %]
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/display/display-home.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/display/display-home.tt
new file mode 100644
index 00000000000..1c5fe28c516
--- /dev/null
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/display/display-home.tt
@@ -0,0 +1,36 @@
+[% USE raw %]
+[% USE To %]
+[% USE Asset %]
+[% USE Koha %]
+[% USE KohaDates %]
+[% USE TablesSettings %]
+[% USE AuthorisedValues %]
+[% SET footerjs = 1 %]
+[% PROCESS 'i18n.inc' %]
+[% INCLUDE 'doc-head-open.inc' %]
+ Displays › Koha
+[% INCLUDE 'doc-head-close.inc' %]
+
+
+
+[% WRAPPER 'header.inc' %]
+ [% INCLUDE 'display-search.inc' %]
+[% END %]
+
+
+
+[% MACRO jsinclude BLOCK %]
+ [% INCLUDE 'calendar.inc' %]
+ [% INCLUDE 'datatables.inc' %]
+ [% INCLUDE 'js-date-format.inc' %]
+ [% INCLUDE 'js-biblio-format.inc' %]
+
+ [% Asset.js("js/vue/dist/display.js") | $raw %]
+[% END %]
+[% INCLUDE 'intranet-bottom.inc' %]
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/intranet-main.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/intranet-main.tt
index ef569c65ee6..ba32c13c9d4 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/intranet-main.tt
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/intranet-main.tt
@@ -167,6 +167,12 @@
[% END %]
+ [% IF Koha.Preference('UseDisplayModule') && CAN_user_displays %]
+
+ Displays
+
+ [% END %]
+
[% IF ( CAN_user_tools || CAN_user_clubs ) %]
Tools
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/recalls/recalls_to_pull.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/recalls/recalls_to_pull.tt
index dba569bc1df..35bb025bae0 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/recalls/recalls_to_pull.tt
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/recalls/recalls_to_pull.tt
@@ -111,8 +111,8 @@
- [% FOREACH loc IN recall.locations %]
- [% AuthorisedValues.GetByCode('LOC', loc) | html %]
+ [% FOREACH location IN recall.locations %]
+ [% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.location', authorised_value => location ) | html %]
[% END %]
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/reports/itemslost.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/reports/itemslost.tt
index 8f87e2161bf..b282f8665d2 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/reports/itemslost.tt
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/reports/itemslost.tt
@@ -126,7 +126,7 @@
[% ItemTypes.GetDescription(item.effective_itemtype) | html %]
[% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.ccode', authorised_value => item.ccode ) | html %]
[% Branches.GetName(item.holdingbranch) | html %]
- [% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.location', authorised_value => item.location ) | html %]
+ [% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.location', authorised_value => item.effective_location ) | html %]
[% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.notforloan', authorised_value => item.notforloan ) | html %] [% item.itemnotes | $raw %]
[% END %]
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tags/list.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tags/list.tt
index 60d1bc4e330..d69a50fb05e 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/tags/list.tt
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tags/list.tt
@@ -96,7 +96,7 @@
>[% FOREACH item IN title.items %]
[% Branches.GetName(item.holdingbranch) | html %]
- [% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.location', authorised_value => item.location ) | html %]
+ [% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.location', authorised_value => item.effective_location ) | html %]
[% IF ( item.itemcallnumber ) %]
([% item.itemcallnumber | html %])
[% END %]
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/viewlog.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/viewlog.tt
index 42634a034e8..10e354965a4 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/viewlog.tt
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/viewlog.tt
@@ -123,7 +123,7 @@
[% ELSE %]
All
[% END %]
- [% FOREACH modx IN [ 'APIKEYS' 'AUTH' 'CATALOGUING' 'AUTHORITIES' 'MEMBERS' 'ACQUISITIONS' 'SERIAL' 'HOLDS' 'ILL' 'CIRCULATION' 'CLAIMS' 'FINES' 'SYSTEMPREFERENCE' 'CRONJOBS', 'REPORTS', 'SEARCHENGINE', 'NOTICES', 'NEWS', 'RECALLS', 'SUGGESTION', 'TRANSFERS' ] %]
+ [% FOREACH modx IN [ 'APIKEYS' 'AUTH' 'CATALOGUING' 'AUTHORITIES' 'MEMBERS' 'ACQUISITIONS' 'SERIAL' 'HOLDS' 'ILL' 'CIRCULATION' 'CLAIMS' 'DISPLAYS' 'FINES' 'SYSTEMPREFERENCE' 'CRONJOBS', 'REPORTS', 'SEARCHENGINE', 'NOTICES', 'NEWS', 'RECALLS', 'SUGGESTION', 'TRANSFERS' ] %]
[% IF modules.grep(modx).size %]
[% PROCESS translate_log_module module=modx %]
[% Branches.GetName(item.holdingbranch) | html %]
- [% IF ( item.location ) %]
- [% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.location', authorised_value => item.location ) | html %]
+ [% IF ( item.effective_location ) %]
+ [% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.location', authorised_value => item.effective_location ) | html %]
[% END %]
[% IF ( item.itemcallnumber ) %]
[[% item.itemcallnumber | html %] ]
diff --git a/koha-tmpl/intranet-tmpl/prog/js/fetch/display-api-client.js b/koha-tmpl/intranet-tmpl/prog/js/fetch/display-api-client.js
index d5490a789c7..e41da83c56b 100644
--- a/koha-tmpl/intranet-tmpl/prog/js/fetch/display-api-client.js
+++ b/koha-tmpl/intranet-tmpl/prog/js/fetch/display-api-client.js
@@ -33,14 +33,16 @@ export class DisplayAPIClient {
this.httpClientDisplays.get({
endpoint: "" + id,
headers: {
- "x-koha-embed": "display_items,home_library,holding_library,item_type,+strings",
+ "x-koha-embed":
+ "display_items,home_library,holding_library,item_type,+strings",
},
}),
getAll: (query, params) =>
this.httpClientDisplays.getAll({
endpoint: "",
headers: {
- "x-koha-embed": "display_items,home_library,holding_library,+strings",
+ "x-koha-embed":
+ "display_items,home_library,holding_library,+strings",
},
params,
query,
diff --git a/koha-tmpl/intranet-tmpl/prog/js/fetch/item-api-client.js b/koha-tmpl/intranet-tmpl/prog/js/fetch/item-api-client.js
index f94ff01e8ce..2d87736dc0e 100644
--- a/koha-tmpl/intranet-tmpl/prog/js/fetch/item-api-client.js
+++ b/koha-tmpl/intranet-tmpl/prog/js/fetch/item-api-client.js
@@ -20,11 +20,12 @@ export class ItemAPIClient {
}),
getByExternalId: external_id =>
this.httpClient.get({
- endpoint: "items?" +
- new URLSearchParams({
- _match: 'starts_with',
- external_id: external_id,
- }),
+ endpoint:
+ "items?" +
+ new URLSearchParams({
+ _match: "starts_with",
+ external_id: external_id,
+ }),
}),
};
}
diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/Display/DisplaysBatchAddItems.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/Display/DisplaysBatchAddItems.vue
index a9b62f006fd..b6cf7000e11 100644
--- a/koha-tmpl/intranet-tmpl/prog/js/vue/components/Display/DisplaysBatchAddItems.vue
+++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/Display/DisplaysBatchAddItems.vue
@@ -3,10 +3,12 @@