From: Bill Erickson Date: Thu, 27 Oct 2016 15:23:56 +0000 (-0400) Subject: Angular selfcheck WIP X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=9d8c359a60ee6e86f6c6f3bdd9d2a2e4a0358044;p=working%2FEvergreen.git Angular selfcheck WIP Signed-off-by: Bill Erickson --- diff --git a/Open-ILS/src/templates/staff/base.tt2 b/Open-ILS/src/templates/staff/base.tt2 index 7f4c64a958..a4fcbfd187 100644 --- a/Open-ILS/src/templates/staff/base.tt2 +++ b/Open-ILS/src/templates/staff/base.tt2 @@ -25,13 +25,15 @@ - - + [% IF !ctx.hide_nav %] + + - - + + + [% END %]
[% content %]
diff --git a/Open-ILS/src/templates/staff/circ/selfcheck/index.tt2 b/Open-ILS/src/templates/staff/circ/selfcheck/index.tt2 new file mode 100644 index 0000000000..dff68f76f1 --- /dev/null +++ b/Open-ILS/src/templates/staff/circ/selfcheck/index.tt2 @@ -0,0 +1,22 @@ +[% + WRAPPER "staff/base.tt2"; + ctx.page_title = l("Self-Checkout"); + ctx.page_app = "egSelfCheckApp"; + ctx.hide_nav = 1; +%] + +[% BLOCK APP_JS %] + + + + + + +[% END %] + +
+ +[% END %] diff --git a/Open-ILS/src/templates/staff/circ/selfcheck/t_checkout.tt2 b/Open-ILS/src/templates/staff/circ/selfcheck/t_checkout.tt2 new file mode 100644 index 0000000000..da9848518c --- /dev/null +++ b/Open-ILS/src/templates/staff/circ/selfcheck/t_checkout.tt2 @@ -0,0 +1,3 @@ +

CHECKOUT

+ +Welcome, {{patron.first_given_name()}} diff --git a/Open-ILS/src/templates/staff/circ/selfcheck/t_login.tt2 b/Open-ILS/src/templates/staff/circ/selfcheck/t_login.tt2 new file mode 100644 index 0000000000..b34a166dfa --- /dev/null +++ b/Open-ILS/src/templates/staff/circ/selfcheck/t_login.tt2 @@ -0,0 +1,40 @@ +
+
+
+
+
+ [% l('Please log in with your username or library barcode.') %] + +
+
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+
+ +
+
+ [% l('Login Failed') %] +
+
+ +
+
+
+
+
+
diff --git a/Open-ILS/web/js/ui/default/staff/circ/selfcheck/app.js b/Open-ILS/web/js/ui/default/staff/circ/selfcheck/app.js new file mode 100644 index 0000000000..4428364abc --- /dev/null +++ b/Open-ILS/web/js/ui/default/staff/circ/selfcheck/app.js @@ -0,0 +1,204 @@ +/** + * Self-Checkout App + */ + +angular.module('egSelfCheckApp', ['ngRoute', 'ui.bootstrap', + 'egCoreMod', 'egUiMod', 'ngToast']) + +.config(['ngToastProvider', function(ngToastProvider) { + ngToastProvider.configure({ + verticalPosition: 'bottom', + animation: 'fade' + }); +}]) + +.config(function($routeProvider, $locationProvider, $compileProvider) { + $locationProvider.html5Mode(true); + $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|blob):/); // grid export + + // data loaded at startup which only requires an authtoken goes + // here. this allows the requests to be run in parallel instead of + // waiting until startup has completed. + var resolver = {delay : ['egCore', function(egCore) { + + // fetch the org settings we care about during egStartup + // and toss them into egCore.env as egCore.env.aous[name] = value. + // note: only load settings here needed by all tabs; load tab- + // specific settings from within their respective controllers + egCore.env.classLoaders.aous = function() { + return egCore.org.settings([ + 'opac.barcode_regex', + 'circ.selfcheck.patron_login_timeout', + 'circ.selfcheck.auto_override_checkout_events', + 'circ.selfcheck.patron_password_required', + 'circ.checkout_auto_renew_age', + 'circ.selfcheck.workstation_required', + 'circ.selfcheck.alert.popup', + 'circ.selfcheck.alert.sound', + 'credit.payments.allow', + 'circ.selfcheck.block_checkout_on_copy_status' + ]).then(function(settings) { + egCore.env.aous = settings; + }); + } + + egCore.env.loadClasses.push('aous'); + + return egCore.startup.go().then(function() { + // TODO load other startup data. + }); + }]}; + + $routeProvider.when('/circ/selfcheck/login', { + templateUrl: './circ/selfcheck/t_login', + controller: 'PatronLoginCtrl', + resolve : resolver + }); + + $routeProvider.when('/circ/selfcheck/checkout', { + templateUrl: './circ/selfcheck/t_checkout', + controller: 'CheckoutCtrl', + resolve : resolver + }); + + $routeProvider.otherwise({redirectTo : '/circ/selfcheck/login'}); +}) + +/** + * Self-Checkout Service + */ +.factory('scSvc', + ['$q','$timeout','$location','$timeout','egCore', +function($q , $timeout , $location , $timeout , egCore) { + + var service = { + login_timer : null, + login_warning_timer : null, + + // function called when login_timeout expires. + login_timer_handler : null, + + // 2 minutes, 40 seconds + login_timeout : 160000, + + // 20 second inactivity warning; total default timeout is 3 minutes. + login_timeout_warning : 20000, + }; + + + service.start_login_timer = function() { + service.login_timer = $timeout( + service.login_timer_handler, service.login_timeout + ); + console.debug('starting patron login timer'); + } + + service.reset_login_timer = function() { + if (service.login_timer) { + $timeout.cancel(service.login_timer); + } + service.start_login_timer(); + console.debug('reset patron login timer'); + } + + + service.fetch_patron = function(username, barcode, deferred) { + + egCore.net.request( + 'open-ils.actor', + 'open-ils.actor.user.retrieve_id_by_barcode_or_username', + egCore.auth.token(), barcode, username + ).then(function(patron_id) { + + if (egCore.evt.parse(patron_id)) { + deferred.reject(); + return; + } + + egCore.net.request( + 'open-ils.actor', + 'open-ils.actor.user.fleshed.retrieve.authoritative', + egCore.auth.token(), patron_id + ).then(function(patron) { + + if (egCore.evt.parse(patron)) { + deferred.reject(); + return; + } + + service.patron = patron; + deferred.resolve(); + }); + }); + } + + service.login_patron = function(username, password) { + var deferred = $q.defer(); + + // TODO: test barcode regex + var barcode = null; + + if (true) { // TODO: test password required + egCore.auth.verify({ + username : username, + barcode : barcode, + password : password + }).then( + function() { + service.fetch_patron(username, barcode, deferred); + }, + function() { deferred.reject() /* verify failed */ } + ); + } else { + service.fetch_patron(username, barcode, deferred); + } + + return deferred.promise; + } + + + return service; +}]) + +/** + * Manages tabbed patron view. + * This is the parent scope of all patron tab scopes. + * + * */ +.controller('PatronLoginCtrl', + ['$scope','$q','$location','egCore','scSvc', +function($scope, $q, $location , egCore, scSvc) { + + $scope.login = function(args) { + $scope.login_failed = false; + + if (!args.username) return; + + scSvc.login_patron(args.username, args.password).then( + function() { + console.log('HERE'); + $location.path('/circ/selfcheck/checkout'); + }, + function() { + $scope.args.password = ''; + $scope.login_failed = true; + $scope.focus_username = true; + } + ); + } +}]) + +.controller('CheckoutCtrl', + ['$scope','$q','$location','egCore','scSvc', +function($scope, $q, $location , egCore, scSvc) { + + if (!scSvc.patron) { + $location.path('/circ/selfcheck/login'); + return; + } + + $scope.patron = scSvc.patron; + +}]) + + diff --git a/Open-ILS/web/js/ui/default/staff/services/auth.js b/Open-ILS/web/js/ui/default/staff/services/auth.js index a677ff4bf2..4b64b1df70 100644 --- a/Open-ILS/web/js/ui/default/staff/services/auth.js +++ b/Open-ILS/web/js/ui/default/staff/services/auth.js @@ -81,6 +81,34 @@ function($q , $timeout , $rootScope , egNet , egHatch) { return deferred.promise; }; + /* Tests login credentials without logging in */ + service.verify = function(args) { + var deferred = $q.defer(); + egNet.request( + 'open-ils.auth', + 'open-ils.auth.authenticate.init', args.username + ).then( + function(seed) { + args.password = hex_md5(seed + hex_md5(args.password)) + return egNet.request( + 'open-ils.auth', + 'open-ils.auth.authenticate.verify', args) + } + ).then( + function(evt) { + if (evt.textcode == 'SUCCESS') { + deferred.resolve(); + } else { + console.error('login verify failed ' + js2JSON(evt)); + deferred.reject(); + } + } + ); + + return deferred.promise; + }; + + /** * Returns a promise, which is resolved on successful * login and rejected on failed login.