From 40da6d4d63440e5aa2633e5662fe3bca107a89c5 Mon Sep 17 00:00:00 2001 From: Mike Rylander Date: Thu, 18 May 2017 12:01:18 -0400 Subject: [PATCH] webstaff: Filter by serial item status, and page through items server-side Signed-off-by: Mike Rylander --- Open-ILS/src/templates/staff/serials/index.tt2 | 10 +++ .../templates/staff/serials/t_view_items_grid.tt2 | 24 ++++++- .../staff/serials/directives/view-items-grid.js | 40 ++++++----- .../js/ui/default/staff/serials/services/core.js | 79 ++++++++++++++++------ 4 files changed, 115 insertions(+), 38 deletions(-) diff --git a/Open-ILS/src/templates/staff/serials/index.tt2 b/Open-ILS/src/templates/staff/serials/index.tt2 index efa0b0a025..d21f9838d3 100644 --- a/Open-ILS/src/templates/staff/serials/index.tt2 +++ b/Open-ILS/src/templates/staff/serials/index.tt2 @@ -29,6 +29,16 @@ angular.module('egCoreMod').run(['egStrings', function(s) { s.CONFIRM_DELETE_ITEMS = "[% l('Delete selected items?') %]"; s.CONFIRM_DELETE_ITEMS_MESSAGE = "[% l('Will delete {{items}} items') %]"; + s.SERIALS_ITEM_STATUS = {}; + s.SERIALS_ITEM_STATUS.Expected = "[% l('Expected') %]"; + s.SERIALS_ITEM_STATUS.Received = "[% l('Received') %]"; + s.SERIALS_ITEM_STATUS.Claimed = "[% l('Claimed') %]"; + s.SERIALS_ITEM_STATUS.Bindery = "[% l('Bindery') %]"; + s.SERIALS_ITEM_STATUS.Bound = "[% l('Bound') %]"; + s.SERIALS_ITEM_STATUS.Discarded = "[% l('Discarded') %]"; + s.SERIALS_ITEM_STATUS['Not Held'] = "[% l('Not Held' ) %]"; + s.SERIALS_ITEM_STATUS['Not Published'] = "[% l('Not Published') %]"; + }]); [% END %] diff --git a/Open-ILS/src/templates/staff/serials/t_view_items_grid.tt2 b/Open-ILS/src/templates/staff/serials/t_view_items_grid.tt2 index 22afd4a059..23676dc34b 100644 --- a/Open-ILS/src/templates/staff/serials/t_view_items_grid.tt2 +++ b/Open-ILS/src/templates/staff/serials/t_view_items_grid.tt2 @@ -4,9 +4,31 @@ features="-display,-sort,-multisort" items-provider="itemGridProvider" grid-controls="itemGridControls" + menu-label="[% l('Filter items') %]" persist-key="serials.view_item_grid"> - + + + + + + + + + + + + + + + diff --git a/Open-ILS/web/js/ui/default/staff/serials/directives/view-items-grid.js b/Open-ILS/web/js/ui/default/staff/serials/directives/view-items-grid.js index f48cdb2189..c584bf8244 100644 --- a/Open-ILS/web/js/ui/default/staff/serials/directives/view-items-grid.js +++ b/Open-ILS/web/js/ui/default/staff/serials/directives/view-items-grid.js @@ -15,14 +15,21 @@ angular.module('egSerialsAppDep') function($scope , $q , egSerialsCoreSvc , egCore , egGridDataProvider , $uibModal , ngToast , egConfirmDialog) { - $scope.svc = egSerialsCoreSvc; // just for debugging + $scope.svc = egSerialsCoreSvc; - function reload(ssubId) { - return egSerialsCoreSvc.fetchItemsForSub(ssubId).then(function(list) { + var _paging_filter; + function reload(ssubId,filter) { + _paging_filter = filter; + return egSerialsCoreSvc.fetchItemsForSub(ssubId,filter).then(function() { $scope.itemGridProvider.refresh(); }); } + $scope.filter_items_all = function () { return reload($scope.ssubId) } + $scope.filter_items_have = function () { return reload($scope.ssubId,{status:['Received','Bindery','Bound']}) } + $scope.filter_items_dont_have = function () { return reload($scope.ssubId,{'-not':{status:['Received','Bindery','Bound']}}) } + $scope.filter_items_by_status = function (item,status) { return reload($scope.ssubId,{status:status.name}) } + $scope.$watch('ssubId', function(newVal, oldVal) { if (newVal && newVal != oldVal) return reload(newVal); }); @@ -33,7 +40,14 @@ function($scope , $q , egSerialsCoreSvc , egCore , egGridDataProvider , $scope.itemGridProvider = egGridDataProvider.instance({ get : function(offset, count) { - return this.arrayNotifier(egSerialsCoreSvc.itemList, offset, count); + var self = this; + if (egSerialsCoreSvc.itemList.length >= offset + count) { // if there's anything on the requested page, notify + return self.arrayNotifier(egSerialsCoreSvc.itemList, offset, count); + } else { // else try to fetch another page + return egSerialsCoreSvc.fetchItemsForSubPaged($scope.ssubId, _paging_filter, offset, count).then(function() { + return self.arrayNotifier(egSerialsCoreSvc.itemList, offset, count); + }); + } } }); @@ -63,7 +77,7 @@ function($scope , $q , egSerialsCoreSvc , egCore , egGridDataProvider , ngToast.danger(egCore.strings.SERIALS_ISSUANCE_FAIL_SAVE); } else { ngToast.success(egCore.strings.SERIALS_ISSUANCE_SUCCESS_SAVE); - return reload($scope.ssubId); + return reload($scope.ssubId,_paging_filter); } }); }); @@ -128,7 +142,7 @@ function($scope , $q , egSerialsCoreSvc , egCore , egGridDataProvider , ngToast.danger(egCore.strings.SERIALS_ISSUANCE_FAIL_SAVE); } else { ngToast.success(egCore.strings.SERIALS_ISSUANCE_SUCCESS_SAVE); - return reload($scope.ssubId); + return reload($scope.ssubId,_paging_filter); } }, function(resp) { @@ -143,7 +157,6 @@ function($scope , $q , egSerialsCoreSvc , egCore , egGridDataProvider , title : egCore.strings.SERIALS_ISSUANCE_ADD, prev_iss : egCore.idl.fromHash('siss',items[0].issuance) }).then(function(hc) { - console.log(hc) return egCore.net.request( 'open-ils.serial', 'open-ils.serial.make_predictions', @@ -159,7 +172,7 @@ function($scope , $q , egSerialsCoreSvc , egCore , egGridDataProvider , ngToast.danger(egCore.strings.SERIALS_ISSUANCE_FAIL_SAVE); } else { ngToast.success(egCore.strings.SERIALS_ISSUANCE_SUCCESS_SAVE); - return reload($scope.ssubId); + return reload($scope.ssubId,_paging_filter); } }, function(resp) { @@ -179,7 +192,6 @@ function($scope , $q , egSerialsCoreSvc , egCore , egGridDataProvider , request_count : true, prev_iss : lastItem }).then(function(hc) { - console.log(hc) var base_iss; if (!lastItem) { @@ -212,7 +224,7 @@ function($scope , $q , egSerialsCoreSvc , egCore , egGridDataProvider , ngToast.danger(egCore.strings.SERIALS_ISSUANCE_FAIL_SAVE); } else { ngToast.success(egCore.strings.SERIALS_ISSUANCE_SUCCESS_SAVE); - return reload($scope.ssubId); + return reload($scope.ssubId,_paging_filter); } }, function(resp) { @@ -228,14 +240,6 @@ function($scope , $q , egSerialsCoreSvc , egCore , egGridDataProvider , return true; }; - if (!egSerialsCoreSvc.subTree.length) { - egSerialsCoreSvc.fetch($scope.bibId).then(function() { - return reload($scope.ssubId); - }); - } else if ($scope.ssubId) { - reload($scope.ssubId); - } - }] } diff --git a/Open-ILS/web/js/ui/default/staff/serials/services/core.js b/Open-ILS/web/js/ui/default/staff/serials/services/core.js index 26695010a5..ca36f8153a 100644 --- a/Open-ILS/web/js/ui/default/staff/serials/services/core.js +++ b/Open-ILS/web/js/ui/default/staff/serials/services/core.js @@ -56,9 +56,27 @@ function(egCore , orderByFilter , $q , $filter , $uibModal) { week : function(d) { return $filter('date')(d, 'ww') }, day : function(d) { return ('00'+d.getDate()).slice(-2) }, hour : function(d) { return ('00'+d.getHours()).slice(-2) } - } + }, + item_status_list : [ + 'Expected', + 'Received', + 'Claimed', + 'Bindery', + 'Bound', + 'Discarded', + 'Not Held', + 'Not Published' + ], + item_status_i18n : [] }; + angular.forEach(service.item_status_list, function(status) { + service.item_status_i18n.push({ + name : status, + label : egCore.strings.SERIALS_ITEM_STATUS[status] + }); + }); + function _loose_season(D) { var m = D.getMonth() + 1; var d = D.getDate(); @@ -104,9 +122,21 @@ function(egCore , orderByFilter , $q , $filter , $uibModal) { update_flat_sdist_sstr_list(); }); } - + + service.fetchItemsForSubPaged = function(subId,filter,offset,limit) { + return service.fetchItemsForSub( + subId, + filter, + { limit : limit, offset : offset, paging : true } + ); + } + // Creates an inverted tree from item to sub - service.fetchItemsForSub = function(subId) { + service.fetchItemsForSub = function(subId,filter,options) { + var deferred = $q.defer(); // side-effects only, otherwise the grid is wonky + + if (!filter) filter = {}; + if (!options) options = { limit : 100 }; // only used during full refresh if (!subId && service.subId) subId = service.subId; if (!subId) return $q.reject('fetchItemsForSub: no subscription id'); @@ -124,19 +154,30 @@ function(egCore , orderByFilter , $q , $filter , $uibModal) { ); }); - return egCore.pcrud.search( - 'sitem', - { stream : streams }, - { - flesh : 1, - flesh_fields : { - sitem : ['issuance','editor','creator','unit','url'] - } - }, + angular.extend(filter, {stream:streams}); + angular.extend(options, { + order_by : [{class:'sitem',field:'date_expected'}], // best aprox of pub date + flesh : 1, + flesh_fields : { + sitem : ['issuance','editor','creator','unit','url'] + } + }); + + egCore.pcrud.search( + 'sitem', filter, options, { atomic : true } ).then(function(list) { service.subId = subId; - service.itemTree = list; + if (!options.paging) { // not paged + service.itemTree = list; + } else { // paged + angular.forEach(list, function (item) { + var exists = service.itemTree.filter(function (i) { + return i.id() == item.id() + }).length; + if (!exists) service.itemTree.push(item); + }); + } // map items by stream for faster lookup var tmp = {}; @@ -159,18 +200,18 @@ function(egCore , orderByFilter , $q , $filter , $uibModal) { }); }); - var hashList = egCore.idl.toHash(list); + var hashList = egCore.idl.toHash(service.itemTree); angular.forEach(hashList, function (item) { item['issuance.date_published'] = item.issuance.date_published; + item['stream.distribution.holding_lib.name'] = item.stream.distribution.holding_lib.name; }); // ... then sort it - service.itemList.length = 0; - angular.extend(service.itemList, - orderByFilter(hashList, ['"issuance.date_published"', '"id"']) - ); - return $q.when(list); + service.itemList = orderByFilter(hashList, ['"issuance.date_published"', '"stream.distribution.holding_lib.name"', '"id"']); + deferred.resolve(); }); + + return deferred.promise; } service.prep_new_holding_code = function (args) { -- 2.11.0