From b8fef614de20ab9c15f71b3a75ac96e8b2fdaf39 Mon Sep 17 00:00:00 2001 From: Alex Arnaud Date: Fri, 8 Jul 2016 15:53:50 +0200 Subject: [PATCH] Bug 16881 - Apply KohaTable and ColVis plugin on MARCdetail's items table Also, the columns displayed are saved for each users in database. Test plan: - apply this BZ, - launch perl installer/data/mysql/updatedatabase.pl - launch perl misc/devel/update_dbix_class_files.pl - go to the items tab on cgi-bin/koha/catalogue/MARCdetail.pl page you should be able to hide/show each columns. - leave this page and come back with the same koha account: You should have the same columns shown/hidden as when you left. --- C4/Utils/DataTables/ColumnsSettings.pm | 21 ++++ C4/Utils/DataTables/DynamicColumnsSettings.pm | 49 ++++++++ Koha/Template/Plugin/ColumnsSettings.pm | 13 +++ catalogue/MARCdetail.pl | 5 +- .../add-table-users_columns_settings.sql | 11 ++ installer/data/mysql/kohastructure.sql | 16 +++ .../prog/en/includes/columns_settings.inc | 2 +- .../prog/en/modules/catalogue/MARCdetail.tt | 47 +++++++- svc/users_columns_settings | 51 ++++++++ t/db_dependent/ColumnsSettings.t | 129 ++++++++++++++++++++- 10 files changed, 337 insertions(+), 7 deletions(-) create mode 100644 C4/Utils/DataTables/DynamicColumnsSettings.pm create mode 100644 installer/data/mysql/atomicupdate/add-table-users_columns_settings.sql create mode 100755 svc/users_columns_settings diff --git a/C4/Utils/DataTables/ColumnsSettings.pm b/C4/Utils/DataTables/ColumnsSettings.pm index a107886..464d15a 100644 --- a/C4/Utils/DataTables/ColumnsSettings.pm +++ b/C4/Utils/DataTables/ColumnsSettings.pm @@ -100,4 +100,25 @@ sub update_columns { } } +sub update_user_columns { + my ($params) = @_; + my $columns = $params->{columns}; + + my $schema = Koha::Database->new->schema; + + foreach my $colname (keys %$columns) { + $schema->resultset('UsersColumnsSetting')->update_or_create( + { + borrowernumber => $params->{borrowernumber}, + module => $params->{module}, + page => $params->{page}, + tablename => $params->{tablename}, + additional_param => $params->{additional_param}, + columnname => $colname, + is_hidden => $columns->{$colname}, + } + ); + } +} + 1; diff --git a/C4/Utils/DataTables/DynamicColumnsSettings.pm b/C4/Utils/DataTables/DynamicColumnsSettings.pm new file mode 100644 index 0000000..a7d8628 --- /dev/null +++ b/C4/Utils/DataTables/DynamicColumnsSettings.pm @@ -0,0 +1,49 @@ +package C4::Utils::DataTables::DynamicColumnsSettings; + +use Modern::Perl; + +use C4::Biblio; +use Koha::Database; + +sub catalogue_marcdetail_itemst { + my ($frameworkcode) = @_; + + my $schema = Koha::Database->new->schema; + my $borrowernumber = C4::Context::userenv->{number}; + + my $columns; + my $tagslib = C4::Biblio::GetMarcStructure( 1, $frameworkcode ); + my ($itemfield) = C4::Biblio::GetMarcFromKohaField( 'items.itemnumber', $frameworkcode ); + foreach my $subfield ( keys %{ $tagslib->{$itemfield} } ) { + next unless $subfield =~ /^\w$/; + next if ( $tagslib->{$itemfield}->{$subfield}->{tab} ne 10 ); + next if ( $tagslib->{$itemfield}->{$subfield}->{hidden} =~ /-7|-4|-3|-2|2|3|5|8/ ); + + my $user_column; + if (my @rs = $schema->resultset('UsersColumnsSetting')->search( + { + borrowernumber => $borrowernumber, + module => 'catalogue', + page => 'marcdetail', + tablename => 'itemst', + additional_param => $frameworkcode, + columnname => $subfield + } + )) { + $user_column = $rs[0]; + } + + if ( $tagslib->{$itemfield}{$subfield}{hidden} eq "0" ) { + push @$columns, + { + columnname => $subfield, + is_hidden => $user_column ? $user_column->is_hidden : 0, + cannot_be_modified => 0, + cannot_be_toggled => 0 + }; + } + } + return $columns; +} + +1; \ No newline at end of file diff --git a/Koha/Template/Plugin/ColumnsSettings.pm b/Koha/Template/Plugin/ColumnsSettings.pm index 4617969..3ee2f9d 100644 --- a/Koha/Template/Plugin/ColumnsSettings.pm +++ b/Koha/Template/Plugin/ColumnsSettings.pm @@ -27,6 +27,7 @@ use JSON qw( to_json ); use C4::Context qw( config ); use C4::Utils::DataTables::ColumnsSettings; +use C4::Utils::DataTables::DynamicColumnsSettings; =pod @@ -52,4 +53,16 @@ sub GetColumns { : $columns } +sub GetDynamicColumns { + my ($self, $module, $page, $tablename, $param) = @_; + + my $sub = $module . '_' . $page . '_' . $tablename; + my $columns = []; + if (my $s = C4::Utils::DataTables::DynamicColumnsSettings->can($sub)) { + $columns = $s->($param); + } + + return to_json($columns); +} + 1; diff --git a/catalogue/MARCdetail.pl b/catalogue/MARCdetail.pl index ccf178e..f1f28c3 100755 --- a/catalogue/MARCdetail.pl +++ b/catalogue/MARCdetail.pl @@ -82,6 +82,9 @@ my ( $template, $loggedinuser, $cookie ) = get_template_and_user( debug => 1, } ); +$template->param( + frameworkcode => $frameworkcode +); my $record = GetMarcBiblio($biblionumber, 1); $template->param( ocoins => GetCOinSBiblio($record) ); @@ -288,7 +291,7 @@ my ($holdingbrtagf,$holdingbrtagsubf) = &GetMarcFromKohaField("items.holdingbran # fill item info my @item_header_loop; for my $subfield_code ( @item_subfield_codes ) { - push @item_header_loop, $witness{$subfield_code}; + push @item_header_loop, { colname => $subfield_code, label => $witness{$subfield_code} }; for my $item_data ( @item_loop ) { $item_data->{$subfield_code} ||= " " } diff --git a/installer/data/mysql/atomicupdate/add-table-users_columns_settings.sql b/installer/data/mysql/atomicupdate/add-table-users_columns_settings.sql new file mode 100644 index 0000000..571370e --- /dev/null +++ b/installer/data/mysql/atomicupdate/add-table-users_columns_settings.sql @@ -0,0 +1,11 @@ +CREATE TABLE IF NOT EXISTS users_columns_settings ( + borrowernumber int(11) NOT NULL, + module varchar(255) NOT NULL, + page varchar(255) NOT NULL, + tablename varchar(255) NOT NULL, + additional_param varchar(255) NOT NULL, + columnname varchar(255) NOT NULL, + is_hidden int(1) NOT NULL DEFAULT 0, + PRIMARY KEY(borrowernumber, module, page, tablename, columnname), + CONSTRAINT borrower_columns_settings_ibfk1 FOREIGN KEY (borrowernumber) REFERENCES borrowers (borrowernumber) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; \ No newline at end of file diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql index 4612a17..ee65814 100644 --- a/installer/data/mysql/kohastructure.sql +++ b/installer/data/mysql/kohastructure.sql @@ -3543,6 +3543,22 @@ CREATE TABLE IF NOT EXISTS columns_settings ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; -- +-- Table structure for table `users_columns_settings` +-- + +CREATE TABLE IF NOT EXISTS users_columns_settings ( + borrowernumber int(11) NOT NULL, + module varchar(255) NOT NULL, + page varchar(255) NOT NULL, + tablename varchar(255) NOT NULL, + additional_param varchar(255) NOT NULL, + columnname varchar(255) NOT NULL, + is_hidden int(1) NOT NULL DEFAULT 0, + PRIMARY KEY(borrowernumber, module, page, tablename, columnname), + CONSTRAINT borrower_columns_settings_ibfk1 FOREIGN KEY (borrowernumber) REFERENCES borrowers (borrowernumber) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; + +-- -- Table structure for table 'items_search_fields' -- diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/columns_settings.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/columns_settings.inc index b065a35..692a17a 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/columns_settings.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/columns_settings.inc @@ -6,7 +6,7 @@ function KohaTable(selector, dt_parameters, columns_settings) { var hidden_ids = []; var included_ids = []; $(columns_settings).each( function() { - var named_id = $( 'thead th[data-colname="' + this.columnname + '"]', selector ).index( 'th' ); + var named_id = $( 'thead th[data-colname="' + this.columnname + '"]', selector ).index(); var used_id = dt_parameters.bKohaColumnsUseNames ? named_id : id; if ( used_id == -1 ) return; diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/MARCdetail.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/MARCdetail.tt index 992bd0a..8532e71 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/MARCdetail.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/MARCdetail.tt @@ -1,3 +1,4 @@ +[% USE ColumnsSettings %] [% INCLUDE 'doc-head-open.inc' %] Koha › Catalog › [% IF ( unknownbiblionumber ) %] @@ -6,8 +7,11 @@ MARC details for [% bibliotitle %] [% END %] + [% INCLUDE 'doc-head-close.inc' %] [% INCLUDE 'browser-strings.inc' %] +[% INCLUDE 'datatables.inc' %] +[% INCLUDE 'columns_settings.inc' %] @@ -17,9 +21,40 @@ var browser = KOHA.browser('[% searchid %]', parseInt('[% biblionumber %]', 10)); browser.show(); - $(document).ready(function() { - $('#bibliotabs').tabs(); - }); +$(document).ready(function() { + $('#bibliotabs').tabs(); + + var columns_settings = [% ColumnsSettings.GetDynamicColumns( 'catalogue', 'marcdetail', 'itemst', frameworkcode ) %]; + var itemst = KohaTable("#tab10XX table", { + 'bPaginate': false, + 'bInfo': false, + "bAutoWidth": false, + "bKohaColumnsUseNames": true, + 'stateSave': true, + 'stateSaveCallback': function (settings, data) { + if (typeof settings['aoColumns'] !== 'undefined') { + var columns = {}; + $.each( settings['aoColumns'], function( index, value ){ + columns[value.colname] = value.bVisible ? '0' : '1'; + }); + $.ajax({ + url: "/cgi-bin/koha/svc/users_columns_settings", + data: { + columns: JSON.stringify(columns), + module: 'catalogue', + page: 'marcdetail', + tablename: 'itemst', + additional_param: '[% frameworkcode %]', + }, + type: "POST", + }); + } + }, + "aoColumnDefs": [ + { "bSortable": false, "bSearchable": false, "aTargets": [ "NoSort" ] } + ] + }, columns_settings); +}); function Changefwk(FwkList) { var fwk = FwkList.options[FwkList.selectedIndex].value; @@ -166,11 +201,14 @@ function Changefwk(FwkList) { [% IF ( tab10XX ) %]
+ [% FOREACH header IN item_header_loop %] - + [% END %] + + [% FOREACH item IN item_loop %] [% FOREACH sf_code IN item_subfield_codes %] @@ -178,6 +216,7 @@ function Changefwk(FwkList) { [% END %] [% END %] +
[% header %][% header.label %]
[% END %] diff --git a/svc/users_columns_settings b/svc/users_columns_settings new file mode 100755 index 0000000..8a8e736 --- /dev/null +++ b/svc/users_columns_settings @@ -0,0 +1,51 @@ +#!/usr/bin/perl + +# Copyright 2016 Biblibre +# +# 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, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +#use Modern::Perl; + +use CGI; +use C4::Auth qw(check_cookie_auth get_session); +use JSON qw(from_json); +use C4::Utils::DataTables::ColumnsSettings; + +my $input = new CGI; + +binmode STDOUT, ":encoding(UTF-8)"; +print $input->header( -type => 'text/plain', -charset => 'UTF-8' ); + +my ( $auth_status, $sessionID ) = + check_cookie_auth( $input->cookie('CGISESSID'), + { catalogue => '*' } ); + +if ( $auth_status ne "ok" ) { + exit 0; +} + +my $session = get_session($sessionID); + +my $params = { + columns => from_json($input->param('columns')), + module => $input->param('module'), + page => $input->param('page'), + tablename => $input->param('tablename'), + borrowernumber => $session->param('number'), + additional_param => $input->param('additional_param') +}; + +C4::Utils::DataTables::ColumnsSettings::update_user_columns($params); diff --git a/t/db_dependent/ColumnsSettings.t b/t/db_dependent/ColumnsSettings.t index da75931..b2650f3 100644 --- a/t/db_dependent/ColumnsSettings.t +++ b/t/db_dependent/ColumnsSettings.t @@ -1,11 +1,20 @@ #!/usr/bin/perl; use Modern::Perl; -use Test::More tests => 2; +use Test::More tests => 5; use Test::MockModule; +use t::lib::TestBuilder; use C4::Context; +use C4::Biblio; use C4::Utils::DataTables::ColumnsSettings; +use C4::Utils::DataTables::DynamicColumnsSettings; + +my $schema = Koha::Database->new()->schema(); +$schema->storage->txn_begin(); + +my $builder = t::lib::TestBuilder->new; + my $dbh = C4::Context->dbh; $dbh->{AutoCommit} = 0; $dbh->{RaiseError} = 1; @@ -56,6 +65,68 @@ $module->mock( } ); +my $borrower = $builder->build({ source => 'Borrower' }); +my $context = new Test::MockModule('C4::Context'); +$context->mock( + 'userenv', + sub { + return { + number => $borrower->{borrowernumber} + }; + } +); + +my $bibliomodule = new Test::MockModule('C4::Biblio'); +$bibliomodule->mock( + 'GetMarcStructure', + sub { + return { + 995 => { + 'q' => { + 'hidden' => '0', + 'authorised_value' => '', + 'defaultvalue' => '', + 'repeatable' => '0', + 'link' => '', + 'seealso' => undef, + 'tab' => '10', + 'mandatory' => '1', + 'lib' => 'Section', + 'maxlength' => '9999', + 'authtypecode' => '', + 'isurl' => '0', + 'kohafield' => '', + 'value_builder' => '' + }, + 'j' => { + 'hidden' => '0', + 'authorised_value' => '', + 'defaultvalue' => '', + 'repeatable' => '0', + 'link' => '', + 'seealso' => undef, + 'tab' => '10', + 'mandatory' => '1', + 'lib' => 'Provider', + 'maxlength' => '9999', + 'authtypecode' => '', + 'isurl' => '0', + 'kohafield' => '', + 'value_builder' => '' + }, + } + } + } +); + +$bibliomodule->mock( + 'GetMarcFromKohaField', + sub { + return '995'; + } +); + + C4::Utils::DataTables::ColumnsSettings::update_columns( { columns => [ @@ -181,4 +252,60 @@ for my $m ( keys %$modules ) { } } +C4::Utils::DataTables::ColumnsSettings::update_user_columns( + { + columns => { + q => 1, + j => 0 + }, + borrowernumber => $borrower->{borrowernumber}, + module => 'catalogue', + page => 'marcdetail', + tablename => 'itemst', + additional_param => 'BOOK' + } +); + +my @c = $schema->resultset('UsersColumnsSetting')->search( + { + borrowernumber => $borrower->{borrowernumber}, + module => 'catalogue', + page => 'marcdetail', + tablename => 'itemst', + columnname => 'q', + additional_param => 'BOOK' + } +); +is(1, $c[0]->is_hidden, 'Column q is hidden'); + +@c = $schema->resultset('UsersColumnsSetting')->search( + { + borrowernumber => $borrower->{borrowernumber}, + module => 'catalogue', + page => 'marcdetail', + tablename => 'itemst', + columnname => 'j', + additional_param => 'BOOK' + } +); +is(0, $c[0]->is_hidden, 'Column j is not hidden'); + +my $expected_columns = [ + { + columnname => 'q', + is_hidden => 1, + cannot_be_modified => 0, + cannot_be_toggled => 0 + }, + { + columnname => 'j', + is_hidden => 0, + cannot_be_modified => 0, + cannot_be_toggled => 0 + }, + +]; +my $columns = C4::Utils::DataTables::DynamicColumnsSettings::catalogue_marcdetail_itemst('BOOK'); +is_deeply( $columns, $expected_columns, 'catalogue_marcdetail_itemst should returns all columns' ); + $dbh->rollback; -- 2.7.0