From: Galen Charlton Date: Wed, 3 Jul 2019 21:53:01 +0000 (-0400) Subject: LP#1777207: teach egGrid how to prepend rows more efficiently X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=59f9d4d7d836b3db37ad5a83fb5573b5934dc9c6;p=working%2FEvergreen.git LP#1777207: teach egGrid how to prepend rows more efficiently The checkin and checkout grids in the AngularJS client have been doing full grid refreshes when adding a checkin or checkout to their respective grids. While this does not result in re-fetching data for the loans that were already processed, as more entries get added to the grid the time it takes to do a full digest of the grid contents during a egGrid.collect() (which empties the list of displayed rows, then refills it), gets progressively longer. Grids that have only ~40 entries have been observed to take several seconds purely on the AngularJS rendering phase. This patch teaches egGrid a new prepend() method that takes the first element from the underlying data source and unshifts it onto the list of displayed grid rows, saving much rendering time. The prepend() method will also force the grid offset back to 0 if it isn't already. Signed-off-by: Galen Charlton --- 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 6d71f6c6dd..965529b4c5 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 @@ -233,9 +233,13 @@ function($scope , $q , $window , $location , $timeout , egCore , checkinSvc , eg {already_checked_in : final_resp.evt.copy_barcode}; } - if ($scope.trim_list && checkinSvc.checkins.length > 20) + if ($scope.trim_list && checkinSvc.checkins.length > 20) { //cut array short at 20 items checkinSvc.checkins.length = 20; + checkinGrid.prepend(20); + } else { + checkinGrid.prepend(); + } }, function() { // Checkin was rejected somewhere along the way. @@ -249,9 +253,7 @@ function($scope , $q , $window , $location , $timeout , egCore , checkinSvc , eg checkinSvc.checkins.splice(pos, 1); })['finally'](function() { - - // when all is said and done, refresh the grid and refocus - checkinGrid.refresh(); + // when all is said and done, refocus $scope.focusMe = true; }); } diff --git a/Open-ILS/web/js/ui/default/staff/circ/patron/checkout.js b/Open-ILS/web/js/ui/default/staff/circ/patron/checkout.js index f3df2d8ace..d79811c705 100644 --- a/Open-ILS/web/js/ui/default/staff/circ/patron/checkout.js +++ b/Open-ILS/web/js/ui/default/staff/circ/patron/checkout.js @@ -189,7 +189,7 @@ function($scope , $q , $routeParams , egCore , egUser , patronSvc , }; $scope.checkouts.unshift(row_item); - $scope.gridDataProvider.refresh(); + $scope.gridDataProvider.prepend(); egCore.hatch.setItem('circ.checkout.strict_barcode', $scope.strict_barcode); var options = {check_barcode : $scope.strict_barcode}; 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 9ee646a47c..a12e47bb25 100644 --- a/Open-ILS/web/js/ui/default/staff/services/grid.js +++ b/Open-ILS/web/js/ui/default/staff/services/grid.js @@ -339,6 +339,10 @@ angular.module('egGridMod', grid.collect(); } + controls.prepend = function(limit) { + grid.prepend(limit); + } + controls.setLimit = function(limit,forget) { grid.limit = limit; if (!forget && grid.persistKey) { @@ -360,6 +364,7 @@ angular.module('egGridMod', } grid.dataProvider.refresh = controls.refresh; + grid.dataProvider.prepend = controls.prepend; grid.controls = controls; } @@ -1322,6 +1327,45 @@ angular.module('egGridMod', }); } + grid.prepend = function(limit) { + if (grid.offset > 0) { + // if we're prepending, we're forcing the + // offset back to zero to display the top + // of the list + grid.offset = 0; + grid.collect(); + return; + } + if (grid.collecting) return; // avoid parallel collect() or prepend() + grid.collecting = true; + console.debug('egGrid.prepend() starting'); + grid.dataProvider.get(0, 1).then( + null, + null, + function(item) { + if (item) { + $scope.items.unshift(item); + if (limit && $scope.items.length > limit) { + // this accommodates the checkin grid that + // allows the user to set a definite limit + // without requiring that entire collect() + $scope.items.length = limit; + } + if ($scope.items.length > grid.limit) { + $scope.items.length = grid.limit; + } + if (grid.controls.itemRetrieved) + grid.controls.itemRetrieved(item); + if ($scope.selectAll) + $scope.selected[grid.indexValue(item)] = true + } + }).finally(function() { + console.debug('egGrid.prepend() complete'); + grid.collecting = false; + $scope.selected = angular.copy($scope.selected); + }); + } + grid.init(); }] }; @@ -1912,6 +1956,7 @@ angular.module('egGridMod', // Calls the grid refresh function. Once instantiated, the // grid will replace this function with it's own refresh() gridData.refresh = function(noReset) { } + gridData.prepend = function(limit) { } if (!gridData.get) { // returns a promise whose notify() delivers items