1 angular.module('egHoldsApp',
2 ['ngRoute', 'ui.bootstrap', 'egCoreMod', 'egUiMod', 'egGridMod'])
4 .config(function($routeProvider, $locationProvider, $compileProvider) {
5 $locationProvider.html5Mode(true);
6 $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|blob):/); // grid export
8 var resolver = {delay :
9 ['egStartup', function(egStartup) {return egStartup.go()}]}
11 $routeProvider.when('/circ/holds/shelf', {
12 templateUrl: './circ/holds/t_shelf',
13 controller: 'HoldsShelfCtrl',
17 $routeProvider.when('/circ/holds/shelf/:hold_id', {
18 templateUrl: './circ/holds/t_shelf',
19 controller: 'HoldsShelfCtrl',
23 $routeProvider.otherwise({redirectTo : '/circ/holds/shelf'});
26 .controller('HoldsShelfCtrl',
27 ['$scope','$q','$routeParams','$window','$location','egCore','egHolds','egCirc','egGridDataProvider',
28 function($scope , $q , $routeParams , $window , $location , egCore , egHolds , egCirc , egGridDataProvider) {
29 $scope.detail_hold_id = $routeParams.hold_id;
33 var clear_mode = false;
34 $scope.gridControls = {};
36 function fetch_holds(offset, count) {
37 var ids = hold_ids.slice(offset, offset + count);
38 return egHolds.fetch_holds(ids).then(null, null,
40 holds.push(hold_data);
41 return hold_data; // to the grid
46 var provider = egGridDataProvider.instance({});
47 $scope.gridDataProvider = provider;
49 provider.get = function(offset, count) {
51 // see if we have the requested range cached
53 return provider.arrayNotifier(patronSvc.holds, offset, count);
56 // see if we have the holds IDs for this range already loaded
57 if (hold_ids[offset]) {
58 return fetch_holds(offset, count);
61 var deferred = $q.defer();
65 var method = 'open-ils.circ.captured_holds.id_list.on_shelf.retrieve.authoritative.atomic';
67 method = 'open-ils.circ.captured_holds.id_list.expired_on_shelf_or_wrong_shelf.retrieve.atomic';
70 'open-ils.circ', method,
71 egCore.auth.token(), $scope.pickup_ou.id()
73 ).then(function(ids) {
80 fetch_holds(offset, count)
81 .then(deferred.resolve, null, deferred.notify);
84 return deferred.promise;
87 function refresh_page() {
94 // re-draw the grid when user changes the org selector
95 $scope.pickup_ou = egCore.org.get(egCore.auth.user().ws_ou());
96 $scope.$watch('pickup_ou', function(newVal, oldVal) {
97 if (newVal && newVal != oldVal)
101 $scope.detail_view = function(action, user_data, items) {
103 $location.path('/circ/holds/shelf/' + h.hold.id());
107 $scope.list_view = function(items) {
108 $location.path('/circ/holds/shelf');
111 // when the detail hold is fetched (and updated), update the bib
112 // record summary display record id.
113 $scope.set_hold = function(hold_data) {
114 $scope.detail_hold_record_id = hold_data.mvr.doc_id();
117 // manage active vs. clearable holds display
118 var clearing = false; // true if actively clearing holds (below)
119 $scope.is_clearing = function() { return clearing };
120 $scope.active_mode = function() {return !clear_mode}
121 $scope.clear_mode = function() {return clear_mode}
122 $scope.show_clearable = function() { clear_mode = true; refresh_page() }
123 $scope.show_active = function() { clear_mode = false; refresh_page() }
124 $scope.disable_clear = function() { return clearing || !clear_mode }
127 // TODO: These are copied directly from patron/holds.js.
128 // Consider refactoring / consolidating.
129 $scope.cancel_hold = function(items) {
130 var hold_ids = items.filter(function(item) {
131 return !item.hold.cancel_time();
132 }).map(function(item) {return item.hold.id()});
134 return egHolds.cancel_holds(hold_ids).then(refresh_page);
137 // jump to circ list for either 1) the targeted copy or
138 // 2) the hold target copy for copy-level holds
139 $scope.show_recent_circs = function(items) {
140 if (items.length && (copy = items[0].copy)) {
141 var url = $location.path(
142 '/cat/item/' + copy.id() + '/circ_list').absUrl();
143 $window.open(url, '_blank').focus();
147 function generic_update(items, action) {
148 if (!items.length) return $q.when();
149 var hold_ids = items.map(function(item) {return item.hold.id()});
150 return egHolds[action](hold_ids).then(refresh_page);
153 $scope.set_copy_quality = function(items) {
154 generic_update(items, 'set_copy_quality'); }
155 $scope.edit_pickup_lib = function(items) {
156 generic_update(items, 'edit_pickup_lib'); }
157 $scope.edit_notify_prefs = function(items) {
158 generic_update(items, 'edit_notify_prefs'); }
159 $scope.edit_dates = function(items) {
160 generic_update(items, 'edit_dates'); }
161 $scope.suspend = function(items) {
162 generic_update(items, 'suspend_holds'); }
163 $scope.activate = function(items) {
164 generic_update(items, 'activate_holds'); }
165 $scope.set_top_of_queue = function(items) {
166 generic_update(items, 'set_top_of_queue'); }
167 $scope.clear_top_of_queue = function(items) {
168 generic_update(items, 'clear_top_of_queue'); }
169 $scope.transfer_to_marked_title = function(items) {
170 generic_update(items, 'transfer_to_marked_title'); }
172 $scope.mark_damaged = function(items) {
174 .filter(function(item) { return Boolean(item.copy) })
175 .map(function(item) { return item.copy.id() });
177 egCirc.mark_damaged(copy_ids).then(refresh_page);
180 $scope.mark_missing = function(items) {
182 .filter(function(item) { return Boolean(item.copy) })
183 .map(function(item) { return item.copy.id() });
185 egCirc.mark_missing(copy_ids).then(refresh_page);
188 $scope.retarget = function(items) {
189 var hold_ids = items.map(function(item) { return item.hold.id() });
190 egHolds.retarget(hold_ids).then(refresh_page);
193 $scope.clear_holds = function() {
195 $scope.clear_progress = { max : 0, value : 0 };
197 // we want to see all processed holds, so (effectively) remove
199 $scope.gridControls.setLimit(1000);
201 // initiate clear shelf and grab cache key
204 'open-ils.circ.hold.clear_shelf.process',
205 egCore.auth.token(), $scope.pickup_ou.id()
207 // request responses from the clear shelf cache
208 ).then(function(resp) {
209 console.debug('clear holds cache key is ' + resp.cache_key);
210 return egCore.net.request(
212 'open-ils.circ.hold.clear_shelf.get_cache',
213 egCore.auth.token(), resp.cache_key
216 // with each clear-shelf response, update the progress meter,
217 // hide it when done.
224 console.debug('clear shelf said: ' + js2JSON(resp));
225 if (!angular.isArray(resp)) resp = [resp];
226 angular.forEach(resp, function(info) {
228 $scope.clear_progress.max = info.maximum;
230 $scope.clear_progress.value = info.progress;
233 var grid_item = holds.filter(function(item) {
234 return item.hold.id() == info.hold_details.id
237 // there will be no grid item if the hold is off-page
239 grid_item.post_clear =
240 egCore.strings['CLEAR_SHELF_ACTION_' + info.action];