LP1821094: Improve item status reload performance
authorJane Sandberg <sandbej@linnbenton.edu>
Sun, 28 Apr 2019 17:57:30 +0000 (13:57 -0400)
committerJane Sandberg <sandbej@linnbenton.edu>
Thu, 30 Jan 2020 17:31:27 +0000 (09:31 -0800)
To test:
1) Create a file with 500 or more item barcodes.
2) Load your file into Item Status.
3) Select a few rows.
4) Go to Actions > Edit > Items.
5) Make some changes, then Save and Exit.
6) Time how long it takes between clicking
"Save and Exit" and when the grid actually
refreshes.
7) Repeat steps 2-6, but use Actions > Edit
> Call Numbers instead.
8) Apply this commit.
9) Repeat steps 2-7. The time should be much
faster with this commit.
10) Verify that no columns lose their data
when refreshed, especially monograph parts
and in-house use count.
11) Note that there is also a progress bar.

Signed-off-by: Jane Sandberg <sandbej@linnbenton.edu>
Signed-off-by: Kyle Huckins <khuckins@catalyte.io>
Open-ILS/web/js/ui/default/staff/cat/item/app.js
Open-ILS/web/js/ui/default/staff/circ/services/item.js

index 52d2d02..fd82c77 100644 (file)
@@ -469,19 +469,36 @@ function($scope , $q , $window , $location , $timeout , egCore , egNet , egGridD
         return cp_id_list;
     }
 
-    $scope.refreshGridData = function() {
-        var chain = $q.when();
-        var all_items = itemSvc.copies.map(function(item) {
-            return item.id;
-        });
-        angular.forEach(all_items.reverse(), function(i) {
-            itemSvc.copies.shift();
-            chain = chain.then(function() {
-                return itemSvc.fetch(null, i);
-            });
+    // Refresh the data shown in the item status grid,
+    // such as after the user has changed some data
+    //
+    // Takes an optional restrictToIds argument, which
+    // is a Set of item IDs that have been changed
+    $scope.refreshGridData = function(restrictToIds) {
+        var fetch_list = [];
+        var progress_bar;
+
+        angular.forEach(itemSvc.copies, function(item, index) {
+            if (!restrictToIds || restrictToIds.has(item['id'])) {
+                fetch_list.push(
+                    itemSvc.fetch(null, item['id'], null, true)
+                    .then(function(res) {
+                        itemSvc.copies[index] = res;
+                        if (progress_bar) egProgressDialog.increment();
+                        return res;
+                    })
+                );
+            }
         });
-        return chain.then(function() {
+
+        progress_bar = $timeout(egProgressDialog.open, 5000, true, {value: 0, max: fetch_list.length});
+
+        $q.all(fetch_list)
+        .then( function() {
             copyGrid.refresh();
+            if (progress_bar) $timeout.cancel(progress_bar);
+            egProgressDialog.close();
+            ngToast.create(egCore.strings.ITEMS_SUCCESSFULLY_MODIFIED);
         });
     }
 
@@ -700,18 +717,33 @@ function($scope , $q , $window , $location , $timeout , egCore , egNet , egGridD
                     'aria-label="' + egCore.strings.ITEM_SUCCESSFULLY_MODIFIED + '">' +
                     '</span>';
             }
-            return icon
+            return icon;
         }
     }
 
     if (typeof BroadcastChannel != 'undefined') {
         var holdings_bChannel = new BroadcastChannel("eg.holdings.update");
         holdings_bChannel.onmessage = function(e) {
-            angular.forEach(e.data.copies, function(i) {
-                modified_items.add(i);
-            });
-            ngToast.create(egCore.strings.ITEMS_SUCCESSFULLY_MODIFIED);
-            $scope.refreshGridData();
+            if (e.data.copies.length) {
+                angular.forEach(e.data.copies, function(i) {
+                    modified_items.add(i);
+                });
+                $scope.refreshGridData(modified_items);
+            } else { // if only call numbers were modified
+                egCore.pcrud.search('acp',
+                    {
+                        deleted : 0,
+                        call_number : e.data.volumes
+                    }, null, {atomic: true}
+                    
+                ).then(function(all_affected_items) {
+                    all_affected_items.map(function(item) {
+                        modified_items.add(item.id());
+                    });
+                    $scope.refreshGridData(modified_items);
+                });
+
+            }
         }
         $scope.$on('$destroy', function() {
             holdings_bChannel.close();
@@ -1199,3 +1231,4 @@ console.debug($scope.copy_alert_count);
 
     loadCopy().then(loadTabData);
 }])
+
index d07c598..3d45be2 100644 (file)
@@ -118,7 +118,7 @@ function(egCore , egOrg , egCirc , $uibModal , $q , $timeout , $window , ngToast
     }
 
     // resolved with the last received copy
-    service.fetch = function(barcode, id, noListDupes) {
+    service.fetch = function(barcode, id, noListDupes, noPrepend) {
         var copy;
         var circ;
         var circ_summary;
@@ -163,7 +163,9 @@ function(egCore , egOrg , egCirc , $uibModal , $q , $timeout , $window , ngToast
                     return !aca.ack_time();
                 }).length;
 
-                service.copies.unshift(flatCopy);
+                if (!noPrepend) {
+                    service.copies.unshift(flatCopy);
+                }
             }
 
             //Get in-house use count
@@ -186,6 +188,9 @@ function(egCore , egOrg , egCirc , $uibModal , $q , $timeout , $window , ngToast
                 });
             });
 
+            if (noPrepend) {
+                return flatCopy;
+            }
             return lastRes = {
                 copy : copyData.copy,
                 index : flatCopy.index