From 55386f3ca8be8b2990ba23af4f5f1b9e7a0b304b Mon Sep 17 00:00:00 2001 From: Bill Erickson Date: Sat, 12 Aug 2017 11:52:40 -0400 Subject: [PATCH] LP#1709521 Webstaff show recent patrons Adds a new library setting 'ui.staff.max_recent_patrons' which specifices the number of recently accessed patrons staff may quickly refetch from the browser client interface. If no value is set, it defaults to 1 for backwards compatibility. If the value is 0 or less, no recent patrons may be retrieved and the 'Retrieve Last Patron' action is hidden. If the value is > 1 a new 'Retrieve Recent Patrons' menu item appears. When clicked, the list of recent patrons is displayed in the patron search interface, most recently accessed patrons sorted to the top. For privacy, the recent patrons list expires from the browser when the authenticion token expires. Signed-off-by: Bill Erickson --- Open-ILS/src/sql/Pg/950.data.seed-values.sql | 23 +++++++ .../sql/Pg/upgrade/XXXX.data.recent-patrons.sql | 26 ++++++++ Open-ILS/src/templates/staff/navbar.tt2 | 9 ++- .../web/js/ui/default/staff/circ/patron/app.js | 76 ++++++++++++++++++++-- .../web/js/ui/default/staff/services/navbar.js | 7 ++ .../web/js/ui/default/staff/services/startup.js | 9 ++- 6 files changed, 142 insertions(+), 8 deletions(-) create mode 100644 Open-ILS/src/sql/Pg/upgrade/XXXX.data.recent-patrons.sql diff --git a/Open-ILS/src/sql/Pg/950.data.seed-values.sql b/Open-ILS/src/sql/Pg/950.data.seed-values.sql index e95d94caea..4ffb86b204 100644 --- a/Open-ILS/src/sql/Pg/950.data.seed-values.sql +++ b/Open-ILS/src/sql/Pg/950.data.seed-values.sql @@ -17125,3 +17125,26 @@ INSERT into config.org_unit_setting_type 'Define the time zone in which a library physically resides', 'coust', 'description'), 'string'); + +INSERT INTO config.org_unit_setting_type + (name, label, description, grp, datatype) +VALUES ( + 'ui.staff.max_recent_patrons', + oils_i18n_gettext( + 'ui.staff.max_recent_patrons', + 'Number of Retrievable Recent Patrons', + 'coust', + 'label' + ), + oils_i18n_gettext( + 'ui.staff.max_recent_patrons', + 'Number of most recently accessed patrons that can be re-retrieved ' || + 'in the staff client. A value of 0 or less disables the feature', + 'coust', + 'description' + ), + 'circ', + 'integer' +); + + diff --git a/Open-ILS/src/sql/Pg/upgrade/XXXX.data.recent-patrons.sql b/Open-ILS/src/sql/Pg/upgrade/XXXX.data.recent-patrons.sql new file mode 100644 index 0000000000..3cf897d60b --- /dev/null +++ b/Open-ILS/src/sql/Pg/upgrade/XXXX.data.recent-patrons.sql @@ -0,0 +1,26 @@ +BEGIN; + +-- SELECT evergreen.upgrade_deps_block_check('XXXX', :eg_version); + +INSERT INTO config.org_unit_setting_type + (name, label, description, grp, datatype) +VALUES ( + 'ui.staff.max_recent_patrons', + oils_i18n_gettext( + 'ui.staff.max_recent_patrons', + 'Number of Retrievable Recent Patrons', + 'coust', + 'label' + ), + oils_i18n_gettext( + 'ui.staff.max_recent_patrons', + 'Number of most recently accessed patrons that can be re-retrieved ' || + 'in the staff client. A value of 0 or less disables the feature', + 'coust', + 'description' + ), + 'circ', + 'integer' +); + +COMMIT; diff --git a/Open-ILS/src/templates/staff/navbar.tt2 b/Open-ILS/src/templates/staff/navbar.tt2 index ba99321dd1..c42c8cfd65 100644 --- a/Open-ILS/src/templates/staff/navbar.tt2 +++ b/Open-ILS/src/templates/staff/navbar.tt2 @@ -114,7 +114,7 @@ [% l('Register Patron') %] -
  • +
  • @@ -122,6 +122,13 @@ [% l('Retrieve Last Patron') %]
  • +
  • + + + [% l('Retrieve Recent Patrons') %] + +
  • diff --git a/Open-ILS/web/js/ui/default/staff/circ/patron/app.js b/Open-ILS/web/js/ui/default/staff/circ/patron/app.js index 1452ce5f43..23cec43a46 100644 --- a/Open-ILS/web/js/ui/default/staff/circ/patron/app.js +++ b/Open-ILS/web/js/ui/default/staff/circ/patron/app.js @@ -292,6 +292,49 @@ function($q , $timeout , $location , egCore, egUser , $locale) { return $q.when(); } + // Set the show-recent flag true only once, then set it to + // false the first time it's used. + service.showRecentPatrons = function() { + if (service.showRecent === undefined + && Boolean($location.path().match(/search/)) + && Boolean($location.search().show_recent)) + service.showRecent = true; + + return service.showRecent; + } + + service.getRecentPatrons = function() { + // avoid getting stuck in a show-recent loop + service.showRecent = false; + + if (service.maxRecentPatrons < 1) return $q.when(); + var patrons = + egCore.hatch.getLoginSessionItem('eg.circ.recent_patrons') || []; + + // add home_ou to the list of fleshed fields for recent patrons + var fleshFields = egUser.defaultFleshFields.slice(0); + fleshFields.push('home_ou'); + + var deferred = $q.defer(); + function getNext() { + if (patrons.length == 0) { + deferred.resolve(); + return; + } + egUser.get(patrons[0], {useFields : fleshFields}).then( + function(usr) { // fetch first user + deferred.notify(usr); + patrons.splice(0, 1); // remove first user from list + getNext(); + } + ); + } + + getNext(); + return deferred.promise; + } + + // sets the primary display user, fetching data as necessary. service.setPrimary = function(id, user, force) { var user_id = id ? id : (user ? user.id() : null); @@ -301,8 +344,19 @@ function($q , $timeout , $location , egCore, egUser , $locale) { if (!user_id) return $q.reject(); // when loading a new patron, update the last patron setting - if (!service.current || service.current.id() != user_id) - egCore.hatch.setLoginSessionItem('eg.circ.last_patron', user_id); + if (service.maxRecentPatrons > 0 && + (!service.current || service.current.id() != user_id)) { + var patrons = + egCore.hatch.getLoginSessionItem('eg.circ.recent_patrons') || []; + patrons.splice(0, 0, user_id); // put this user at front + patrons.splice(service.maxRecentPatrons, 1); // remove excess + + // remove any other occurrences of user_id + var idx = patrons.indexOf(user_id, 1); + if (idx > 0) patrons.splice(idx, 1); + + egCore.hatch.setLoginSessionItem('eg.circ.recent_patrons', patrons); + } // avoid running multiple retrievals for the same patron, which // can happen during dbl-click by maintaining a single running @@ -647,6 +701,12 @@ function($scope, $q , $location , $filter , egCore , egNet , egUser , egAlertDi $scope.aous = egCore.env.aous; $scope.auth_user_id = egCore.auth.user().id(); + // max recents setting is loaded and scrubbed during startup. + // cache it in a local variable for ease of access. + egCore.org.settings('ui.staff.max_recent_patrons').then(function(s) { + patronSvc.maxRecentPatrons = s['ui.staff.max_recent_patrons']; + }); + if (patron_id) { $scope.patron_id = patron_id; return patronSvc.setPrimary($scope.patron_id) @@ -932,7 +992,7 @@ function($scope, $q, $routeParams, $timeout, $window, $location, egCore, var propagate; var propagate_inactive; - if (patronSvc.lastSearch) { + if (patronSvc.lastSearch && !patronSvc.showRecentPatrons()) { propagate = patronSvc.lastSearch.search; // home_ou needs to be treated specially propagate.home_ou = { @@ -987,6 +1047,11 @@ function($scope, $q, $routeParams, $timeout, $window, $location, egCore, provider.get = function(offset, count) { var deferred = $q.defer(); + if (patronSvc.showRecentPatrons()) { + // avoid getting stuck in show-recent mode + return patronSvc.getRecentPatrons(); + } + var fullSearch; if (patronSvc.urlSearch) { fullSearch = patronSvc.urlSearch; @@ -1766,8 +1831,9 @@ function($scope, $routeParams , $location , egCore , patronSvc) { ['$scope','$location','egCore', function($scope , $location , egCore) { - var id = egCore.hatch.getLoginSessionItem('eg.circ.last_patron'); - if (id) return $location.path('/circ/patron/' + id + '/checkout'); + var ids = egCore.hatch.getLoginSessionItem('eg.circ.recent_patrons') || []; + if (ids.length) + return $location.path('/circ/patron/' + ids[0] + '/checkout'); $scope.no_last = true; }]) diff --git a/Open-ILS/web/js/ui/default/staff/services/navbar.js b/Open-ILS/web/js/ui/default/staff/services/navbar.js index 713d9f39ec..1d90691956 100644 --- a/Open-ILS/web/js/ui/default/staff/services/navbar.js +++ b/Open-ILS/web/js/ui/default/staff/services/navbar.js @@ -116,6 +116,13 @@ angular.module('egCoreMod') $scope.op_changed = egCore.auth.OCtoken() ? true : false; $scope.username = egCore.auth.user().usrname(); $scope.workstation = egCore.auth.workstation(); + + egCore.org.settings('ui.staff.max_recent_patrons') + .then(function(s) { + var val = s['ui.staff.max_recent_patrons']; + $scope.showRecentPatron = val > 0; + $scope.showRecentPatrons = val > 1; + }); } } ); diff --git a/Open-ILS/web/js/ui/default/staff/services/startup.js b/Open-ILS/web/js/ui/default/staff/services/startup.js index 038eb2dfc2..603d040991 100644 --- a/Open-ILS/web/js/ui/default/staff/services/startup.js +++ b/Open-ILS/web/js/ui/default/staff/services/startup.js @@ -25,14 +25,15 @@ function($q, $rootScope, $location, $window, egIDL, egAuth, egEnv , egOrg var service = { promise : null } - // Load date/time format settings on all pages. Add more .push(...) - // calls to add more universal data-loading functions. + // Some org settings affect every page. Load them during startup. + // Other startup data loaders can be added by appending to egEnv.loaders. // egEnv.loaders functions must return a promise. egEnv.loaders.push( function() { return egOrg.settings([ 'webstaff.format.dates', 'webstaff.format.date_and_time', + 'ui.staff.max_recent_patrons', // affects navbar 'lib.timezone' ]).then( function(set) { @@ -40,6 +41,10 @@ function($q, $rootScope, $location, $window, egIDL, egAuth, egEnv , egOrg set['webstaff.format.dates'] || 'shortDate'; $rootScope.egDateAndTimeFormat = set['webstaff.format.date_and_time'] || 'short'; + + // default to 1 for backwards compat. + if (set['ui.staff.max_recent_patrons'] === null) + set['ui.staff.max_recent_patrons'] = 1 } ); } -- 2.11.0