From eef3345386ab7481d1959fc6a8e757f9458b77dd Mon Sep 17 00:00:00 2001 From: Kyle M Hall Date: Tue, 9 Jul 2013 12:30:58 -0400 Subject: [PATCH] Bug 10558 - Convert records table in manage-marc-import.pl to ajax DataTable Some libraries would like to sort by columns for the records of an import batch. This seems like a good use of ajax DataTables. Test plan: 1) Apply this patch 2) Import a record batch into Koha a) Use some form of matching b) Have some records that will match and some that won't c) Have at least 30 records so you can test the pager 3) Verify the new table is functionally equivilent to the old static one --- C4/ImportBatch.pm | 7 +- .../prog/en/modules/tools/manage-marc-import.tt | 136 +++++++++---------- tools/batch_records_ajax.pl | 112 ++++++++++++++++ tools/manage-marc-import.pl | 98 +++++++------- 4 files changed, 230 insertions(+), 123 deletions(-) create mode 100755 tools/batch_records_ajax.pl diff --git a/C4/ImportBatch.pm b/C4/ImportBatch.pm index 3ce5c67..7279b26 100644 --- a/C4/ImportBatch.pm +++ b/C4/ImportBatch.pm @@ -990,7 +990,10 @@ starting at the given offset. =cut sub GetImportRecordsRange { - my ($batch_id, $offset, $results_per_group, $status) = @_; + my ( $batch_id, $offset, $results_per_group, $status, $parameters ) = @_; + + my $order_by = $parameters->{order_by} || 'import_record_id'; + my $order_by_direction = $parameters->{order_by_direction} || 'ASC'; my $dbh = C4::Context->dbh; my $query = "SELECT title, author, isbn, issn, authorized_heading, import_records.import_record_id, @@ -1006,7 +1009,7 @@ sub GetImportRecordsRange { $query .= " AND status=?"; push(@params,$status); } - $query.=" ORDER BY import_record_id"; + $query.=" ORDER BY $order_by $order_by_direction"; if($results_per_group){ $query .= " LIMIT ?"; diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/manage-marc-import.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/manage-marc-import.tt index 5b0e3a2..ba1736d 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/manage-marc-import.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/manage-marc-import.tt @@ -1,22 +1,3 @@ -[% BLOCK final_match_link %] - [% IF ( record.record_type == 'biblio' ) %] - [% record.final_match_id %] - [% ELSIF ( record.record_type == 'auth' ) %] - [% record.final_match_id %] - [% END %] -[% END %] -[% BLOCK match_link %] - [% IF ( record_lis.match_id ) %] - - - [% IF ( record.record_type == 'biblio' ) %] - Matches biblio [% record_lis.match_id %] (score = [% record_lis.match_score %]): [% record_lis.match_citation %] - [% ELSIF ( record.record_type == 'auth' ) %] - Matches authority [% record_lis.match_id %] (score = [% record_lis.match_score %]): [% record_lis.match_citation %] - [% END %] - - [% END %] -[% END %] [% INCLUDE 'doc-head-open.inc' %] Koha › Tools › Manage staged MARC records [% IF ( import_batch_id ) %] @@ -26,6 +7,11 @@ [% INCLUDE 'greybox.inc' %] [% INCLUDE 'doc-head-close.inc' %] <script type="text/javascript" src="[% themelang %]/js/background-job-progressbar.js"></script> +<link rel="stylesheet" type="text/css" href="[% themelang %]/css/datatables.css" /> +<script type="text/javascript" src="[% themelang %]/lib/jquery/plugins/jquery.dataTables.min.js"></script> +<script type="text/javascript" src="[% themelang %]/lib/jquery/plugins/jquery.dataTables.columnFilter.js"></script> +[% INCLUDE 'datatables-strings.inc' %] +<script type="text/javascript" src="[% themelang %]/js/datatables.js"></script> <script type="text/JavaScript" language="JavaScript"> //<![CDATA[ var MSG_CONFIRM_CLEAN = _("Clear all reservoir records staged in this batch? This cannot be undone."); @@ -41,6 +27,54 @@ $(document).ready(function(){ $("#"+str+" option[selected='selected']").attr("selected","selected"); $(this).parent().hide(); }); + + $("#records-table").dataTable({ + "aLengthMenu": [[10, 15, 20, 25, 50, 100], [10, 15, 20, 25, 50, 100]], + "iDisplayLength" : 20, + "bAutoWidth": false, + "bFilter": false, + "bProcessing": true, + "bServerSide": true, + "sAjaxSource": 'batch_records_ajax.pl', + "sPaginationType": "full_numbers", + "aoColumns": [ + { "mDataProp": "import_record_id" }, + { "mDataProp": "citation" }, + { "mDataProp": "status" }, + { "mDataProp": "overlay_status" }, + { "mDataProp": "match_citation" }, + { "mDataProp": "matched" }, + ], + "fnServerData": function ( sSource, aoData, fnCallback ) { + aoData.push( { "name": "import_batch_id", "value": [% import_batch_id %] } ); + + $.getJSON( sSource, aoData, function (json) { + fnCallback(json) + } ); + }, + "fnRowCallback": function( nRow, aData, iDisplayIndex, iDisplayIndexFull ) { + $('td:eq(1)', nRow).html( + '<a rel="gb_page_center[600,500]" href="/cgi-bin/koha/catalogue/showmarc.pl?importid=' + + aData['import_record_id'] + '">' + aData['citation'] + '</a>' + ); + + if ( aData['match_id'] ) { + $('td:eq(4)', nRow).html( + _('Matches biblio ') + + aData['match_id'] + + ' (' + _('score') + '=' + + aData['score'] + + '):' + '<a target="_blank" href="http://staff.kohadev/cgi-bin/koha/catalogue/detail.pl?biblionumber=' + + aData['match_id'] + '">' + aData['match_citation'] + '</a>' + ); + } + + $('td:eq(5)', nRow).html( + '<a target="_blank" href="http://staff.kohadev/cgi-bin/koha/catalogue/detail.pl?biblionumber=' + + aData['matched'] + '">' + aData['matched'] + '</a>' + ); + }, + }); }); //]]> </script> @@ -316,61 +350,19 @@ Page [% END %] [% END %] -[% IF ( record_list ) %] - [% IF ( pages ) %] -<div class="pages"> -Page - [% FOREACH page IN pages %] - [% IF ( page.current_page ) %] - <span class="current">[% page.page_number %]</span> - [% ELSE %] - <a class="nav" href="[% page.script_name %]?import_batch_id=[% import_batch_id %]&offset=[% page.offset %]">[% page.page_number %]</a> - [% END %] - [% END %] -</div> - [% END %] -<table> - <tr> - <th>#</th> - <th>Citation</th> - <th>Status</th> - <th>Match?</th> - <th>Record</th> +<table id="records-table"> + <thead> + <tr> + <th>#</th> + <th>Citation</th> + <th>Status</th> + <th>Match?</th> + <th> </th> + <th>Record</th> + </tr> + </thead> - </tr> - [% FOREACH record_lis IN record_list %] - [% UNLESS ( loop.odd ) %]<tr class="highlight">[% ELSE %]<tr>[% END %] - <td>[% record_lis.record_sequence %]</td> - <td><a href="/cgi-bin/koha/catalogue/showmarc.pl?importid=[% record_lis.import_record_id %]" rel="gb_page_center[600,500]">[% record_lis.citation %]</a></td> - <td>[% record_lis.status %]</td> - <td>[% record_lis.overlay_status %]</td> - <td>[% IF ( record_lis.final_match_id ) %] - [% PROCESS final_match_link record=record_lis %] - [% END %] - </td> - </tr> - [% PROCESS match_link record=record_lis %] - [% END %] </table> - [% IF ( pages ) %] -<div class="pages"> -Page - [% FOREACH page IN pages %] - [% IF ( page.current_page ) %] - <span class="current">[% page.page_number %]</span> - [% ELSE %] - <a class="nav" href="[% page.script_name %]?import_batch_id=[% import_batch_id %]&offset=[% page.offset %]">[% page.page_number %]</a> - [% END %] - [% END %] -</div> - [% END %] -[% ELSE %] - [% IF ( batch_info ) %] - <div class="dialog alert">There are no records in this batch to import. - <a href="/cgi-bin/koha/tools/manage-marc-import.pl">Manage staged MARC records</a>.</div> - - [% END %] -[% END %] </div> </div> diff --git a/tools/batch_records_ajax.pl b/tools/batch_records_ajax.pl new file mode 100755 index 0000000..f4a1542 --- /dev/null +++ b/tools/batch_records_ajax.pl @@ -0,0 +1,112 @@ +#!/usr/bin/perl + +# This software is placed under the gnu General Public License, v2 (http://www.gnu.org/licenses/gpl.html) + +# Copyright 2007 Tamil s.a.r.l. +# +# 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 2 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. + +=head1 ysearch.pl + + +=cut + +use Modern::Perl; + +use CGI; +use JSON qw/ to_json /; + +use C4::Context; +use C4::Charset; +use C4::Auth qw/check_cookie_auth/; +use C4::ImportBatch; + +my $input = new CGI; + +my @sort_columns = + qw/import_record_id title status overlay_status overlay_status/; + +my $import_batch_id = $input->param('import_batch_id'); +my $offset = $input->param('iDisplayStart'); +my $results_per_page = $input->param('iDisplayLength'); +my $sorting_column = $sort_columns[ $input->param('iSortCol_0') ]; +my $sorting_direction = $input->param('sSortDir_0'); + +binmode STDOUT, ":encoding(UTF-8)"; +print $input->header( -type => 'text/plain', -charset => 'UTF-8' ); + +my ( $auth_status, $sessionID ) = + check_cookie_auth( $input->cookie('CGISESSID'), { editcatalogue => '*' } ); +if ( $auth_status ne "ok" ) { + exit 0; +} + +my $batch = GetImportBatch($import_batch_id); +my $records = + GetImportRecordsRange( $import_batch_id, $offset, $results_per_page, undef, + { order_by => $sorting_column, order_by_direction => $sorting_direction } ); +my @list = (); +foreach my $record (@$records) { + my $citation = $record->{'title'} || $record->{'authorized_heading'}; + $citation .= " $record->{'author'}" if $record->{'author'}; + $citation .= " (" if $record->{'issn'} or $record->{'isbn'}; + $citation .= $record->{'isbn'} if $record->{'isbn'}; + $citation .= ", " if $record->{'issn'} and $record->{'isbn'}; + $citation .= $record->{'issn'} if $record->{'issn'}; + $citation .= ")" if $record->{'issn'} or $record->{'isbn'}; + + my $match = GetImportRecordMatches( $record->{'import_record_id'}, 1 ); + my $match_citation = ''; + my $match_id; + if ( $#$match > -1 ) { + if ( $match->[0]->{'record_type'} eq 'biblio' ) { + $match_citation .= $match->[0]->{'title'} + if defined( $match->[0]->{'title'} ); + $match_citation .= ' ' . $match->[0]->{'author'} + if defined( $match->[0]->{'author'} ); + $match_id = $match->[0]->{'biblionumber'}; + } + elsif ( $match->[0]->{'record_type'} eq 'auth' ) { + if ( defined( $match->[0]->{'authorized_heading'} ) ) { + $match_citation .= $match->[0]->{'authorized_heading'}; + $match_id = $match->[0]->{'candidate_match_id'}; + } + } + } + + push @list, + { + DT_RowId => $record->{'import_record_id'}, + import_record_id => $record->{'import_record_id'}, + citation => $citation, + status => $record->{'status'}, + overlay_status => $record->{'overlay_status'}, + match_citation => $match_citation, + matched => $record->{'matched_biblionumber'} + || $record->{'matched_authid'} + || q{}, + score => $#$match > -1 ? $match->[0]->{'score'} : 0, + match_id => $match_id, + }; +} + +my $data; +$data->{'iTotalRecords'} = $batch->{'num_records'}; +$data->{'iTotalDisplayRecords'} = $batch->{'num_records'}; +$data->{'sEcho'} = $input->param('sEcho') || undef; +$data->{'aaData'} = \@list; + +print to_json($data); diff --git a/tools/manage-marc-import.pl b/tools/manage-marc-import.pl index 25f7769..62d581d 100755 --- a/tools/manage-marc-import.pl +++ b/tools/manage-marc-import.pl @@ -352,55 +352,55 @@ sub import_records_list { my ($template, $import_batch_id, $offset, $results_per_page) = @_; my $batch = GetImportBatch($import_batch_id); - my $records = GetImportRecordsRange($import_batch_id, $offset, $results_per_page); - my @list = (); - foreach my $record (@$records) { - my $citation = $record->{'title'} || $record->{'authorized_heading'}; - $citation .= " $record->{'author'}" if $record->{'author'}; - $citation .= " (" if $record->{'issn'} or $record->{'isbn'}; - $citation .= $record->{'isbn'} if $record->{'isbn'}; - $citation .= ", " if $record->{'issn'} and $record->{'isbn'}; - $citation .= $record->{'issn'} if $record->{'issn'}; - $citation .= ")" if $record->{'issn'} or $record->{'isbn'}; - - my $match = GetImportRecordMatches($record->{'import_record_id'}, 1); - my $match_citation = ''; - my $match_id; - if ($#$match > -1) { - if ($match->[0]->{'record_type'} eq 'biblio') { - $match_citation .= $match->[0]->{'title'} if defined($match->[0]->{'title'}); - $match_citation .= ' ' . $match->[0]->{'author'} if defined($match->[0]->{'author'}); - $match_id = $match->[0]->{'biblionumber'}; - } elsif ($match->[0]->{'record_type'} eq 'auth') { - if (defined($match->[0]->{'authorized_heading'})) { - $match_citation .= $match->[0]->{'authorized_heading'}; - $match_id = $match->[0]->{'candidate_match_id'}; - } - } - } - - push @list, - { import_record_id => $record->{'import_record_id'}, - final_match_id => $record->{'matched_biblionumber'} || $record->{'matched_authid'}, - citation => $citation, - status => $record->{'status'}, - record_sequence => $record->{'record_sequence'}, - overlay_status => $record->{'overlay_status'}, - # Sorry about the match_id being from the "biblionumber" field; - # as it turns out, any match id will go in biblionumber - match_id => $match_id, - match_citation => $match_citation, - match_score => $#$match > -1 ? $match->[0]->{'score'} : 0, - record_type => $record->{'record_type'}, - }; - } - my $num_records = $batch->{'num_records'}; - $template->param(record_list => \@list); - add_page_numbers($template, $offset, $results_per_page, $num_records); - $template->param(offset => $offset); - $template->param(range_top => $offset + $results_per_page - 1); - $template->param(num_results => $num_records); - $template->param(results_per_page => $results_per_page); +# my $records = GetImportRecordsRange($import_batch_id); +# my @list = (); +# foreach my $record (@$records) { +# my $citation = $record->{'title'} || $record->{'authorized_heading'}; +# $citation .= " $record->{'author'}" if $record->{'author'}; +# $citation .= " (" if $record->{'issn'} or $record->{'isbn'}; +# $citation .= $record->{'isbn'} if $record->{'isbn'}; +# $citation .= ", " if $record->{'issn'} and $record->{'isbn'}; +# $citation .= $record->{'issn'} if $record->{'issn'}; +# $citation .= ")" if $record->{'issn'} or $record->{'isbn'}; +# +# my $match = GetImportRecordMatches($record->{'import_record_id'}, 1); +# my $match_citation = ''; +# my $match_id; +# if ($#$match > -1) { +# if ($match->[0]->{'record_type'} eq 'biblio') { +# $match_citation .= $match->[0]->{'title'} if defined($match->[0]->{'title'}); +# $match_citation .= ' ' . $match->[0]->{'author'} if defined($match->[0]->{'author'}); +# $match_id = $match->[0]->{'biblionumber'}; +# } elsif ($match->[0]->{'record_type'} eq 'auth') { +# if (defined($match->[0]->{'authorized_heading'})) { +# $match_citation .= $match->[0]->{'authorized_heading'}; +# $match_id = $match->[0]->{'candidate_match_id'}; +# } +# } +# } +# +# push @list, +# { import_record_id => $record->{'import_record_id'}, +# final_match_id => $record->{'matched_biblionumber'} || $record->{'matched_authid'}, +# citation => $citation, +# status => $record->{'status'}, +# record_sequence => $record->{'record_sequence'}, +# overlay_status => $record->{'overlay_status'}, +# # Sorry about the match_id being from the "biblionumber" field; +# # as it turns out, any match id will go in biblionumber +# match_id => $match_id, +# match_citation => $match_citation, +# match_score => $#$match > -1 ? $match->[0]->{'score'} : 0, +# record_type => $record->{'record_type'}, +# }; +# } +# my $num_records = $batch->{'num_records'}; +# $template->param(record_list => \@list); +# add_page_numbers($template, $offset, $results_per_page, $num_records); +# $template->param(offset => $offset); +# $template->param(range_top => $offset + $results_per_page - 1); +# $template->param(num_results => $num_records); +# $template->param(results_per_page => $results_per_page); $template->param(import_batch_id => $import_batch_id); my $overlay_action = GetImportBatchOverlayAction($import_batch_id); $template->param("overlay_action_${overlay_action}" => 1); -- 1.7.2.5