Bug 24156: Make sort order and number of items to display configurable (basket page)
authorJonathan Druart <jonathan.druart@bugs.koha-community.org>
Thu, 5 Dec 2019 16:55:00 +0000 (17:55 +0100)
committerJonathan Druart <jonathan.druart@bugs.koha-community.org>
Thu, 25 Jun 2020 08:51:59 +0000 (10:51 +0200)
This patch is the main patch of this patchset, you will find the
description and the test plan.

The idea of this new enhancement is to add the ability to define the
default sort order and the default number of rows displayed on the
acquisition basket page.
The existing "columns settings" feature was replaced by a
"tables settings" feature. To prepare the ground, there were some
works that were needed:
  * rename variables and files
  * Modify the structure of the yml files
  * Create a new DB table to store the tables settings

Test plan:
0)
  a. Execute the update DB entry to create the new table
  b. Restart all (to get a new version of the yml file, that is cached by
   memcached)
  c. Create several orders for a given basket
1) Go to the basket view page
=> The default values are the same than without this patchset, the
number of entries to display is set to "20" and the table is sorted by
basket number (first column)
2) Go to the "Columns settings" page
3) Unfold the "Acquisition" tab
=> Notice the 2 dropdown lists at the bottom of the basket table
4) Select different values for "Default display length" and "Default
sort order"
5) Refresh the basket view page
=> Notice that the default settings are now effective on the table

QA note: We can decide to replace the different occurrences of "Columns settings"
by "Tables settings" if needed.

Sponsored-by: Institute of Technology Tallaght

Signed-off-by: Liz Rea <wizzyrea@gmail.com>

Signed-off-by: Liz Rea <wizzyrea@gmail.com>
Signed-off-by: Alex Arnaud <alex.arnaud@biblibre.com>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>

C4/Utils/DataTables/TablesSettings.pm
Koha/Template/Plugin/TablesSettings.pm
admin/columns_settings.pl
koha-tmpl/intranet-tmpl/prog/en/modules/acqui/basket.tt
koha-tmpl/intranet-tmpl/prog/en/modules/admin/columns_settings.tt
t/db_dependent/TablesSettings.t

index 1c52dbb..a343944 100644 (file)
@@ -14,7 +14,7 @@ sub get_yaml {
 
     unless ($yaml) {
         $yaml = eval { YAML::LoadFile($yml_path) };
-        warn "ERROR: the yaml file for DT::TablesSettings is not correctly formated: $@"
+        warn "ERROR: the yaml file for DT::TablesSettings is not correctly formatted: $@"
           if $@;
         $cache->set_in_cache( 'TablesSettingsYaml', $yaml, { expiry => 3600 } );
     }
@@ -39,12 +39,12 @@ sub get_columns {
 
     while ( my $c = $rs->next ) {
         my $column = first { $c->columnname eq $_->{columnname} }
-        @{ $list->{modules}{ $c->module }{ $c->page }{ $c->tablename } };
+        @{ $list->{modules}{ $c->module }{ $c->page }{ $c->tablename }{ columns } };
         $column->{is_hidden}         = $c->is_hidden;
         $column->{cannot_be_toggled} = $c->cannot_be_toggled;
     }
 
-    my $columns = $list->{modules}{$module}{$page}{$tablename} || [];
+    my $columns = $list->{modules}{$module}{$page}{$tablename}{columns} || [];
 
     # Assign default value if does not exist
     $columns = [ map {
@@ -59,6 +59,22 @@ sub get_columns {
     return $columns;
 }
 
+sub get_table_settings {
+    my ( $module, $page, $tablename ) = @_;
+    my $list = get_yaml;
+
+    my $schema = Koha::Database->new->schema;
+
+    my $rs = $schema->resultset('TablesSetting')->search(
+        {
+            module    => $module,
+            page      => $page,
+            tablename => $tablename,
+        }
+    )->next;
+    return $rs ? $rs : $list->{modules}{$module}{$page}{$tablename};
+}
+
 sub get_modules {
     my $list = get_yaml;
 
@@ -67,7 +83,7 @@ sub get_modules {
 
     while ( my $c = $rs->next ) {
         my $column = first { $c->columnname eq $_->{columnname} }
-        @{ $list->{modules}{ $c->module }{ $c->page }{ $c->tablename } };
+        @{ $list->{modules}{ $c->module }{ $c->page }{ $c->tablename }{columns} };
         $column->{is_hidden}         = $c->is_hidden;
         $column->{cannot_be_toggled} = $c->cannot_be_toggled;
         $column->{cannot_be_modified} = 0
@@ -100,4 +116,41 @@ sub update_columns {
     }
 }
 
+=head3 update_table_settings
+
+C4::Utils::DataTables::TablesSettings::update_table_settings(
+    {
+        module                 => $module,
+        pag                    => $page,
+        tablename              => $tablename,
+        default_display_length => $default_display_length,
+        default_sort_order     => $default_sort_order
+    }
+);
+
+Will update the default_display_length and default_sort_order for the given table.
+
+=cut
+
+sub update_table_settings {
+    my ($params)               = @_;
+    my $module                 = $params->{module};
+    my $page                   = $params->{page};
+    my $tablename              = $params->{tablename};
+    my $default_display_length = $params->{default_display_length};
+    my $default_sort_order     = $params->{default_sort_order};
+
+    my $schema = Koha::Database->new->schema;
+
+    $schema->resultset('TablesSetting')->update_or_create(
+        {
+            module                 => $module,
+            page                   => $page,
+            tablename              => $tablename,
+            default_display_length => $default_display_length,
+            default_sort_order     => $default_sort_order,
+        }
+    );
+}
+
 1;
index 2ed567c..6aecf52 100644 (file)
@@ -74,6 +74,17 @@ datatables instantiator.
 
 =cut
 
+=head3 GetColumns
+
+var columns_settings = [% TablesSettings.GetColumns( module, page, table 'json' ) | $raw%]
+
+This method is usually be used to retrieve the columns settings for a DataTable init.
+
+So the 'json' format will be provided and the columns_settings JS var will be
+passed as argument of the constructor.
+
+=cut
+
 sub GetColumns {
     my ( $self, $module, $page, $table, $format ) = @_;
     $format //= q{};
@@ -107,4 +118,25 @@ sub is_hidden {
     return 0;
 }
 
+=head3 GetTableSettings
+
+[% SET table_settings = GetTableSettings( module, page, table ) %]
+
+This method is used to retrieve the tables settings (like table_settings.default_display_length and
+table_settings.default_sort_order).
+They can be passed to the DataTable constructor (for iDisplayLength and order parameters)
+
+=cut
+
+sub GetTableSettings {
+    my ( $self, $module, $page, $table, $format ) = @_;
+    $format //= q{};
+
+    my $settings = C4::Utils::DataTables::TablesSettings::get_table_settings( $module, $page, $table );
+
+    return $format eq 'json'
+        ? to_json( $settings || {} )
+        : $settings
+}
+
 1;
index 11117de..afa33c7 100755 (executable)
@@ -48,6 +48,24 @@ if ( $action eq 'save' ) {
         }
     );
 
+    my @table_ids = $input->multi_param('table_id');
+    for my $table_id (@table_ids) {
+        next unless $table_id =~ m|^([^#]*)#(.*)$|;
+        my $default_display_length = $input->param( $table_id . '_default_display_length' );
+        my $default_sort_order     = $input->param( $table_id . '_default_sort_order' );
+        if ( $default_display_length && $default_sort_order ) {
+            C4::Utils::DataTables::TablesSettings::update_table_settings(
+                {
+                    module                 => $module,
+                    page                   => $1,
+                    tablename              => $2,
+                    default_display_length => $default_display_length,
+                    default_sort_order     => $default_sort_order,
+                }
+            );
+        }
+    }
+
     $action = 'list';
 }
 
index e709ec8..784838b 100644 (file)
     [% END %]
     <script>
         var columns_settings = [% TablesSettings.GetColumns( 'acqui', 'basket', 'orders', 'json' ) | $raw %];
+        [% SET table_settings = TablesSettings.GetTableSettings( 'acqui', 'basket', 'orders' ) %];
         $(document).ready(function() {
             KohaTable("orders", {
                 [% IF ( active ) %]
                 [% END %]
                 "sPaginationType": "full",
                 "autoWidth": false,
-                "exportColumns": [0,1,2,3,4,5,6,7,8,9,10,11,12,13]
+                "exportColumns": [0,1,2,3,4,5,6,7,8,9,10,11,12,13],
+                "iDisplayLength": [% table_settings.default_display_length | html %],
+                "order": [[ [% table_settings.default_sort_order | html %], 'asc']],
             }, columns_settings);
 
             var cancelledorderst = $("#cancelledorderst").dataTable($.extend(true, {}, dataTablesDefaults, {
index db421ce..04c6fad 100644 (file)
@@ -1,7 +1,9 @@
 [% USE raw %]
 [% USE Asset %]
+[% USE TablesSettings %]
 [% SET footerjs = 1 %]
 [% SET panel_id = 0 %]
+[% USE Dumper %]
 [% BLOCK pagelist %]
     [% IF module.keys and module.keys.size > 0 %]
         Jump to:
                     [% SET tables = module %]
                     [% IF tables.$pagename.keys and tables.$pagename.keys.size > 0 %]
                         [% FOR tablename IN tables.$pagename.keys.sort %]
-                            [% IF pagename == 'additem' AND tablename == 'itemst' %]
-                                <div class="alert">Changes made below will only apply to item subfields that are mapped to the 'items' table. <a href="/cgi-bin/koha/admin/koha2marclinks.pl?tablename=items">Go to Koha to MARC mapping</a></div>
-                            [% END %]
-                            <table>
-                                <caption>
-                                    [% IF tablename == 'currencies-table' %]
-                                        Currency
-                                    [% ELSIF pagename == 'additem' AND tablename == 'itemst' %]
-                                        Items Editor
-                                    [% ELSE %]
-                                        Table id: [% tablename | html %]
-                                    [% END %]
-                                </caption>
-                                <thead>
-                                    <tr>
-                                        <th>Column name</th>
-                                        <th>Is hidden by default</th>
-                                        <th>Cannot be toggled</th>
-                                    </tr>
-                                </thead>
-                                <tbody>
-                                    [% FOR column IN tables.$pagename.$tablename %]
-                                        [% SET value = pagename _ '#' _ tablename _ '#' _ column.columnname %]
+                            [% SET table_id = pagename _ '#' _ tablename %]
+                            <div class="datatable_config" id="[% table_id | html %]" style="border:1px solid #7EA6B2; padding: 1em;">
+                                <input type="hidden" name="table_id" value="[% table_id| html %]" />
+                                [% IF pagename == 'additem' AND tablename == 'itemst' %]
+                                    <div class="alert">Changes made below will only apply to item subfields that are mapped to the 'items' table. <a href="/cgi-bin/koha/admin/koha2marclinks.pl?tablename=items">Go to Koha to MARC mapping</a></div>
+                                [% END %]
+                                <table>
+                                    <caption>
+                                        [% IF tablename == 'currencies-table' %]
+                                            Currency
+                                        [% ELSIF pagename == 'additem' AND tablename == 'itemst' %]
+                                            Items Editor
+                                        [% ELSE %]
+                                            Table id: [% tablename | html %]
+                                        [% END %]
+                                    </caption>
+                                    <thead>
                                         <tr>
-                                            <td>
-                                                [% column.columnname | html %]
-                                                <input type="hidden" name="columnid" value="[% value | html %]" />
-                                            </td>
-                                            <td>
-                                                [% IF column.is_hidden %]
-                                                    [% IF column.cannot_be_modified %]
-                                                        <input type="checkbox" name="[% value | html %]_hidden" value="1" checked="checked" disabled="disabled" />
-                                                        <input type="hidden" name="[% value | html %]_hidden" value="1" />
-                                                    [% ELSE %]
-                                                        <input type="checkbox" name="[% value | html %]_hidden" value="1" checked="checked" />
-                                                    [% END %]
-                                                [% ELSE %]
-                                                    [% IF column.cannot_be_modified %]
-                                                        <input type="checkbox" name="[% value | html %]_hidden" value="1" disabled="disabled" />
-                                                        <input type="hidden" name="[% value | html %]_hidden" value="0" />
+                                            <th>Column name</th>
+                                            <th>Is hidden by default</th>
+                                            <th>Cannot be toggled</th>
+                                        </tr>
+                                    </thead>
+                                    <tbody>
+                                        [% FOR column IN tables.$pagename.$tablename.columns %]
+                                            [% SET value = pagename _ '#' _ tablename _ '#' _ column.columnname %]
+                                            <tr>
+                                                <td>
+                                                    [% column.columnname | html %]
+                                                    <input type="hidden" name="columnid" value="[% value | html %]" />
+                                                </td>
+                                                <td>
+                                                    [% IF column.is_hidden %]
+                                                        [% IF column.cannot_be_modified %]
+                                                            <input type="checkbox" name="[% value | html %]_hidden" value="1" checked="checked" disabled="disabled" />
+                                                            <input type="hidden" name="[% value | html %]_hidden" value="1" />
+                                                        [% ELSE %]
+                                                            <input type="checkbox" name="[% value | html %]_hidden" value="1" checked="checked" />
+                                                        [% END %]
                                                     [% ELSE %]
-                                                        <input type="checkbox" name="[% value | html %]_hidden" value="1" />
+                                                        [% IF column.cannot_be_modified %]
+                                                            <input type="checkbox" name="[% value | html %]_hidden" value="1" disabled="disabled" />
+                                                            <input type="hidden" name="[% value | html %]_hidden" value="0" />
+                                                        [% ELSE %]
+                                                            <input type="checkbox" name="[% value | html %]_hidden" value="1" />
+                                                        [% END %]
                                                     [% END %]
-                                                [% END %]
-                                            </td>
-                                            <td>
-                                                [% IF column.cannot_be_toggled %]
-                                                    [% IF column.cannot_be_modified %]
-                                                        <input type="checkbox" name="[% value | html %]_cannot_be_toggled" value="1" checked="checked" disabled="disabled" />
-                                                        <input type="hidden" name="[% value | html %]_cannot_be_toggled" value="1" />
+                                                </td>
+                                                <td>
+                                                    [% IF column.cannot_be_toggled %]
+                                                        [% IF column.cannot_be_modified %]
+                                                            <input type="checkbox" name="[% value | html %]_cannot_be_toggled" value="1" checked="checked" disabled="disabled" />
+                                                            <input type="hidden" name="[% value | html %]_cannot_be_toggled" value="1" />
+                                                        [% ELSE %]
+                                                            <input type="checkbox" name="[% value | html %]_cannot_be_toggled" value="1" checked="checked" />
+                                                        [% END %]
                                                     [% ELSE %]
-                                                        <input type="checkbox" name="[% value | html %]_cannot_be_toggled" value="1" checked="checked" />
+                                                        [% IF column.cannot_be_modified %]
+                                                            <input type="checkbox" name="[% value | html %]_cannot_be_toggled" value="1" disabled="disabled" />
+                                                            <input type="hidden" name="[% value | html %]_cannot_be_toggled" value="0" />
+                                                        [% ELSE %]
+                                                            <input type="checkbox" name="[% value | html %]_cannot_be_toggled" value="1" />
+                                                        [% END %]
                                                     [% END %]
+                                                </td>
+                                            </tr>
+                                        [% END %]
+                                    </tbody>
+                                </table>
+                                [% SET table_settings = TablesSettings.GetTableSettings( modulename, pagename, tablename ) %]
+                                [% IF table_settings.default_display_length %]
+                                    <p>
+                                        Default display length:
+                                        <select name="[% table_id | html %]_default_display_length">
+                                            [% IF table_settings.default_display_length == 10 %]
+                                                <option value="10" selected="selected">10</option>
+                                            [% ELSE %]
+                                            [% END %]
+                                            [% IF table_settings.default_display_length == 20 %]
+                                                <option value="20" selected="selected">20</option>
+                                            [% ELSE %]
+                                                <option value="20">20</option>
+                                            [% END %]
+                                            [% IF table_settings.default_display_length == 50 %]
+                                                <option value="50" selected="selected">50</option>
+                                            [% ELSE %]
+                                                <option value="50">50</option>
+                                            [% END %]
+                                            [% IF table_settings.default_display_length == 100 %]
+                                                <option value="100" selected="selected">100</option>
+                                            [% ELSE %]
+                                                <option value="100">100</option>
+                                            [% END %]
+                                            [% IF table_settings.default_display_length == -1 %]
+                                                <option value="-1" selected="selected">All</option>
+                                            [% ELSE %]
+                                                <option value="-1">All</option>
+                                            [% END %]
+                                        </select>
+                                    </p>
+                                [% END %]
+                                [% IF table_settings.default_sort_order.defined %]
+                                    <p>
+                                        Default sort order:
+                                        <select name="[% pagename | html %]#[% tablename | html %]_default_sort_order">
+                                            [% FOR column IN tables.$pagename.$tablename.columns %]
+                                                [% IF table_settings.default_sort_order == loop.count - 1 %]
+                                                    <option value="[% loop.count - 1 %]" selected="selected">[% column.columnname | html %]</option>
                                                 [% ELSE %]
-                                                    [% IF column.cannot_be_modified %]
-                                                        <input type="checkbox" name="[% value | html %]_cannot_be_toggled" value="1" disabled="disabled" />
-                                                        <input type="hidden" name="[% value | html %]_cannot_be_toggled" value="0" />
-                                                    [% ELSE %]
-                                                        <input type="checkbox" name="[% value | html %]_cannot_be_toggled" value="1" />
-                                                    [% END %]
+                                                    <option value="[% loop.count - 1 %]">[% column.columnname | html %]</option>
                                                 [% END %]
-                                            </td>
-                                        </tr>
-                                    [% END %]
-                                </tbody>
-                            </table>
+                                            [% END %]
+                                        </select>
+                                    </p>
+                                [% END %]
+
+                            </div>
                         [% END %]
                         <fieldset class="action">
                             <input type="submit" value="Save" />
index d53f9f1..eda462d 100644 (file)
@@ -1,7 +1,7 @@
 #!/usr/bin/perl;
 
 use Modern::Perl;
-use Test::More tests => 2;
+use Test::More tests => 3;
 use Test::MockModule;
 
 use C4::Context;
@@ -22,38 +22,41 @@ $module->mock(
             modules => {
                 admin => {
                     currency => {
-                        'currencies-table' => [
-                            {
-                                columnname         => 'currency',
-                                cannot_be_toggled  => '1',
-                                cannot_be_modified => '1'
-                            },
-                            {
-                                columnname         => 'rate',
-                                cannot_be_toggled  => '1',
-                                cannot_be_modified => '1'
-                            },
-                            {
-                                columnname => 'symbol'
-                            },
-                            {
-                                is_hidden  => '1',
-                                columnname => 'iso_code'
-                            },
-                            {
-                                columnname => 'last_updated'
-                            },
-                            {
-                                columnname => 'active'
-                            },
-                            {
-                                columnname => 'actions'
-                            }
-                        ]
+                        'currencies-table' => {
+                            default_display_length => 20,
+                            default_sort_order => 1,
+                            columns => [
+                                {
+                                    columnname         => 'currency',
+                                    cannot_be_toggled  => '1',
+                                    cannot_be_modified => '1'
+                                },
+                                {
+                                    columnname         => 'rate',
+                                    cannot_be_toggled  => '1',
+                                    cannot_be_modified => '1'
+                                },
+                                {
+                                    columnname => 'symbol'
+                                },
+                                {
+                                    is_hidden  => '1',
+                                    columnname => 'iso_code'
+                                },
+                                {
+                                    columnname => 'last_updated'
+                                },
+                                {
+                                    columnname => 'active'
+                                },
+                                {
+                                    columnname => 'actions'
+                                }
+                            ]
+                        }
                     }
-                }
-              }
-
+                },
+            }
         };
     }
 );
@@ -119,50 +122,54 @@ my $modules = C4::Utils::DataTables::TablesSettings::get_modules();
 my $modules_expected = {
     'admin' => {
         'currency' => {
-            'currencies-table' => [
-                {
-                    columnname         => 'currency',
-                    cannot_be_toggled  => 1,
-                    cannot_be_modified => 1,
-                    is_hidden  => 0,
-                },
-                {
-                    columnname         => 'rate',
-                    cannot_be_toggled  => 1,
-                    cannot_be_modified => 1,
-                    is_hidden  => 0,
-                },
-                {
-                    columnname => 'symbol',
-                    cannot_be_toggled  => 0,
-                    cannot_be_modified => 0,
-                    is_hidden  => 0,
-                },
-                {
-                    columnname => 'iso_code',
-                    cannot_be_toggled  => 0,
-                    cannot_be_modified => 0,
-                    is_hidden  => 0,
-                },
-                {
-                    columnname => 'last_updated',
-                    cannot_be_toggled  => 0,
-                    cannot_be_modified => 0,
-                    is_hidden  => 0,
-                },
-                {
-                    columnname => 'active',
-                    cannot_be_toggled  => 0,
-                    cannot_be_modified => 0,
-                    is_hidden  => 1,
-                },
-                {
-                    columnname        => 'actions',
-                    cannot_be_toggled => 1,
-                    cannot_be_modified => 0,
-                    is_hidden  => 0,
-                },
-            ]
+            'currencies-table' => {
+                default_display_length => 20,
+                default_sort_order => 1,
+                columns => [
+                    {
+                        columnname         => 'currency',
+                        cannot_be_toggled  => 1,
+                        cannot_be_modified => 1,
+                        is_hidden  => 0,
+                    },
+                    {
+                        columnname         => 'rate',
+                        cannot_be_toggled  => 1,
+                        cannot_be_modified => 1,
+                        is_hidden  => 0,
+                    },
+                    {
+                        columnname => 'symbol',
+                        cannot_be_toggled  => 0,
+                        cannot_be_modified => 0,
+                        is_hidden  => 0,
+                    },
+                    {
+                        columnname => 'iso_code',
+                        cannot_be_toggled  => 0,
+                        cannot_be_modified => 0,
+                        is_hidden  => 0,
+                    },
+                    {
+                        columnname => 'last_updated',
+                        cannot_be_toggled  => 0,
+                        cannot_be_modified => 0,
+                        is_hidden  => 0,
+                    },
+                    {
+                        columnname => 'active',
+                        cannot_be_toggled  => 0,
+                        cannot_be_modified => 0,
+                        is_hidden  => 1,
+                    },
+                    {
+                        columnname        => 'actions',
+                        cannot_be_toggled => 1,
+                        cannot_be_modified => 0,
+                        is_hidden  => 0,
+                    },
+                ]
+            }
         }
     }
 };
@@ -176,9 +183,21 @@ for my $m ( keys %$modules ) {
               C4::Utils::DataTables::TablesSettings::get_columns( $m, $p, $t );
             is_deeply(
                 $columns,
-                $modules->{$m}{$p}{$t},
+                $modules->{$m}{$p}{$t}{columns},
                 "columns for $m>$p>$t"
             );
+            my $table_settings =
+              C4::Utils::DataTables::TablesSettings::get_table_settings( $m, $p, $t );
+            is_deeply(
+                {
+                    default_display_length => $table_settings->{default_display_length},
+                    default_sort_order     => $table_settings->{default_sort_order}
+                },
+                {
+                    default_display_length => $modules->{$m}{$p}{$t}{default_display_length},
+                    default_sort_order     => $modules->{$m}{$p}{$t}{default_sort_order},
+                }
+            );
         }
     }
 }