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

Evergreen Git git at git.evergreen-ils.org
Mon Mar 6 15:18:44 EST 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  6fa137e176b4f08f083828fcc454aefbc2e8118b (commit)
       via  1f55699f8c5ceb01400d2d56c3aaac60aac0380b (commit)
       via  02edc5ca4b6cc1b4f7c03d2faaa18b09ac4764bf (commit)
      from  8d12a5adbfcb7a7be1bdf8bde714ec383b5caa83 (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 6fa137e176b4f08f083828fcc454aefbc2e8118b
Author: Bill Erickson <berickxx at gmail.com>
Date:   Thu Mar 2 18:05:05 2017 -0500

    LP#1653001 Hold pull list progress dialog
    
    Display a progress dialog while loading the holds pull list grid and the
    when collecting data for printing the holds pull list.
    
    Signed-off-by: Bill Erickson <berickxx at gmail.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>

diff --git a/Open-ILS/src/templates/staff/circ/holds/t_pull_list.tt2 b/Open-ILS/src/templates/staff/circ/holds/t_pull_list.tt2
index 91b8571..4016967 100644
--- a/Open-ILS/src/templates/staff/circ/holds/t_pull_list.tt2
+++ b/Open-ILS/src/templates/staff/circ/holds/t_pull_list.tt2
@@ -1,7 +1,3 @@
-<div ng-if="print_list_progress !== null" class="strong-text-2">
-  [% l('Loading... [_1]', '{{print_list_progress}}') %]
-</div>
-
 <eg-grid
   id-field="id"
   idl-class="ahopl"
diff --git a/Open-ILS/web/js/ui/default/staff/circ/holds/app.js b/Open-ILS/web/js/ui/default/staff/circ/holds/app.js
index 0dccd94..98eee85 100644
--- a/Open-ILS/web/js/ui/default/staff/circ/holds/app.js
+++ b/Open-ILS/web/js/ui/default/staff/circ/holds/app.js
@@ -245,9 +245,9 @@ function($scope , $q , $routeParams , $window , $location , egCore , egHolds , e
 
 .controller('HoldsPullListCtrl',
        ['$scope','$q','$routeParams','$window','$location','egCore',
-        'egHolds','egCirc','egHoldGridActions',
+        'egHolds','egCirc','egHoldGridActions','egProgressDialog',
 function($scope , $q , $routeParams , $window , $location , egCore , 
-         egHolds , egCirc , egHoldGridActions) {
+         egHolds , egCirc , egHoldGridActions , egProgressDialog) {
 
     $scope.detail_hold_id = $routeParams.hold_id;
 
@@ -261,12 +261,22 @@ function($scope , $q , $routeParams , $window , $location , egCore ,
         setSort : function() {
             return ['copy_location_order_position','call_number_sort_key']
         },
+        collectStarted : function(offset) {
+            // Launch an indeterminate -> semi-determinate progress
+            // modal.  Using a determinate modal that starts counting
+            // on the post-grid holds data retrieval results in a modal
+            // that's stuck at 0% for most of its life, which is aggravating.
+            egProgressDialog.open();
+        },
         itemRetrieved : function(item) {
+            egProgressDialog.increment();
             if (!cached_details[item.id]) {
                 details_needed[item.id] = item;
             }
         },
-        allItemsRetrieved : flesh_holds
+        allItemsRetrieved : function() {
+            flesh_holds().finally(egProgressDialog.close);
+        }
     }
 
 
@@ -275,40 +285,36 @@ function($scope , $q , $routeParams , $window , $location , egCore ,
     // and friends have access to holds data they understand.
     // Only fetch not-yet-cached data.
     function flesh_holds() {
+        egProgressDialog.increment();
 
         // Start by fleshing hold details from our cached data.
         var items = $scope.gridControls.allItems();
         angular.forEach(items, function(item) {
-            if (!cached_details[item.id]) return;
+            if (!cached_details[item.id]) return $q.when();
             angular.forEach(cached_details[item.id], 
                 function(val, key) { item[key] = val })
         });
 
         // Exit if all needed details were already cached
-        if (Object.keys(details_needed).length == 0) return;
-
-        $scope.print_list_loading = true;
-        $scope.print_list_progress = 0;
+        if (Object.keys(details_needed).length == 0) return $q.when();
 
-        egCore.net.request(
+        return egCore.net.request(
             'open-ils.circ',
             'open-ils.circ.hold.details.batch.retrieve.authoritative',
             egCore.auth.token(), Object.keys(details_needed)
-        ).then(
-            function() {
-                $scope.print_list_loading = false;
-                $scope.print_list_progress = null;
-            }, null,
-            function(hold_info) {
-                var hold_id = hold_info.hold.id();
-                cached_details[hold_id] = hold_info;
-                var item = details_needed[hold_id];
-                delete details_needed[hold_id];
-                angular.forEach(hold_info, 
-                    function(val, key) { item[key] = val });
-                $scope.print_list_progress++;
-            }
-        );
+
+        ).then(null, null, function(hold_info) {
+            egProgressDialog.increment();
+            var hold_id = hold_info.hold.id();
+            cached_details[hold_id] = hold_info;
+            var item = details_needed[hold_id];
+            delete details_needed[hold_id];
+
+            // flesh the grid item from the blob of hold data.
+            angular.forEach(hold_info, 
+                function(val, key) { item[key] = val });
+
+        });
     }
 
     $scope.grid_actions = egHoldGridActions;
@@ -343,11 +349,9 @@ function($scope , $q , $routeParams , $window , $location , egCore ,
         win.focus();
     }
 
-    $scope.print_list_progress = null;
     $scope.print_full_list = function() {
         var print_holds = [];
-        $scope.print_list_loading = true;
-        $scope.print_list_progress = 0;
+        egProgressDialog.open({value : 0});
 
         // collect the full list of holds
         egCore.net.request(
@@ -367,7 +371,7 @@ function($scope , $q , $routeParams , $window , $location , egCore ,
             },
             null, 
             function(hold_data) {
-                $scope.print_list_progress++;
+                egProgressDialog.increment();
                 egHolds.local_flesh(hold_data);
                 print_holds.push(hold_data);
                 hold_data.title = hold_data.mvr.title();
@@ -377,10 +381,7 @@ function($scope , $q , $routeParams , $window , $location , egCore ,
                 hold_data.volume = egCore.idl.toHash(hold_data.volume);
                 hold_data.part = egCore.idl.toHash(hold_data.part);
             }
-        ).finally(function() {
-            $scope.print_list_loading = false;
-            $scope.print_list_progress = null;
-        });
+        ).finally(egProgressDialog.close);
     }
 
 }])
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 ff438f8..f85872b 100644
--- a/Open-ILS/web/js/ui/default/staff/services/grid.js
+++ b/Open-ILS/web/js/ui/default/staff/services/grid.js
@@ -68,6 +68,7 @@ angular.module('egGridMod',
             //  These functions are defined by the calling scope and 
             //  invoked as-is by the grid w/ the specified parameters.
             //
+            //  collectStarted    : function() {}
             //  itemRetrieved     : function(item) {}
             //  allItemsRetrieved : function() {}
             //
@@ -1000,6 +1001,15 @@ angular.module('egGridMod',
 
                 $scope.items = [];
                 $scope.selected = {};
+
+                // Inform the caller we've asked the data provider
+                // for data.  This is useful for knowing when collection
+                // has started (e.g. to display a progress dialg) when 
+                // using the stock (flattener) data provider, where the 
+                // user is not directly defining a get() handler.
+                if (grid.controls.collectStarted)
+                    grid.controls.collectStarted(grid.offset, grid.limit);
+
                 grid.dataProvider.get(grid.offset, grid.limit).then(
                 function() {
                     if (grid.controls.allItemsRetrieved)

commit 1f55699f8c5ceb01400d2d56c3aaac60aac0380b
Author: Bill Erickson <berick at esilibrary.com>
Date:   Wed Aug 20 16:45:47 2014 -0400

    LP#1653001 webstaff: Holds pull list sortable columns
    
    Retrieve holds for the pull list via the canned "ahopl" pull list IDL
    class.  This lets the grid fetch the data via canned flattener query,
    supporting server-side sort/limit/offset options.
    
    To retain all previous UI behavior, primarily editing hold attributes
    (e.g. notification prefs), hold details for each hold have to be fetched
    (and cached) in addition to the main grid data.  The grid renders and
    sorts the flattener data, then grid actions act upon the fleshed hold
    details data.
    
    Commit also includes:
    
    1. Added some missing IDL links for the "ahopl" class.
    2. Micro-optimization to egGrid to exit early when an invalid IDL path
       is provided.
    
    Signed-off-by: Bill Erickson <berickxx at gmail.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>

diff --git a/Open-ILS/examples/fm_IDL.xml b/Open-ILS/examples/fm_IDL.xml
index 2ec0f20..86efb0d 100644
--- a/Open-ILS/examples/fm_IDL.xml
+++ b/Open-ILS/examples/fm_IDL.xml
@@ -5658,7 +5658,7 @@ SELECT  usr,
 			<field reporter:label="Status" name="status" oils_persist:virtual="true" />
 			<field reporter:label="Transit" name="transit" oils_persist:virtual="true" />
 			<field reporter:label="Capture Date/Time" name="capture_time" reporter:datatype="timestamp"/>
-			<field reporter:label="Currently Targeted Copy" name="current_copy" />
+			<field reporter:label="Currently Targeted Copy" name="current_copy" reporter:datatype="link"/>
 			<field reporter:label="Notify by Email?" name="email_notify" reporter:datatype="bool"/>
 			<field reporter:label="Hold Expire Date/Time" name="expire_time" reporter:datatype="timestamp"/>
 			<field reporter:label="Fulfilling Library" name="fulfillment_lib" reporter:datatype="org_unit"/>
@@ -5806,7 +5806,7 @@ SELECT  usr,
 			<field reporter:label="Status" name="status" oils_persist:virtual="true" />
 			<field reporter:label="Transit" name="transit" oils_persist:virtual="true" />
 			<field reporter:label="Capture Date/Time" name="capture_time" reporter:datatype="timestamp"/>
-			<field reporter:label="Currently Targeted Copy" name="current_copy" />
+			<field reporter:label="Currently Targeted Copy" name="current_copy" reporter:datatype="link"/>
 			<field reporter:label="Notify by Email?" name="email_notify" reporter:datatype="bool"/>
 			<field reporter:label="Hold Expire Date/Time" name="expire_time" reporter:datatype="timestamp"/>
 			<field reporter:label="Fulfilling Library" name="fulfillment_lib" reporter:datatype="org_unit"/>
@@ -5891,7 +5891,7 @@ SELECT  usr,
 			<field reporter:label="Status" name="status" oils_persist:virtual="true" />
 			<field reporter:label="Transit" name="transit" oils_persist:virtual="true" />
 			<field reporter:label="Capture Date/Time" name="capture_time" reporter:datatype="timestamp"/>
-			<field reporter:label="Currently Targeted Copy" name="current_copy" />
+			<field reporter:label="Currently Targeted Copy" name="current_copy" reporter:datatype="link"/>
 			<field reporter:label="Notify by Email?" name="email_notify" reporter:datatype="bool"/>
 			<field reporter:label="Hold Expire Date/Time" name="expire_time" reporter:datatype="timestamp"/>
 			<field reporter:label="Fulfilling Library" name="fulfillment_lib" reporter:datatype="org_unit"/>
@@ -5973,7 +5973,7 @@ SELECT  usr,
 		<fields oils_persist:primary="id" oils_persist:sequence="action.hold_request_id_seq">
 			<field reporter:label="Status" name="status" oils_persist:virtual="true" />
 			<field reporter:label="Capture Date/Time" name="capture_time" reporter:datatype="timestamp"/>
-			<field reporter:label="Currently Targeted Copy" name="current_copy" />
+			<field reporter:label="Currently Targeted Copy" name="current_copy" reporter:datatype="link"/>
 			<field reporter:label="Notify by Email?" name="email_notify" reporter:datatype="bool"/>
 			<field reporter:label="Hold Expire Date/Time" name="expire_time" reporter:datatype="timestamp"/>
 			<field reporter:label="Fulfilling Library" name="fulfillment_lib" reporter:datatype="org_unit"/>
@@ -6032,7 +6032,7 @@ SELECT  usr,
 		<fields oils_persist:primary="id" oils_persist:sequence="action.hold_request_id_seq">
 			<field reporter:label="Status" name="status" oils_persist:virtual="true" />
 			<field reporter:label="Capture Date/Time" name="capture_time" reporter:datatype="timestamp"/>
-			<field reporter:label="Currently Targeted Copy" name="current_copy" />
+			<field reporter:label="Currently Targeted Copy" name="current_copy" reporter:datatype="link"/>
 			<field reporter:label="Notify by Email?" name="email_notify" reporter:datatype="bool"/>
 			<field reporter:label="Hold Expire Date/Time" name="expire_time" reporter:datatype="timestamp"/>
 			<field reporter:label="Fulfilling Library" name="fulfillment_lib" reporter:datatype="org_unit"/>
diff --git a/Open-ILS/src/templates/staff/circ/holds/t_pull_list.tt2 b/Open-ILS/src/templates/staff/circ/holds/t_pull_list.tt2
index 4f4502f..91b8571 100644
--- a/Open-ILS/src/templates/staff/circ/holds/t_pull_list.tt2
+++ b/Open-ILS/src/templates/staff/circ/holds/t_pull_list.tt2
@@ -4,8 +4,8 @@
 
 <eg-grid
   id-field="id"
-  features="-sort,-multisort"
-  items-provider="gridDataProvider"
+  idl-class="ahopl"
+  grid-controls="gridControls"
   persist-key="circ.holds.pull">
 
   <eg-grid-menu-item handler="detail_view" 
@@ -56,39 +56,88 @@
   <eg-grid-action handler="grid_actions.cancel_hold"
     label="[% l('Cancel Hold') %]"></eg-grid-action>
 
-  <eg-grid-field label="[% l('Hold ID') %]" path='hold.id'></eg-grid-field>
-  <eg-grid-field label="[% l('Current Copy') %]" 
-    path='hold.current_copy.barcode'>
-    <a href="./cat/item/{{item.hold.current_copy().id()}}/summary" target="_self">
-      {{item.hold.current_copy().barcode()}}
-    </a>
+  <!-- Define the column using the sort-able copy location order
+       position, but display the location label in each cell -->
+  <eg-grid-field name="copy_location_order_position" required 
+    label="[% l('Shelving Location') %]">
+    <span>{{item.shelving_loc}}</span>
+  </eg-grid-field>
+  <eg-grid-field name="shelving_loc" path="current_copy.location.name" 
+    required hidden label="[% l('Shelving Location Label') %]">
   </eg-grid-field>
 
-  <eg-grid-field label="[% l('Part') %]" path='part.label'></eg-grid-field>
-  <eg-grid-field label="[% l('Request Date') %]" path='hold.request_time'></eg-grid-field>
-  <eg-grid-field label="[% l('Hold Type') %]" path='hold.hold_type'></eg-grid-field>
-  <eg-grid-field label="[% l('Pickup Library') %]" path='hold.pickup_lib.shortname'></eg-grid-field>
-  <eg-grid-field label="[% l('Copy Location') %]" path='copy.location.name'></eg-grid-field>
-  <eg-grid-field label="[% l('Call Number') %]" path='volume.label'></eg-grid-field>
-
-  <eg-grid-field label="[% l('Title') %]" path='mvr.title'>
-    <a target="_self" href="[% ctx.base_path %]/staff/cat/catalog/record/{{item.mvr.doc_id()}}">
-      {{item.mvr.title()}}
-    </a>
+  <!-- Render the colum using the sort-able call number sort key, but 
+       display the call number label, complete with prefix and suffix 
+       in the cell. -->
+  <eg-grid-field name="call_number_sort_key" required
+    path="current_copy.call_number.label_sortkey" 
+    label="[% l('Call Number') %]">
+    <span>{{item.cn_prefix}} {{item.call_number_label}} {{item.cn_suffix}}</span>
   </eg-grid-field>
+  <eg-grid-field name="call_number_label" 
+    path="call_number_label" required hidden
+    label="[% l('Call Number Label') %]"></eg-grid-field>
+  <eg-grid-field name="cn_prefix" path="current_copy.call_number.prefix.label" 
+    hidden required label="[% l('Call Number Prefix') %]"></eg-grid-field>
+  <eg-grid-field name="cn_suffix" path="current_copy.call_number.suffix.label"
+    hidden required label="[% l('Call Number Suffix') %]"></eg-grid-field>
 
-  <eg-grid-field label="[% l('Author') %]" path='mvr.author'></eg-grid-field>
-  <eg-grid-field label="[% l('Potential Copies') %]" path='potential_copies'></eg-grid-field>
-  <eg-grid-field label="[% l('Status') %]" path='status_string' hidden></eg-grid-field>
 
-  <eg-grid-field label="[% l('Queue Position') %]" path='queue_position' hidden></eg-grid-field>
-  <eg-grid-field path='hold.*' parent-idl-class="ahr" hidden></eg-grid-field>
-  <eg-grid-field path='hold.usr.*' parent-idl-class="ahr" hidden></eg-grid-field>
-  <eg-grid-field path='hold.usr.card.*' parent-idl-class="ahr" hidden></eg-grid-field>
-  <eg-grid-field path='hold.requestor.*' parent-idl-class="ahr" hidden></eg-grid-field>
-  <eg-grid-field path='hold.requestor.card.*' parent-idl-class="ahr" hidden></eg-grid-field>
-  <eg-grid-field path='copy.*' parent-idl-class="acp" hidden></eg-grid-field>
-  <eg-grid-field path='volume.*' parent-idl-class="acn" hidden></eg-grid-field>
-  <eg-grid-field path='mvr.*' parent-idl-class="mvr" hidden></eg-grid-field>
+  <eg-grid-field name="author" 
+    path="current_copy.call_number.record.simple_record.author" 
+    label="[% l('Author') %]"></eg-grid-field>
+  <eg-grid-field name="title" 
+    path="current_copy.call_number.record.simple_record.title" 
+    label="[% l('Title') %]">
+    <a target="_self" 
+      href="[% ctx.base_path %]/staff/cat/catalog/record/{{item.record_id}}">
+      {{item.title}}
+    </a>
+  </eg-grid-field>
+  <eg-grid-field name="record_id" label="[% l('Bib Record ID') %]" 
+    required hidden path="current_copy.call_number.record.id"></eg-grid-field>
+  <eg-grid-field name="copy_id" 
+    path="current_copy.id" hidden required></eg-grid-field>
+  <eg-grid-field name="barcode" 
+    path="current_copy.barcode" label="[% l('Current Copy') %]">
+    <a href="./cat/item/{{item.copy_id}}/summary" target="_self">
+      {{item.barcode}}
+    </a>
+  </eg-grid-field>
+  <eg-grid-field name="parts" path="current_copy.parts.label" 
+    label="[% l('Parts') %]"></eg-grid-field>
+  <eg-grid-field name="copy_status" path="current_copy.status.name" 
+    label="[% l('Copy Status') %]"></eg-grid-field>
+  <eg-grid-field name="copy_circ_lib_id" path="current_copy.circ_lib.id" 
+    required hidden label="[% l('Copy Circ Lib ID') %]"></eg-grid-field>
+  <eg-grid-field name="notes" path="notes.body" 
+    hidden label="[% l('Hold Notes') %]"></eg-grid-field>
+  <eg-grid-field name="patron_id" path="usr.id" hidden required></eg-grid-field>
+  <eg-grid-field name="patron_barcode" path="usr.card.barcode" 
+    hidden label="[% l('Patron Barcode') %]">
+    <a href="./circ/patron/{{item.patron_id}}/holds" target="_self">
+      {{item.patron_barcode}}
+    </a>
+  </eg-grid-field>
+  <eg-grid-field name="pickup_lib_name" path="pickup_lib.name" 
+    hidden label="[% l('Pickup Library') %]"></eg-grid-field>
+  <eg-grid-field name="pickup_lib_shortname" path="pickup_lib.shortname" 
+    hidden label="[% l('Pickup Library (Shortname)') %]"></eg-grid-field>
+  <eg-grid-field name="request_lib_name" path="request_lib.name" 
+    hidden label="[% l('Request Library') %]"></eg-grid-field>
+  <eg-grid-field name="request_lib_shortname" path="request_lib.shortname" 
+    hidden label="[% l('Request Library (Shortname)') %]"></eg-grid-field>
+  <eg-grid-field name="selection_ou" path="selection_ou.shortname" 
+    hidden label="[% l('Selection Locus') %]"></eg-grid-field>
+  <eg-grid-field name="sms_carrier_name" path="sms_carrier.name" 
+    hidden label="[% l('SMS Carrier') %]"></eg-grid-field>
+  <eg-grid-field label="[% l('Potential Copies') %]" 
+    path='potential_copies'></eg-grid-field>
+  <eg-grid-field label="[% l('Queue Position') %]" 
+    path='queue_position' hidden></eg-grid-field>
+  <eg-grid-field label="[% l('Hold ID') %]" path='id' required hidden>
+  </eg-grid-field>
+  <eg-grid-field label="[% l('Request Date') %]" path='request_time' hidden>
+  </eg-grid-field>
 </eg-grid>
 
diff --git a/Open-ILS/web/js/ui/default/staff/circ/holds/app.js b/Open-ILS/web/js/ui/default/staff/circ/holds/app.js
index 83bb529..0dccd94 100644
--- a/Open-ILS/web/js/ui/default/staff/circ/holds/app.js
+++ b/Open-ILS/web/js/ui/default/staff/circ/holds/app.js
@@ -35,11 +35,6 @@ angular.module('egHoldsApp',
     $routeProvider.otherwise({redirectTo : '/circ/holds/shelf'});
 })
 
-.factory('holdUiSvc', function() {
-    return {
-        holds : [] // cache
-    }
-})
 
 .controller('HoldsShelfCtrl',
        ['$scope','$q','$routeParams','$window','$location','egCore','egHolds','egHoldGridActions','egCirc','egGridDataProvider',
@@ -249,43 +244,77 @@ function($scope , $q , $routeParams , $window , $location , egCore , egHolds , e
 }])
 
 .controller('HoldsPullListCtrl',
-       ['$scope','$q','$routeParams','$window','$location','egCore','egHolds','egCirc','egGridDataProvider','egHoldGridActions','holdUiSvc',
-function($scope , $q , $routeParams , $window , $location , egCore , egHolds , egCirc , egGridDataProvider , egHoldGridActions , holdUiSvc)  {
-    $scope.detail_hold_id = $routeParams.hold_id;
+       ['$scope','$q','$routeParams','$window','$location','egCore',
+        'egHolds','egCirc','egHoldGridActions',
+function($scope , $q , $routeParams , $window , $location , egCore , 
+         egHolds , egCirc , egHoldGridActions) {
 
-    var provider = egGridDataProvider.instance({});
-    $scope.gridDataProvider = provider;
+    $scope.detail_hold_id = $routeParams.hold_id;
 
-    $scope.grid_actions = egHoldGridActions;
-    $scope.grid_actions.refresh = function() {
-        holdUiSvc.holds = [];
-        provider.refresh();
+    var cached_details = {};
+    var details_needed = {};
+
+    $scope.gridControls = {
+        setQuery : function() {
+            return {'copy_circ_lib_id' : egCore.auth.user().ws_ou()}
+        },
+        setSort : function() {
+            return ['copy_location_order_position','call_number_sort_key']
+        },
+        itemRetrieved : function(item) {
+            if (!cached_details[item.id]) {
+                details_needed[item.id] = item;
+            }
+        },
+        allItemsRetrieved : flesh_holds
     }
 
-    provider.get = function(offset, count) {
 
-        if (holdUiSvc.holds[offset]) {
-            return provider.arrayNotifier(holdUiSvc.holds, offset, count);
-        }
+    // Fetches hold detail data for each hold in the grid and links
+    // the detail data to the related grid item so egHoldGridActions 
+    // and friends have access to holds data they understand.
+    // Only fetch not-yet-cached data.
+    function flesh_holds() {
 
-        var deferred = $q.defer();
-        var recv_index = 0;
+        // Start by fleshing hold details from our cached data.
+        var items = $scope.gridControls.allItems();
+        angular.forEach(items, function(item) {
+            if (!cached_details[item.id]) return;
+            angular.forEach(cached_details[item.id], 
+                function(val, key) { item[key] = val })
+        });
+
+        // Exit if all needed details were already cached
+        if (Object.keys(details_needed).length == 0) return;
+
+        $scope.print_list_loading = true;
+        $scope.print_list_progress = 0;
 
-        // fetch the IDs
         egCore.net.request(
             'open-ils.circ',
-            'open-ils.circ.hold_pull_list.fleshed.stream',
-            egCore.auth.token(), count, offset
+            'open-ils.circ.hold.details.batch.retrieve.authoritative',
+            egCore.auth.token(), Object.keys(details_needed)
         ).then(
-            deferred.resolve, null, 
-            function(hold_data) {
-                egHolds.local_flesh(hold_data);
-                holdUiSvc.holds[offset + recv_index++] = hold_data;
-                deferred.notify(hold_data);
+            function() {
+                $scope.print_list_loading = false;
+                $scope.print_list_progress = null;
+            }, null,
+            function(hold_info) {
+                var hold_id = hold_info.hold.id();
+                cached_details[hold_id] = hold_info;
+                var item = details_needed[hold_id];
+                delete details_needed[hold_id];
+                angular.forEach(hold_info, 
+                    function(val, key) { item[key] = val });
+                $scope.print_list_progress++;
             }
         );
+    }
 
-        return deferred.promise;
+    $scope.grid_actions = egHoldGridActions;
+    $scope.grid_actions.refresh = function() {
+        cached_details = {}; // un-cache details after edit actions.
+        $scope.gridControls.refresh();
     }
 
     $scope.detail_view = function(action, user_data, items) {
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 8828456..ff438f8 100644
--- a/Open-ILS/web/js/ui/default/staff/services/grid.js
+++ b/Open-ILS/web/js/ui/default/staff/services/grid.js
@@ -1420,16 +1420,17 @@ angular.module('egGridMod',
                 idl_parent = idl_field;
                 idl_field = class_obj.field_map[part];
 
-                if (idl_field && idl_field['class'] && (
-                    idl_field.datatype == 'link' || 
-                    idl_field.datatype == 'org_unit')) {
-                    class_obj = egCore.idl.classes[idl_field['class']];
+                if (idl_field) {
+                    if (idl_field['class'] && (
+                        idl_field.datatype == 'link' || 
+                        idl_field.datatype == 'org_unit')) {
+                        class_obj = egCore.idl.classes[idl_field['class']];
+                    }
+                } else {
+                    return null;
                 }
-                // else, path is not in the IDL, which is fine
             }
 
-            if (!idl_field) return null;
-
             return {
                 idl_parent: idl_parent,
                 idl_field : idl_field,

commit 02edc5ca4b6cc1b4f7c03d2faaa18b09ac4764bf
Author: Bill Erickson <berickxx at gmail.com>
Date:   Fri Dec 30 11:54:08 2016 -0500

    LP#1653001 Hold details authoritative API cstore maintenance
    
    Avoid cstore exhaustion during .authorative API calls that run
    Holds:retrieve_hold_queue_status_impl() by using the in-transaction
    editor for YAOUS lookups instead of allowing the lookups to create their
    own cstore connections, each spawning a new transaction, since
    CStoreEditor is in authoritative mode.
    
    Since CStoreEditor authoritative handling leaves each cstore transaction
    open until the API call completes, and in this case, each hold in the batch
    lookup resulted in 2 additional open cstore connections per hold, a batch
    lookup of (say) 15 holds, meant 31 cstore connections were opened in one API
    call.
    
    Telling the YAOUS lookup to use the existing editor means the same call
    completes with 1 cstore connection.
    
    Signed-off-by: Bill Erickson <berickxx at gmail.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>

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 9f5f42c..1825c71 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Holds.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Holds.pm
@@ -1443,8 +1443,10 @@ sub retrieve_hold_queue_status_impl {
 
     my $user_org = $e->json_query({select => {au => ['home_ou']}, from => 'au', where => {id => $hold->usr}})->[0]->{home_ou};
 
-    my $default_wait = $U->ou_ancestor_setting_value($user_org, OILS_SETTING_HOLD_ESIMATE_WAIT_INTERVAL);
-    my $min_wait = $U->ou_ancestor_setting_value($user_org, 'circ.holds.min_estimated_wait_interval');
+    my $default_wait = $U->ou_ancestor_setting_value(
+        $user_org, OILS_SETTING_HOLD_ESIMATE_WAIT_INTERVAL, $e);
+    my $min_wait = $U->ou_ancestor_setting_value(
+        $user_org, 'circ.holds.min_estimated_wait_interval', $e);
     $min_wait = OpenSRF::Utils::interval_to_seconds($min_wait || '0 seconds');
     $default_wait ||= '0 seconds';
 

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

Summary of changes:
 Open-ILS/examples/fm_IDL.xml                       |   10 +-
 .../perlmods/lib/OpenILS/Application/Circ/Holds.pm |    6 +-
 .../src/templates/staff/circ/holds/t_pull_list.tt2 |  115 ++++++++++++++------
 Open-ILS/web/js/ui/default/staff/circ/holds/app.js |  112 ++++++++++++-------
 Open-ILS/web/js/ui/default/staff/services/grid.js  |   25 +++--
 5 files changed, 178 insertions(+), 90 deletions(-)


hooks/post-receive
-- 
Evergreen ILS


More information about the open-ils-commits mailing list