[open-ils-commits] [GIT] Evergreen ILS branch master updated. f0a523932954579685cd95505c3d064b4450aa0a

Evergreen Git git at git.evergreen-ils.org
Fri Jun 30 10:45:39 EDT 2017


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Evergreen ILS".

The branch, master has been updated
       via  f0a523932954579685cd95505c3d064b4450aa0a (commit)
       via  c0989e28005e21ecf6cfa6a70750c385ad52f070 (commit)
       via  85a648005c0948a641b79a64d9b9029bdfc02ecf (commit)
       via  07425b0cc1737a515af877d66fdd5f349514a2e8 (commit)
       via  63cebb9dcdb960d754322a4aad810d351e1f4a84 (commit)
       via  dc038b64a9d32ac0d2c631cda8aa6b2926660c42 (commit)
       via  23483d848a9869284b6584e37136fb0c5e7ca757 (commit)
       via  f9cac2940e4f5c6fec9506119017e8e8c332d1e6 (commit)
       via  c5c5f878d3f15b04475ce5f76a844b78953ce1a5 (commit)
       via  1e0ff6f2b91293e80588cb4843b0911a5c85953f (commit)
       via  70e126cd0121c1de2246bf6f51be7c772d8a7e06 (commit)
       via  dac1016c777c821b455f9be34e093a1441a52326 (commit)
       via  26352c64f78e45ee7be09439f40e03a31bbc67f9 (commit)
       via  c1f3bd316785d9f68a20f49943129649ee113928 (commit)
       via  520215937726cba99ab6aeb8c16e689b2c3e0dd5 (commit)
      from  58e662f046b178ad7696a288c9e26546216902a1 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit f0a523932954579685cd95505c3d064b4450aa0a
Author: Bill Erickson <berickxx at gmail.com>
Date:   Thu Jun 29 14:51:40 2017 -0400

    LP#1697954 Items out fetch grids only when needed
    
    Avoid forcing a refresh of Items Out grids in cases where the grids will
    automatically refresh as a new grid is instantiated.  This prevents the
    code from calling redundant data collection APIs, resulting in local
    cache's with duplicate data sets.
    
    Signed-off-by: Bill Erickson <berickxx at gmail.com>
    Signed-off-by: Mike Rylander <mrylander at gmail.com>

diff --git a/Open-ILS/src/templates/staff/circ/patron/t_items_out.tt2 b/Open-ILS/src/templates/staff/circ/patron/t_items_out.tt2
index c6b6e62..c8b0d1f 100644
--- a/Open-ILS/src/templates/staff/circ/patron/t_items_out.tt2
+++ b/Open-ILS/src/templates/staff/circ/patron/t_items_out.tt2
@@ -5,12 +5,12 @@
       circ list is meant to display -->
   <ul class="nav nav-tabs">
     <li ng-class="{active : items_out_display == 'main'}">
-      <a href ng-click="show_main_list()">
+      <a href ng-click="show_main_list(items_out_display=='alt')">
         [% l('Items Checked Out') %] ({{main_list.length}})
       </a>
     </li>
     <li ng-if="show_alt_circs" ng-class="{active : items_out_display == 'alt'}">
-      <a href ng-click="show_alt_list()">
+      <a href ng-click="show_alt_list(items_out_display=='main')">
         [% l('Other/Special Circulations') %] ({{alt_list.length}})
       </a>
     </li>
diff --git a/Open-ILS/web/js/ui/default/staff/circ/patron/items_out.js b/Open-ILS/web/js/ui/default/staff/circ/patron/items_out.js
index 51f935f..be77ab2 100644
--- a/Open-ILS/web/js/ui/default/staff/circ/patron/items_out.js
+++ b/Open-ILS/web/js/ui/default/staff/circ/patron/items_out.js
@@ -55,25 +55,30 @@ function($scope,  $q,  $routeParams,  $timeout,  egCore , egUser,  patronSvc , $
     }
 
     $scope.items_out_display = 'main';
-    $scope.show_main_list = function() {
+    $scope.show_main_list = function(refresh_grid) {
         // don't need a full reset_page() to swap tabs
         $scope.items_out_display = 'main';
         patronSvc.items_out = [];
-        provider.refresh();
+        // only refresh the grid when navigating from a tab that 
+        // shares the same grid.
+        if (refresh_grid) provider.refresh();
     }
 
-    $scope.show_alt_list = function() {
+    $scope.show_alt_list = function(refresh_grid) {
         // don't need a full reset_page() to swap tabs
         $scope.items_out_display = 'alt';
         patronSvc.items_out = [];
-        provider.refresh();
+        // only refresh the grid when navigating from a tab that 
+        // shares the same grid.
+        if (refresh_grid) provider.refresh();
     }
 
     $scope.show_noncat_list = function() {
         // don't need a full reset_page() to swap tabs
         $scope.items_out_display = 'noncat';
         patronSvc.items_out = [];
-        provider.refresh();
+        // Grid refresh is not necessary because switching to the
+        // noncat_list always involves instantiating a new grid.
     }
 
     // Reload the user to pick up changes in items out, fines, etc.
@@ -84,7 +89,7 @@ function($scope,  $q,  $routeParams,  $timeout,  egCore , egUser,  patronSvc , $
         patronSvc.items_out = []; 
         $scope.main_list = [];
         $scope.alt_list = [];
-        provider.refresh() 
+        $timeout(provider.refresh);  // allow scope changes to propagate
     }
 
     var provider = egGridDataProvider.instance({});
@@ -231,6 +236,7 @@ function($scope,  $q,  $routeParams,  $timeout,  egCore , egUser,  patronSvc , $
         var id_list = $scope[$scope.items_out_display + '_list'];
 
         // see if we have the requested range cached
+        // Note this items_out list is reset w/ each items-out tab change
         if (patronSvc.items_out[offset]) {
             return provider.arrayNotifier(
                 patronSvc.items_out, offset, count);

commit c0989e28005e21ecf6cfa6a70750c385ad52f070
Author: Bill Erickson <berickxx at gmail.com>
Date:   Thu Jun 29 11:55:26 2017 -0400

    LP#1697954 Items out pre-fetch renders selected range
    
    Items out and noncat items out grids now only render the selected range
    of transactions, instead of the full set collected for client-side grid
    sorting.
    
    Signed-off-by: Bill Erickson <berickxx at gmail.com>
    Signed-off-by: Mike Rylander <mrylander at gmail.com>

diff --git a/Open-ILS/web/js/ui/default/staff/circ/patron/items_out.js b/Open-ILS/web/js/ui/default/staff/circ/patron/items_out.js
index 449f190..51f935f 100644
--- a/Open-ILS/web/js/ui/default/staff/circ/patron/items_out.js
+++ b/Open-ILS/web/js/ui/default/staff/circ/patron/items_out.js
@@ -93,8 +93,11 @@ function($scope,  $q,  $routeParams,  $timeout,  egCore , egUser,  patronSvc , $
     function fetch_circs(id_list, offset, count) {
         if (!id_list.length) return $q.when();
 
+        var deferred = $q.defer();
+        var rendered = 0;
+
         // fetch the lot of circs and stream the results back via notify
-        return egCore.pcrud.search('circ', {id : id_list},
+        egCore.pcrud.search('circ', {id : id_list},
             {   flesh : 4,
                 flesh_fields : {
                     circ : ['target_copy', 'workstation', 'checkin_workstation'],
@@ -114,7 +117,7 @@ function($scope,  $q,  $routeParams,  $timeout,  egCore , egUser,  patronSvc , $
                 // we need an order-by to support paging
                 order_by : {circ : ['xact_start']} 
 
-        }).then(null, null, function(circ) {
+        }).then(deferred.resolve, null, function(circ) {
             circ.circ_lib(egCore.org.get(circ.circ_lib())); // local fleshing
 
             if (circ.target_copy().call_number().id() == -1) {
@@ -127,14 +130,23 @@ function($scope,  $q,  $routeParams,  $timeout,  egCore , egUser,  patronSvc , $
             }
 
             patronSvc.items_out.push(circ); // toss it into the cache
-            return circ;
+
+            // We fetch all circs for client-side sorting, but only
+            // notify the caller for the page of requested circs.  
+            if (rendered++ >= offset && rendered <= count)
+                deferred.notify(circ);
         });
+
+        return deferred.promise;
     }
 
     function fetch_noncat_circs(id_list, offset, count) {
         if (!id_list.length) return $q.when();
 
-        return egCore.pcrud.search('ancc', {id : id_list},
+        var deferred = $q.defer();
+        var rendered = 0;
+
+        egCore.pcrud.search('ancc', {id : id_list},
             {   flesh : 1,
                 flesh_fields : {ancc : ['item_type','staff']},
                 // TODO: LP#1697954 Fetch all circs on grid render 
@@ -145,7 +157,7 @@ function($scope,  $q,  $routeParams,  $timeout,  egCore , egUser,  patronSvc , $
                 // we need an order-by to support paging
                 order_by : {circ : ['circ_time']} 
 
-        }).then(null, null, function(noncat_circ) {
+        }).then(deferred.resolve, null, function(noncat_circ) {
 
             // calculate the virtual due date from the item type duration
             var seconds = egCore.date.intervalToSeconds(
@@ -158,8 +170,14 @@ function($scope,  $q,  $routeParams,  $timeout,  egCore , egUser,  patronSvc , $
             noncat_circ.circ_lib(egCore.org.get(noncat_circ.circ_lib()));
 
             patronSvc.items_out.push(noncat_circ); // cache it
-            return noncat_circ;
+
+            // We fetch all noncat circs for client-side sorting, but
+            // only notify the caller for the page of requested circs.  
+            if (rendered++ >= offset && rendered <= count)
+                deferred.notify(noncat_circ);
         });
+
+        return deferred.promise;
     }
 
 

commit 85a648005c0948a641b79a64d9b9029bdfc02ecf
Author: Mike Rylander <mrylander at gmail.com>
Date:   Thu Jun 22 12:09:26 2017 -0400

    LP#1697954 Notify correct page of patron holds
    
    Instead of notifying the grid on all holds, just notify when we're inside
    the current page of results.
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Bill Erickson <berickxx at gmail.com>

diff --git a/Open-ILS/web/js/ui/default/staff/circ/patron/holds.js b/Open-ILS/web/js/ui/default/staff/circ/patron/holds.js
index e2c422b..1e51cde 100644
--- a/Open-ILS/web/js/ui/default/staff/circ/patron/holds.js
+++ b/Open-ILS/web/js/ui/default/staff/circ/patron/holds.js
@@ -83,6 +83,7 @@ function($scope,  $q,  $routeParams,  egCore,  egUser,  patronSvc,
         if ($scope.holds_display == 'alt')
             method = 'open-ils.circ.holds.canceled.id_list.retrieve.authoritative';
 
+        var current = 0;
         egCore.net.request(
             'open-ils.circ', method,
             egCore.auth.token(), $scope.patron_id
@@ -92,7 +93,14 @@ function($scope,  $q,  $routeParams,  egCore,  egUser,  patronSvc,
 
             patronSvc.hold_ids = hold_ids;
             fetchHolds(offset, count)
-            .then(deferred.resolve, null, deferred.notify);
+            .then(deferred.resolve, null, function (data) {
+                if (data) {
+                    if (current >= offset && current < count) {
+                        deferred.notify(data);
+                    }
+                    current++;
+                }
+            });
         });
 
         return deferred.promise;

commit 07425b0cc1737a515af877d66fdd5f349514a2e8
Author: Bill Erickson <berickxx at gmail.com>
Date:   Wed Jun 21 12:09:37 2017 -0400

    LP#1697954 Hold details API additional fleshing
    
    * Support new flesh options in hold details retrieval API:
    
    include_current_copy
    include_usr
    include_cancel_cause
    include_requestor
    
    * Teach browser client code to use the new flesh options.  This reduces
      the number of API calls significantly for rendering holds grids.
    
    * Add debug logging to existing local-flesh calls to indicate when/if
      additional API fleshing may be needed.
    
    * Remove TODO comment about batching holds to avoid cstore exhaustion,
      which was fixed with LP#1653001.  However, leave the batching in place
      since it noticeably improves UI responsiveness, at the cost of a few
      extra API calls.
    
    Signed-off-by: Bill Erickson <berickxx at gmail.com>
    Signed-off-by: Mike Rylander <mrylander at gmail.com>

diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Holds.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Holds.pm
index 9c1ca72..a331fac 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Holds.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Holds.pm
@@ -3377,15 +3377,14 @@ sub uber_hold_impl {
     my($e, $hold_id, $args) = @_;
     $args ||= {};
 
-    my $hold = $e->retrieve_action_hold_request(
-        [
-            $hold_id,
-            {
-                flesh => 1,
-                flesh_fields => { ahr => [ 'current_copy', 'usr', 'notes' ] }
-            }
-        ]
-    ) or return $e->event;
+    my $flesh_fields = ['current_copy', 'usr', 'notes'];
+    push (@$flesh_fields, 'requestor') if $args->{include_requestor};
+    push (@$flesh_fields, 'cancel_cause') if $args->{include_cancel_cause};
+
+    my $hold = $e->retrieve_action_hold_request([
+        $hold_id,
+        {flesh => 1, flesh_fields => {ahr => $flesh_fields}}
+    ]) or return $e->event;
 
     if($hold->usr->id ne $e->requestor->id) {
         # caller is asking for someone else's hold
@@ -3405,12 +3404,13 @@ sub uber_hold_impl {
     $hold->usr($user->id);
 
 
-    my( $mvr, $volume, $copy, $issuance, $part, $bre ) = find_hold_mvr($e, $hold, $args->{suppress_mvr});
+    my( $mvr, $volume, $copy, $issuance, $part, $bre ) = find_hold_mvr($e, $hold, $args);
 
     flesh_hold_notices([$hold], $e) unless $args->{suppress_notices};
     flesh_hold_transits([$hold]) unless $args->{suppress_transits};
 
     my $details = retrieve_hold_queue_status_impl($e, $hold);
+    $hold->usr($user) if $args->{include_usr}; # re-flesh
 
     my $resp = {
         hold    => $hold,
@@ -3446,13 +3446,14 @@ sub uber_hold_impl {
 # hold is all about
 # -----------------------------------------------------
 sub find_hold_mvr {
-    my( $e, $hold, $no_mvr ) = @_;
+    my( $e, $hold, $args ) = @_;
 
     my $tid;
     my $copy;
     my $volume;
     my $issuance;
     my $part;
+    my $no_mvr = $args->{suppress_mvr};
 
     if( $hold->hold_type eq OILS_HOLD_TYPE_METARECORD ) {
         my $mr = $e->retrieve_metabib_metarecord($hold->target)
@@ -3494,7 +3495,7 @@ sub find_hold_mvr {
 
     if(!$copy and ref $hold->current_copy ) {
         $copy = $hold->current_copy;
-        $hold->current_copy($copy->id);
+        $hold->current_copy($copy->id) unless $args->{include_current_copy};
     }
 
     if(!$volume and $copy) {
diff --git a/Open-ILS/web/js/ui/default/staff/circ/services/holds.js b/Open-ILS/web/js/ui/default/staff/circ/services/holds.js
index ab0b07d..53cd39c 100644
--- a/Open-ILS/web/js/ui/default/staff/circ/services/holds.js
+++ b/Open-ILS/web/js/ui/default/staff/circ/services/holds.js
@@ -14,11 +14,7 @@ function($uibModal , $q , egCore , egConfirmDialog , egAlertDialog) {
     service.fetch_holds = function(hold_ids) {
         var deferred = $q.defer();
 
-        // FIXME: large batches using .authoritative result in many 
-        // stranded cstore backends on the server.  Needs investigation.
-        // For now, collect holds in a series of small batches.
-        // Fetch them serially both to avoid the above problem and
-        // to maintain order.
+        // Fetch hold details in batches for better UI responsiveness.
         var batch_size = 5;
         var index = 0;
 
@@ -37,7 +33,12 @@ function($uibModal , $q , egCore , egConfirmDialog , egAlertDialog) {
             egCore.net.request(
                 'open-ils.circ',
                 'open-ils.circ.hold.details.batch.retrieve.authoritative',
-                egCore.auth.token(), ids
+                egCore.auth.token(), ids, {
+                    include_current_copy : true,
+                    include_usr          : true,
+                    include_cancel_cause : true,
+                    include_requestor    : true
+                }
 
             ).then(
                 one_batch,  // kick off the next batch
@@ -452,14 +453,23 @@ function($uibModal , $q , egCore , egConfirmDialog , egAlertDialog) {
         hold.current_shelf_lib(egCore.org.get(hold.current_shelf_lib()));
         hold_data.id = hold.id();
 
-        if (hold.requestor() && typeof hold.requestor() != 'object')
+        // TODO: LP#1697954 fleshing calls below are deprecated in favor
+        // of API fleshing.
+
+        if (hold.requestor() && typeof hold.requestor() != 'object') {
+            console.debug('fetching hold requestor');
             egCore.pcrud.retrieve('au',hold.requestor()).then(function(u) { hold.requestor(u) });
+        }
 
-        if (hold.cancel_cause() && typeof hold.cancel_cause() != 'object')
+        if (hold.cancel_cause() && typeof hold.cancel_cause() != 'object') {
+            console.debug('fetching hold cancel cause');
             egCore.pcrud.retrieve('ahrcc',hold.cancel_cause()).then(function(c) { hold.cancel_cause(c) });
+        }
 
-        if (hold.usr() && typeof hold.usr() != 'object')
+        if (hold.usr() && typeof hold.usr() != 'object') {
+            console.debug('fetching hold user');
             egCore.pcrud.retrieve('au',hold.usr()).then(function(u) { hold.usr(u) });
+        }
 
         // current_copy is not always fleshed in the API
         if (hold.current_copy() && typeof hold.current_copy() != 'object') {
@@ -621,8 +631,12 @@ function($window , $location , $timeout , egCore , egHolds , egCirc) {
                     egCore.net.request(
                         'open-ils.circ',
                         'open-ils.circ.hold.details.retrieve.authoritative',
-                        egCore.auth.token(), $scope.holdId
-
+                        egCore.auth.token(), $scope.holdId, {
+                            include_current_copy : true,
+                            include_usr          : true,
+                            include_cancel_cause : true,
+                            include_requestor    : true
+                        }
                     ).then(function(hold_data) { 
                         egHolds.local_flesh(hold_data);
     

commit 63cebb9dcdb960d754322a4aad810d351e1f4a84
Author: Bill Erickson <berickxx at gmail.com>
Date:   Wed Jun 21 11:35:15 2017 -0400

    LP#1697954 TODO comments for client sort all-fetching
    
    Add additional code comments further clarifying why some grids pre-fetch
    all rows (for client-side sorting) instead of fetching in pages.
    
    Signed-off-by: Bill Erickson <berickxx at gmail.com>
    Signed-off-by: Mike Rylander <mrylander at gmail.com>

diff --git a/Open-ILS/web/js/ui/default/staff/circ/patron/holds.js b/Open-ILS/web/js/ui/default/staff/circ/patron/holds.js
index 4013bc7..e2c422b 100644
--- a/Open-ILS/web/js/ui/default/staff/circ/patron/holds.js
+++ b/Open-ILS/web/js/ui/default/staff/circ/patron/holds.js
@@ -50,7 +50,12 @@ function($scope,  $q,  $routeParams,  egCore,  egUser,  patronSvc,
     $scope.gridDataProvider = provider;
 
     function fetchHolds(offset, count) {
-        //var ids = patronSvc.hold_ids.slice(offset, offset + count); // we're going to just fetch all the holds up front
+        // TODO: LP#1697954 Fetch all holds on grid render to support
+        // client-side sorting.  Migrate to server-side sorting to avoid
+        // the need for fetching all items.
+
+        // we're going to just fetch all the holds up front
+        //var ids = patronSvc.hold_ids.slice(offset, offset + count); 
         return egHolds.fetch_holds(patronSvc.hold_ids).then(null, null,
             function(hold_data) { 
                 patronSvc.holds.push(hold_data);
diff --git a/Open-ILS/web/js/ui/default/staff/circ/patron/items_out.js b/Open-ILS/web/js/ui/default/staff/circ/patron/items_out.js
index 94bc0f6..449f190 100644
--- a/Open-ILS/web/js/ui/default/staff/circ/patron/items_out.js
+++ b/Open-ILS/web/js/ui/default/staff/circ/patron/items_out.js
@@ -106,6 +106,9 @@ function($scope,  $q,  $routeParams,  $timeout,  egCore , egUser,  patronSvc , $
                 // fields on the bre to select.  More may be needed.
                 // note that fleshed fields are explicitly selected.
                 select : { bre : ['id'] },
+                // TODO: LP#1697954 Fetch all circs on grid render 
+                // to support client-side sorting.  Migrate to server-side
+                // sorting to avoid the need for fetching all items.
                 //limit  : count,
                 //offset : offset,
                 // we need an order-by to support paging
@@ -134,6 +137,9 @@ function($scope,  $q,  $routeParams,  $timeout,  egCore , egUser,  patronSvc , $
         return egCore.pcrud.search('ancc', {id : id_list},
             {   flesh : 1,
                 flesh_fields : {ancc : ['item_type','staff']},
+                // TODO: LP#1697954 Fetch all circs on grid render 
+                // to support client-side sorting.  Migrate to server-side
+                // sorting to avoid the need for fetching all items.
                 //limit  : count,
                 //offset : offset,
                 // we need an order-by to support paging

commit dc038b64a9d32ac0d2c631cda8aa6b2926660c42
Author: Mike Rylander <mrylander at gmail.com>
Date:   Wed Jun 14 11:53:11 2017 -0400

    LP#1697954: Enable clientsort for user items out lists
    
    These will generally be small, so we'll fetch all the data to support client-
    side sorting.
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Andrea Neiman <abneiman at equinoxinitiative.org>
    Signed-off-by: Bill Erickson <berickxx at gmail.com>

diff --git a/Open-ILS/src/templates/staff/circ/patron/t_items_out.tt2 b/Open-ILS/src/templates/staff/circ/patron/t_items_out.tt2
index f7b4020..c6b6e62 100644
--- a/Open-ILS/src/templates/staff/circ/patron/t_items_out.tt2
+++ b/Open-ILS/src/templates/staff/circ/patron/t_items_out.tt2
@@ -29,7 +29,7 @@
   ng-if="items_out_display == 'noncat'"
   idl-class="ancc"
   id-field="id"
-  features="-sort,-multisort"
+  features="clientsort"
   items-provider="gridDataProvider"
   persist-key="circ.patron.items_out.noncat"
   dateformat="{{$root.egDateAndTimeFormat}}">
@@ -46,7 +46,7 @@
   ng-if="items_out_display != 'noncat'"
   idl-class="circ"
   id-field="id"
-  features="-sort,-multisort"
+  features="clientsort"
   items-provider="gridDataProvider"
   persist-key="circ.patron.items_out"
   dateformat="{{$root.egDateAndTimeFormat}}">
@@ -86,7 +86,7 @@
   <eg-grid-field label="[% l('Checkout / Renewal Library') %]" path='circ_lib.shortname'></eg-grid-field>
   <eg-grid-field label="[% l('Renewals Remaining') %]" path='renewal_remaining'></eg-grid-field>
   <eg-grid-field label="[% l('Fines Stopped') %]" path='stop_fines'></eg-grid-field>
-  <eg-grid-field label="[% l('Title') %]" name="title">
+  <eg-grid-field label="[% l('Title') %]" path="target_copy.call_number.record.simple_record.title" name="title">
     <a target="_self" href="[% ctx.base_path %]/staff/cat/catalog/record/{{item.target_copy().call_number().record().id()}}">
       {{item.target_copy().call_number().record().simple_record().title()}}
     </a>
diff --git a/Open-ILS/web/js/ui/default/staff/circ/patron/items_out.js b/Open-ILS/web/js/ui/default/staff/circ/patron/items_out.js
index eaeb4b4..94bc0f6 100644
--- a/Open-ILS/web/js/ui/default/staff/circ/patron/items_out.js
+++ b/Open-ILS/web/js/ui/default/staff/circ/patron/items_out.js
@@ -106,8 +106,8 @@ function($scope,  $q,  $routeParams,  $timeout,  egCore , egUser,  patronSvc , $
                 // fields on the bre to select.  More may be needed.
                 // note that fleshed fields are explicitly selected.
                 select : { bre : ['id'] },
-                limit  : count,
-                offset : offset,
+                //limit  : count,
+                //offset : offset,
                 // we need an order-by to support paging
                 order_by : {circ : ['xact_start']} 
 
@@ -134,8 +134,8 @@ function($scope,  $q,  $routeParams,  $timeout,  egCore , egUser,  patronSvc , $
         return egCore.pcrud.search('ancc', {id : id_list},
             {   flesh : 1,
                 flesh_fields : {ancc : ['item_type','staff']},
-                limit  : count,
-                offset : offset,
+                //limit  : count,
+                //offset : offset,
                 // we need an order-by to support paging
                 order_by : {circ : ['circ_time']} 
 

commit 23483d848a9869284b6584e37136fb0c5e7ca757
Author: Mike Rylander <mrylander at gmail.com>
Date:   Wed Jun 14 11:51:53 2017 -0400

    LP#1697954: Enable clientsort for user holds lists
    
    These will generally be small, so we'll fetch all the data to support client-
    side sorting.
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Andrea Neiman <abneiman at equinoxinitiative.org>
    Signed-off-by: Bill Erickson <berickxx at gmail.com>

diff --git a/Open-ILS/src/templates/staff/circ/patron/t_holds_list.tt2 b/Open-ILS/src/templates/staff/circ/patron/t_holds_list.tt2
index 665ca04..5fa3b96 100644
--- a/Open-ILS/src/templates/staff/circ/patron/t_holds_list.tt2
+++ b/Open-ILS/src/templates/staff/circ/patron/t_holds_list.tt2
@@ -1,6 +1,6 @@
 <eg-grid
   id-field="id"
-  features="-sort,-multisort"
+  features="clientsort"
   items-provider="gridDataProvider"
   persist-key="circ.patron.holds"
   dateformat="{{$root.egDateAndTimeFormat}}">
@@ -53,8 +53,8 @@
     </a>
   </eg-grid-field>
 
-  <eg-grid-field label="[% l('Patron Barcode') %]" hidden>{{item.patron_barcode}}</eg-grid-field>
-  <eg-grid-field label="[% l('Patron alias') %]" hidden>{{item.patron_alias}}</eg-grid-field>
+  <eg-grid-field label="[% l('Patron Barcode') %]" path="patron_barcode" hidden>{{item.patron_barcode}}</eg-grid-field>
+  <eg-grid-field label="[% l('Patron alias') %]" path="patron_alias" hidden>{{item.patron_alias}}</eg-grid-field>
   <eg-grid-field label="[% l('Request Date') %]" path='hold.request_time' datatype="timestamp"></eg-grid-field>
   <eg-grid-field label="[% l('Capture Date') %]" path='hold.capture_time' datatype="timestamp"></eg-grid-field>
   <eg-grid-field label="[% l('Available Date') %]" path='hold.shelf_time' datatype="timestamp"></eg-grid-field>
diff --git a/Open-ILS/web/js/ui/default/staff/circ/patron/holds.js b/Open-ILS/web/js/ui/default/staff/circ/patron/holds.js
index ddbf1d8..4013bc7 100644
--- a/Open-ILS/web/js/ui/default/staff/circ/patron/holds.js
+++ b/Open-ILS/web/js/ui/default/staff/circ/patron/holds.js
@@ -50,8 +50,8 @@ function($scope,  $q,  $routeParams,  egCore,  egUser,  patronSvc,
     $scope.gridDataProvider = provider;
 
     function fetchHolds(offset, count) {
-        var ids = patronSvc.hold_ids.slice(offset, offset + count);
-        return egHolds.fetch_holds(ids).then(null, null,
+        //var ids = patronSvc.hold_ids.slice(offset, offset + count); // we're going to just fetch all the holds up front
+        return egHolds.fetch_holds(patronSvc.hold_ids).then(null, null,
             function(hold_data) { 
                 patronSvc.holds.push(hold_data);
                 return hold_data;

commit f9cac2940e4f5c6fec9506119017e8e8c332d1e6
Author: Mike Rylander <mrylander at gmail.com>
Date:   Wed Jun 14 11:51:24 2017 -0400

    LP#1697954: Enable clientsort for checkout
    
    This list is filled by the user, so it's safe to use client-side sorting.
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Andrea Neiman <abneiman at equinoxinitiative.org>
    Signed-off-by: Bill Erickson <berickxx at gmail.com>

diff --git a/Open-ILS/src/templates/staff/circ/patron/t_checkout.tt2 b/Open-ILS/src/templates/staff/circ/patron/t_checkout.tt2
index 1abdf45..3210a53 100644
--- a/Open-ILS/src/templates/staff/circ/patron/t_checkout.tt2
+++ b/Open-ILS/src/templates/staff/circ/patron/t_checkout.tt2
@@ -59,7 +59,7 @@
 
 <eg-grid
   id-field="index"
-  features="-sort,-multisort"
+  features="clientsort"
   items-provider="gridDataProvider"
   grid-controls="gridControls"
   persist-key="circ.patron.checkout"

commit c5c5f878d3f15b04475ce5f76a844b78953ce1a5
Author: Mike Rylander <mrylander at gmail.com>
Date:   Wed Jun 14 12:07:52 2017 -0400

    LP#1697954: Provide custom comparator for sorting money on renew
    
    mbts.balance_owed often arrives as a string, so we provide here a custom
    comparator function that runs the values through parseFloat() before comparing
    them.
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Andrea Neiman <abneiman at equinoxinitiative.org>
    Signed-off-by: Bill Erickson <berickxx at gmail.com>

diff --git a/Open-ILS/src/templates/staff/circ/renew/t_renew.tt2 b/Open-ILS/src/templates/staff/circ/renew/t_renew.tt2
index 9678176..7b0fdb7 100644
--- a/Open-ILS/src/templates/staff/circ/renew/t_renew.tt2
+++ b/Open-ILS/src/templates/staff/circ/renew/t_renew.tt2
@@ -72,7 +72,7 @@
     path="acp.alert_message"></eg-grid-field>
 
   <eg-grid-field label="[% l('Balance Owed') %]"     
-    path='mbts.balance_owed'></eg-grid-field>
+    path='mbts.balance_owed' comparator="sort_money"></eg-grid-field>
 
   <eg-grid-field label="[% l('Barcode') %]" path="copy_barcode">
     <!-- FIXME: ng-if / ng-disabled not working since the contents 
diff --git a/Open-ILS/web/js/ui/default/staff/circ/renew/app.js b/Open-ILS/web/js/ui/default/staff/circ/renew/app.js
index 85ed294..bb20b98 100644
--- a/Open-ILS/web/js/ui/default/staff/circ/renew/app.js
+++ b/Open-ILS/web/js/ui/default/staff/circ/renew/app.js
@@ -40,6 +40,14 @@ function($scope , $window , $location , egCore , egGridDataProvider , egCirc) {
     var today = new Date();
     $scope.renewalArgs = {due_date : today};
 
+    $scope.sort_money = function (a,b) {
+        var ma = parseFloat(a);
+        var mb = parseFloat(b);
+        if (ma < mb) return -1;
+        if (ma > mb) return 1;
+        return 0
+    }
+
     $scope.gridDataProvider = egGridDataProvider.instance({
         get : function(offset, count) {
             return this.arrayNotifier($scope.renewals, offset, count);

commit 1e0ff6f2b91293e80588cb4843b0911a5c85953f
Author: Mike Rylander <mrylander at gmail.com>
Date:   Wed Jun 14 11:50:52 2017 -0400

    LP#1697954: Enable clientsort for renew
    
    This list is filled by the user, so it's safe to use client-side sorting.
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Andrea Neiman <abneiman at equinoxinitiative.org>
    Signed-off-by: Bill Erickson <berickxx at gmail.com>

diff --git a/Open-ILS/src/templates/staff/circ/renew/t_renew.tt2 b/Open-ILS/src/templates/staff/circ/renew/t_renew.tt2
index 2a7871e..9678176 100644
--- a/Open-ILS/src/templates/staff/circ/renew/t_renew.tt2
+++ b/Open-ILS/src/templates/staff/circ/renew/t_renew.tt2
@@ -42,7 +42,7 @@
 
 <eg-grid
   id-field="index"
-  features="-sort,-multisort"
+  features="clientsort"
   items-provider="gridDataProvider"
   grid-controls="gridControls"
   persist-key="circ.renew"
@@ -74,7 +74,7 @@
   <eg-grid-field label="[% l('Balance Owed') %]"     
     path='mbts.balance_owed'></eg-grid-field>
 
-  <eg-grid-field label="[% l('Barcode') %]" path="acp_barcode">
+  <eg-grid-field label="[% l('Barcode') %]" path="copy_barcode">
     <!-- FIXME: ng-if / ng-disabled not working since the contents 
         are $interpolate'd and not $compile'd.
         I want to hide / disable the href when there is no acp ID 

commit 70e126cd0121c1de2246bf6f51be7c772d8a7e06
Author: Mike Rylander <mrylander at gmail.com>
Date:   Wed Jun 14 11:50:08 2017 -0400

    LP#1697954: Enable clientsort for pending patrons
    
    This list always retreives all data, so it's safe to use client-side sorting.
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Andrea Neiman <abneiman at equinoxinitiative.org>
    Signed-off-by: Bill Erickson <berickxx at gmail.com>

diff --git a/Open-ILS/src/templates/staff/circ/patron/t_pending_list.tt2 b/Open-ILS/src/templates/staff/circ/patron/t_pending_list.tt2
index a5510c1..b073b8c 100644
--- a/Open-ILS/src/templates/staff/circ/patron/t_pending_list.tt2
+++ b/Open-ILS/src/templates/staff/circ/patron/t_pending_list.tt2
@@ -10,7 +10,7 @@
 
 <eg-grid
   id-field="id"
-  features="-sort,-multisort"
+  features="clientsort"
   items-provider="grid_data_provider"
   grid-controls="grid_controls"
   persist-key="circ.pending_patrons.list"

commit dac1016c777c821b455f9be34e093a1441a52326
Author: Mike Rylander <mrylander at gmail.com>
Date:   Wed Jun 14 12:11:27 2017 -0400

    LP#1697954: Provide custom comparator for sorting money on checkin
    
    mbts.balance_owed often arrives as a string, so we provide here a custom
    comparator function that runs the values through parseFloat() before comparing
    them.
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Andrea Neiman <abneiman at equinoxinitiative.org>
    Signed-off-by: Bill Erickson <berickxx at gmail.com>

diff --git a/Open-ILS/src/templates/staff/circ/checkin/t_checkin_table.tt2 b/Open-ILS/src/templates/staff/circ/checkin/t_checkin_table.tt2
index 5c6268a..920ee2b 100644
--- a/Open-ILS/src/templates/staff/circ/checkin/t_checkin_table.tt2
+++ b/Open-ILS/src/templates/staff/circ/checkin/t_checkin_table.tt2
@@ -30,7 +30,7 @@
     path="acp.alert_message"></eg-grid-field>
 
   <eg-grid-field label="[% l('Balance Owed') %]"     
-    path='mbts.balance_owed'></eg-grid-field>
+    path='mbts.balance_owed' comparator="sort_money"></eg-grid-field>
 
   <eg-grid-field label="[% l('Barcode') %]" path="copy_barcode">
     <!-- FIXME: ng-if / ng-disabled not working since the contents 
diff --git a/Open-ILS/web/js/ui/default/staff/circ/checkin/app.js b/Open-ILS/web/js/ui/default/staff/circ/checkin/app.js
index a9b70ca..099b1be 100644
--- a/Open-ILS/web/js/ui/default/staff/circ/checkin/app.js
+++ b/Open-ILS/web/js/ui/default/staff/circ/checkin/app.js
@@ -58,6 +58,14 @@ function($scope , $q , $window , $location , egCore , checkinSvc , egGridDataPro
         suppress_popups = set['ui.circ.suppress_checkin_popups'];
     });
 
+    $scope.sort_money = function (a,b) {
+        var ma = parseFloat(a);
+        var mb = parseFloat(b);
+        if (ma < mb) return -1;
+        if (ma > mb) return 1;
+        return 0
+    }
+
     // checkin & hold capture modifiers
     var modifiers = [
         'void_overdues', 

commit 26352c64f78e45ee7be09439f40e03a31bbc67f9
Author: Mike Rylander <mrylander at gmail.com>
Date:   Wed Jun 14 11:49:12 2017 -0400

    LP#1697954: Enable clientsort for checkin
    
    This list is filled by the user, so it's safe to use client-side sorting.
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Andrea Neiman <abneiman at equinoxinitiative.org>
    Signed-off-by: Bill Erickson <berickxx at gmail.com>

diff --git a/Open-ILS/src/templates/staff/circ/checkin/t_checkin_table.tt2 b/Open-ILS/src/templates/staff/circ/checkin/t_checkin_table.tt2
index e7d809b..5c6268a 100644
--- a/Open-ILS/src/templates/staff/circ/checkin/t_checkin_table.tt2
+++ b/Open-ILS/src/templates/staff/circ/checkin/t_checkin_table.tt2
@@ -2,7 +2,7 @@
 
 <eg-grid
   id-field="index"
-  features="-sort,-multisort"
+  features="clientsort"
   main-label="[% l('Items Checked In') %]"
   items-provider="gridDataProvider"
   grid-controls="gridControls"
@@ -32,7 +32,7 @@
   <eg-grid-field label="[% l('Balance Owed') %]"     
     path='mbts.balance_owed'></eg-grid-field>
 
-  <eg-grid-field label="[% l('Barcode') %]" path="acp_barcode">
+  <eg-grid-field label="[% l('Barcode') %]" path="copy_barcode">
     <!-- FIXME: ng-if / ng-disabled not working since the contents 
         are $interpolate'd and not $compile'd.
         I want to hide / disable the href when there is no acp ID 

commit c1f3bd316785d9f68a20f49943129649ee113928
Author: Mike Rylander <mrylander at gmail.com>
Date:   Wed Jun 14 11:47:48 2017 -0400

    LP#1697954: Enable clientsort for item status list
    
    This list is filled by the user, so it's safe to use client-side sorting.
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Andrea Neiman <abneiman at equinoxinitiative.org>
    Signed-off-by: Bill Erickson <berickxx at gmail.com>

diff --git a/Open-ILS/src/templates/staff/cat/item/t_list.tt2 b/Open-ILS/src/templates/staff/cat/item/t_list.tt2
index 176527c..a481d0d 100644
--- a/Open-ILS/src/templates/staff/cat/item/t_list.tt2
+++ b/Open-ILS/src/templates/staff/cat/item/t_list.tt2
@@ -1,7 +1,7 @@
 <eg-grid
   id-field="index"
   idl-class="acp"
-  features="-display,-sort,-multisort"
+  features="-display,clientsort"
   main-label="[% l('Item Status') %]"
   items-provider="gridDataProvider"
   grid-controls="gridControls"

commit 520215937726cba99ab6aeb8c16e689b2c3e0dd5
Author: Mike Rylander <mrylander at gmail.com>
Date:   Wed Jun 14 11:32:36 2017 -0400

    LP#1697954: Provide client-side sorting for grids that can use it
    
    There are several grids (items out, checkin, checkout, item status, etc) that
    could benefit from the ability to sort their items, but either the data
    provider uses a complex data structure or an API call that doesn't offer
    sorting, or the item list is populated by user input rather than a call to the
    server.  In those cases, sorting is not available.  However, if we know that
    all the data in the grid is in client memory, it would be reasonable to offer
    a client-side sort option.
    
    This commit does that by teaching the grid to accept a "clientsort" feature
    and teaching arrayNotifier how to sort the items currently stored.  The sort
    works over any mix of IDL objects, hashes, and flattened fields, supports
    multisort, and pushes "nulls" to the end of the list.
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Andrea Neiman <abneiman at equinoxinitiative.org>
    Signed-off-by: Bill Erickson <berickxx at gmail.com>

diff --git a/Open-ILS/web/js/ui/default/staff/services/grid.js b/Open-ILS/web/js/ui/default/staff/services/grid.js
index 5fe4355..96c4a9e 100644
--- a/Open-ILS/web/js/ui/default/staff/services/grid.js
+++ b/Open-ILS/web/js/ui/default/staff/services/grid.js
@@ -179,6 +179,7 @@ angular.module('egGridMod',
 
                 grid.columnsProvider = egGridColumnsProvider.instance({
                     idlClass : grid.idlClass,
+                    clientSort : (features.indexOf('clientsort') > -1 && features.indexOf('-clientsort') == -1),
                     defaultToHidden : (features.indexOf('-display') > -1),
                     defaultToNoSort : (features.indexOf('-sort') > -1),
                     defaultToNoMultiSort : (features.indexOf('-multisort') > -1),
@@ -210,6 +211,8 @@ angular.module('egGridMod',
                     });
                 }
 
+                grid.dataProvider.columnsProvider = grid.columnsProvider;
+
                 $scope.itemFieldValue = grid.dataProvider.itemFieldValue;
                 $scope.indexValue = function(item) {
                     return grid.indexValue(item)
@@ -1082,6 +1085,7 @@ angular.module('egGridMod',
         restrict : 'AE',
         scope : {
             flesher: '=', // optional; function that can flesh a linked field, given the value
+            comparator: '=', // optional; function that can sort the thing at the end of 'path' 
             name  : '@', // required; unique name
             path  : '@', // optional; flesh path
             ignore: '@', // optional; fields to ignore when path is a wildcard
@@ -1170,6 +1174,7 @@ angular.module('egGridMod',
         cols.columns = [];
         cols.stockVisible = [];
         cols.idlClass = args.idlClass;
+        cols.clientSort = args.clientSort;
         cols.defaultToHidden = args.defaultToHidden;
         cols.defaultToNoSort = args.defaultToNoSort;
         cols.defaultToNoMultiSort = args.defaultToNoMultiSort;
@@ -1362,6 +1367,7 @@ angular.module('egGridMod',
         cols.cloneFromScope = function(colSpec) {
             return {
                 flesher  : colSpec.flesher,
+                comparator  : colSpec.comparator,
                 name  : colSpec.name,
                 label : colSpec.label,
                 path  : colSpec.path,
@@ -1520,6 +1526,81 @@ angular.module('egGridMod',
             // the range defined by count and offset
             gridData.arrayNotifier = function(arr, offset, count) {
                 if (!arr || arr.length == 0) return $q.when();
+
+                if (gridData.columnsProvider.clientSort
+                    && gridData.sort
+                    && gridData.sort.length > 0
+                ) {
+                    var sorter_cache = [];
+                    arr.sort(function(a,b) {
+                        for (var si = 0; si < gridData.sort.length; si++) {
+                            if (!sorter_cache[si]) { // Build sort structure on first comparison, reuse thereafter
+                                var field = gridData.sort[si];
+                                var dir = 'asc';
+
+                                if (angular.isObject(field)) {
+                                    dir = Object.values(field)[0];
+                                    field = Object.keys(field)[0];
+                                }
+
+                                var path = gridData.columnsProvider.findColumn(field).path || field;
+                                var comparator = gridData.columnsProvider.findColumn(field).comparator ||
+                                    function (x,y) { if (x < y) return -1; if (x > y) return 1; return 0 };
+
+                                sorter_cache[si] = {
+                                    field       : path,
+                                    dir         : dir,
+                                    comparator  : comparator
+                                };
+                            }
+
+                            var sc = sorter_cache[si];
+
+                            var af,bf;
+
+                            if (a._isfieldmapper || angular.isFunction(a[sc.field])) {
+                                try {af = a[sc.field](); bf = b[sc.field]() } catch (e) {};
+                            } else {
+                                af = a[sc.field]; bf = b[sc.field];
+                            }
+                            if (af === undefined && sc.field.indexOf('.') > -1) { // assume an object, not flat path
+                                var parts = sc.field.split('.');
+                                af = a;
+                                bf = b;
+                                angular.forEach(parts, function (p) {
+                                    if (af) {
+                                        if (af._isfieldmapper || angular.isFunction(af[p])) af = af[p]();
+                                        else af = af[p];
+                                    }
+                                    if (bf) {
+                                        if (bf._isfieldmapper || angular.isFunction(bf[p])) bf = bf[p]();
+                                        else bf = bf[p];
+                                    }
+                                });
+                            }
+
+                            if (af === undefined) af = null;
+                            if (bf === undefined) bf = null;
+
+                            if (af === null && bf !== null) return 1;
+                            if (bf === null && af !== null) return -1;
+
+                            if (!(bf === null && af === null)) {
+                                var partial = sc.comparator(af,bf);
+                                if (partial) {
+                                    if (sc.dir == 'desc') {
+                                        if (partial > 0) return -1;
+                                        return 1;
+                                    }
+                                    return partial;
+                                }
+                            }
+                        }
+
+                        return 0;
+                    });
+                }
+
                 if (count) arr = arr.slice(offset, offset + count);
                 var def = $q.defer();
                 // promise notifications are only witnessed when delivered

-----------------------------------------------------------------------

Summary of changes:
 .../perlmods/lib/OpenILS/Application/Circ/Holds.pm |   25 +++---
 Open-ILS/src/templates/staff/cat/item/t_list.tt2   |    2 +-
 .../staff/circ/checkin/t_checkin_table.tt2         |    6 +-
 .../src/templates/staff/circ/patron/t_checkout.tt2 |    2 +-
 .../templates/staff/circ/patron/t_holds_list.tt2   |    6 +-
 .../templates/staff/circ/patron/t_items_out.tt2    |   10 +-
 .../templates/staff/circ/patron/t_pending_list.tt2 |    2 +-
 .../src/templates/staff/circ/renew/t_renew.tt2     |    6 +-
 .../web/js/ui/default/staff/circ/checkin/app.js    |    8 ++
 .../web/js/ui/default/staff/circ/patron/holds.js   |   19 ++++-
 .../js/ui/default/staff/circ/patron/items_out.js   |   62 +++++++++++----
 Open-ILS/web/js/ui/default/staff/circ/renew/app.js |    8 ++
 .../web/js/ui/default/staff/circ/services/holds.js |   36 ++++++---
 Open-ILS/web/js/ui/default/staff/services/grid.js  |   81 ++++++++++++++++++++
 14 files changed, 214 insertions(+), 59 deletions(-)


hooks/post-receive
-- 
Evergreen ILS




More information about the open-ils-commits mailing list