WRAPPER "staff/base.tt2";
ctx.page_title = l("Self-Checkout");
ctx.page_app = "egSelfCheckApp";
+ ctx.page_ctrl = "SelfCheckCtrl";
ctx.hide_nav = 1;
%]
<script>
angular.module('egCoreMod').run(['egStrings', function(s) {
+ s.CONFIRM_TIMEOUT_TITLE =
+ "[% l('Inactivity Warning') %]";
+ s.CONFIRM_TIMEOUT_MSG =
+ "[% l('Your login session will soon timeout due to inactivity.') %]";
+ s.CONFIRM_TIMEOUT_CONTINUE = "[% l('Continue Session') %]";
+ s.CONFIRM_TIMEOUT_LOGOUT = "[% l('Logout') %]";
}]);
</script>
[% END %]
-<div ng-view></div>
+<div class="row" ng-if="!is_login_page()">
+ <div class="col-md-12">
+ <div class="row">
+ <div>[% l('Welcome, [_1]', '{{patron().first_given_name()}}') %]</div>
+ </div>
+ <div class="row">
+ <!-- TODO: header image stuff -->
+ <div class="col-md-5"></div>
+ <div class="col-md-2">
+ <input
+ class="form-control"
+ focus-me="scanbox.focus"
+ ng-model="scanbox.text"
+ ng-disabled="scanbox.disabled()"
+ type="text"/>
+ </div>
+ <div class="col-md-5"></div>
+ </div>
+ </div>
+</div>
+
+<div class="row">
+ <div class="col-md-8">
+ <div ng-view></div>
+ </div>
+ <div class="col-md-4" ng-if="!is_login_page()">
+ <fieldset>
+ <legend>[% l('Items Checked Out') %]</legend>
+ <div>[% l('Total items this session: [_1]',
+ '{{counts("session_circ")}}') %]</div>
+ <div>[% l('Total items on account: [_1]',
+ '{{counts("total_circ")}}') %]</div>
+ <div><button class="btn btn-success">
+ [% l('View Items Out') %]</button></div>
+ </fieldset>
+ <fieldset>
+ <legend>[% l('Holds') %]</legend>
+ <div>[% l('You have [_1] item(s) ready for pickup',
+ '{{counts("hold_ready")}}') %]</div>
+ <div>[% l('You have [_1] total holds',
+ '{{counts("total_hold")}}') %]</div>
+ <div><button class="btn btn-success">
+ [% l('View Holds') %]</button></div>
+ </fieldset>
+ <fieldset>
+ <legend>[% l('Fines') %]</legend>
+ <div><button class="btn btn-success">
+ [% l('View Details') %]</button>
+ </div>
+ </fieldset>
+ </div>
+</div>
[% END %]
* Self-Checkout App
*/
-angular.module('egSelfCheckApp', ['ngRoute', 'ui.bootstrap',
- 'egCoreMod', 'egUiMod', 'ngToast'])
+angular.module('egSelfCheckApp',
+ ['ngRoute', 'ui.bootstrap', 'egCoreMod', 'egUiMod', 'ngToast'])
.config(['ngToastProvider', function(ngToastProvider) {
ngToastProvider.configure({
.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
* Self-Checkout Service
*/
.factory('scSvc',
- ['$q','$timeout','$location','$timeout','egCore',
-function($q , $timeout , $location , $timeout , egCore) {
+ ['$q','$timeout','$window','$location','$timeout','egCore','egConfirmDialog',
+function($q , $timeout , $window , $location , $timeout , egCore , egConfirmDialog) {
var service = {
login_timer : null,
// 20 second inactivity warning; total default timeout is 3 minutes.
login_timeout_warning : 20000,
+
+ session_circ_count : 0,
+ total_circ_count : 0,
+ hold_ready_count : 0,
+ total_hold_count : 0,
+
};
+ service.show_timeout_warning = function() {
+ // TODO: force logout after warning timeout
+
+ egConfirmDialog.open(
+ egCore.strings.CONFIRM_TIMEOUT_TITLE,
+ egCore.strings.CONFIRM_TIMEOUT_MSG,
+ { ok : function() { service.reset_login_timer() },
+ cancel : function() { service.logout_patron() }
+ },
+ egCore.strings.CONFIRM_TIMEOUT_CONTINUE,
+ egCore.strings.CONFIRM_TIMEOUT_LOGOUT
+ );
+
+ service.login_warning_timer = $timeout(
+ service.logout_patron, service.login_timeout_warning
+ );
+ }
service.start_login_timer = function() {
service.login_timer = $timeout(
- service.login_timer_handler, service.login_timeout
+ service.show_timeout_warning, service.login_timeout
);
console.debug('starting patron login timer');
}
service.reset_login_timer = function() {
if (service.login_timer) {
$timeout.cancel(service.login_timer);
+ service.login_timer = null;
+ }
+ if (service.login_warning_timer) {
+ $timeout.cancel(service.login_warning_timer);
+ service.login_warning_timer = null;
}
service.start_login_timer();
console.debug('reset patron login timer');
}
- service.fetch_patron = function(username, barcode, deferred) {
+ service.fetch_patron = function(username, barcode) {
+ var evt;
- egCore.net.request(
+ return 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;
+ if (evt = egCore.evt.parse(patron_id)) {
+ console.warn(evt);
+ return $q.reject(evt);
}
- egCore.net.request(
+ 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;
+ if (evt = egCore.evt.parse(patron)) {
+ console.warn(evt);
+ return $q.reject(evt);
}
service.patron = patron;
- deferred.resolve();
+ service.start_login_timer();
});
});
}
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({
+ return egCore.auth.verify({
username : username,
barcode : barcode,
password : password
- }).then(
- function() {
- service.fetch_patron(username, barcode, deferred);
- },
- function() { deferred.reject() /* verify failed */ }
- );
+ }).then(function() {
+ return service.fetch_patron(username, barcode);
+ });
} else {
- service.fetch_patron(username, barcode, deferred);
+ return service.fetch_patron(username, barcode);
}
-
- return deferred.promise;
}
+ service.logout_patron = function() {
+ // force a page reload to clear all cached data.
+ $window.location.href = $location.absUrl().replace(
+ /\/selfcheck\/.*/, '/selfcheck/login');
+ }
return service;
}])
+/* Page-level parent controller for all self-check controllers.
+ * Handles navigation, scanbox, and page wrapper display.
+ * This controller is instantiated once per page load, not per navigation.
+ */
+
+.controller('SelfCheckCtrl',
+ ['$scope','$q','$location','egCore','scSvc',
+function($scope, $q, $location , egCore, scSvc) {
+
+ // data shared with sub-scopes
+ $scope.counts = function(type) {
+ return scSvc[type + '_count'];
+ }
+
+ $scope.is_login_page = function() {
+ return $location.path() == '/circ/selfcheck/login';
+ }
+
+ $scope.scanbox = {
+ text : '',
+ focus : false,
+ disabled : function() {
+ // TODO: inactive barcode, etc.
+ return false;
+ }
+ }
+
+ $scope.patron = function() { return scSvc.patron }
+
+}])
+
+
/**
* Manages tabbed patron view.
* This is the parent scope of all patron tab scopes.
scSvc.login_patron(args.username, args.password).then(
function() {
- console.log('HERE');
$location.path('/circ/selfcheck/checkout');
},
function() {
return;
}
- $scope.patron = scSvc.patron;
+ scSvc.reset_login_timer();
+ $scope.scanbox.focus = true;
}])