From 4962d99be33190e5287c6e875bdee7a5ac0e5b02 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 Signed-off-by: Kathy Lussier Signed-off-by: Jason Etheridge --- 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 | 5 +- .../web/js/ui/default/staff/services/navbar.js | 7 ++ .../js/ui/default/staff/services/patron_search.js | 81 ++++++++++++++++++++-- .../web/js/ui/default/staff/services/startup.js | 9 ++- 7 files changed, 151 insertions(+), 9 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 a5e32fe582..5505325bef 100644 --- a/Open-ILS/src/sql/Pg/950.data.seed-values.sql +++ b/Open-ILS/src/sql/Pg/950.data.seed-values.sql @@ -17161,3 +17161,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 1142bcc69d..16cd665fe5 100644 --- a/Open-ILS/src/templates/staff/navbar.tt2 +++ b/Open-ILS/src/templates/staff/navbar.tt2 @@ -146,7 +146,7 @@ [% l('Register Patron') %] -
  • +
  • @@ -154,6 +154,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 e942a0c97b..e7d6430453 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 @@ -1175,8 +1175,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 41d5ed87eb..bae8190944 100644 --- a/Open-ILS/web/js/ui/default/staff/services/navbar.js +++ b/Open-ILS/web/js/ui/default/staff/services/navbar.js @@ -109,6 +109,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/patron_search.js b/Open-ILS/web/js/ui/default/staff/services/patron_search.js index ed5c86b3a9..97c91529a7 100644 --- a/Open-ILS/web/js/ui/default/staff/services/patron_search.js +++ b/Open-ILS/web/js/ui/default/staff/services/patron_search.js @@ -74,6 +74,60 @@ function($q , $timeout , $location , egCore, egUser , egConfirmDialog , $locale return $q.when(); } + 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') || []; + + // Ensure the cached list is no bigger than the current config. + // This can happen if the setting changes while logged in. + patrons = patrons.slice(0, service.maxRecentPatrons); + + // 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; + } + + service.addRecentPatron = function(user_id) { + if (service.maxRecentPatrons < 1) return; + + // no need to re-track same user + if (service.current && service.current.id() == user_id) return; + + 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 this user, which may have been + // added before the most recent user. + var idx = patrons.indexOf(user_id, 1); + if (idx > 0) patrons.splice(idx, 1); + + egCore.hatch.setLoginSessionItem('eg.circ.recent_patrons', patrons); + } + // sets the primary display user, fetching data as necessary. service.setPrimary = function(id, user, force) { var user_id = id ? id : (user ? user.id() : null); @@ -82,9 +136,7 @@ function($q , $timeout , $location , egCore, egUser , egConfirmDialog , $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); + service.addRecentPatron(user_id); // avoid running multiple retrievals for the same patron, which // can happen during dbl-click by maintaining a single running @@ -457,6 +509,22 @@ function($scope, $q, $routeParams, $timeout, $window, $location, egCore, selectedItems : function() {return []} } + // Max recents setting is loaded and scrubbed during egStartup. + // Copy it to a local variable here for ease of local access. + egCore.org.settings('ui.staff.max_recent_patrons').then(function(s) { + patronSvc.maxRecentPatrons = s['ui.staff.max_recent_patrons']; + }); + + // The first time we encounter the show-recent CGI param, put the + // service into show-recent mode. The first time recents are shown, + // the service is taken out of show-recent mode so the page does not + // get stuck in a show-recent loop. + if (patronSvc.showRecent === undefined + && Boolean($location.path().match(/search/)) + && Boolean($location.search().show_recent)) { + patronSvc.showRecent = true; + } + // Handle URL-encoded searches if ($location.search().search) { console.log('URL search = ' + $location.search().search); @@ -479,7 +547,7 @@ function($scope, $q, $routeParams, $timeout, $window, $location, egCore, var propagate; var propagate_inactive; - if (patronSvc.lastSearch) { + if (patronSvc.lastSearch && !patronSvc.showRecent) { propagate = patronSvc.lastSearch.search; // home_ou needs to be treated specially propagate.home_ou = { @@ -525,6 +593,11 @@ function($scope, $q, $routeParams, $timeout, $window, $location, egCore, provider.get = function(offset, count) { var deferred = $q.defer(); + if (patronSvc.showRecent) { + // avoid getting stuck in show-recent mode + return patronSvc.getRecentPatrons(); + } + var fullSearch; if (patronSvc.urlSearch) { fullSearch = patronSvc.urlSearch; 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 958ff9fe31..07e1f8c0fe 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