#admin-workstation-container .new-entry {
margin-top: 10px;
padding-top: 10px;
- border-top: 1px solid #F5F5F5;
+ border-top: 2px solid #F5F5F5;
}
</style>
<div class="row">
<div class="col-md-6">
- [% l('Registered Workstations') %]
+ <div class="checkbox">
+ <label>
+ <input type="checkbox" ng-class="{disabled : !userHasAdminPerm}"
+ ng-model="hatchRequired" ng-change="updateHatchRequired()">
+[% l('This workstation uses a remote print / storage service ("Hatch")?') %]
+ </label>
+ </div>
+ </div><!-- row -->
+ </div>
+ <div class="row">
+ <div class="col-md-6">
+ <input type='text' class='form-control'
+ ng-disabled="!hatchRequired || !userHasRegPerm"
+ title="[% l('Hatch URL') %]"
+ placeholder="[% l('Hatch URL') %]"
+ ng-change='updateHatchURL()' ng-model='hatchURL'/>
+ </div>
+ </div>
+
+ <div class="row new-entry">
+ <div class="col-md-6">
+ [% l('Workstations Registered With This Computer') %]
</div>
</div>
<div class="row">
<div class="col-md-6">
- <div class="input-group">
- <select class="form-control" ng-model="selectedWS">
- <option ng-repeat="ws in workstations" value="{{ws.id}}"
- ng-selected="ws.id == defaultWS.id">
- {{getWSLabel(ws)}}
- </option>
- </select>
- <div class="input-group-btn">
- <button class="btn btn-default">
- [% l('Login') %]
- </button>
- </div>
- <div class="input-group-btn">
- <button class="btn btn-default" ng-click="setDefaultWS()">
- [% l('Set as Default') %]
- </button>
- </div>
- <div class="input-group-btn">
- <button class="btn btn-default btn-warning">
- [% l('Delete') %]
- </button>
- </div>
- </div>
+ <select class="form-control" ng-model="selectedWS">
+ <option ng-repeat="ws in workstations" value="{{ws}}"
+ ng-selected="ws == selectedWS">
+ {{getWSLabel(ws)}}
+ </option>
+ </select>
+ </div>
+ </div>
+
+ <div class="row">
+ <div class="col-md-6">
+ <button class="btn btn-default" ng-click="useWS()">
+ [% l('Use Now') %]
+ </button>
+ <button class="btn btn-default" ng-click="setDefaultWS()">
+ [% l('Mark As Default') %]
+ </button>
+ <button class="btn btn-default btn-danger disabled">
+ [% l('Delete') %]
+ </button>
</div>
</div>
<div class="row new-entry">
<div class="col-md-6">
- [% l('Register a New Workstation') %]
+ [% l('Register a New Workstation For This Computer') %]
</div>
</div>
<div class="row">
<div class="input-group-btn">
<eg-org-selector
selected="contextOrg"
- org-changed="wsOrgChanged">
+ hidden-test="wsOrgHidden">
</eg-org-selector>
</div>
<input type='text' class='form-control'
</div>
</div>
-
- <div class="row new-entry">
- <div class="col-md-6">
- <div class="checkbox">
- <label>
- <input type="checkbox" ng-class="{disabled : !userHasAdminPerm}"
- ng-model="hatchRequired" ng-change="updateHatchRequired()">
-[% l('This workstation uses a remote print / storage service ("Hatch")?') %]
- </label>
- </div>
- </div><!-- row -->
- </div>
- <div class="row">
- <div class="col-md-6">
- <input type='text' class='form-control'
- ng-disabled="!hatchRequired || !userHasAdminPerm"
- title="[% l('Hatch URL') %]"
- placeholder="[% l('Hatch URL') %]"
- ng-change='updateHatchURL()' ng-model='hatchURL'/>
- </div>
- </div>
-
<div class="row new-entry">
<div class="col-md-6">
<span class="glyphicon glyphicon-print"></span>
The input IDs are there to match the labels.
They are not referenced in the Login controller.
-->
- <form ng-submit="login(args)" name="login-form">
- <div class="form-group row">
+ <form ng-submit="login(args)" name="login-form" class="form-horizontal" role="form">
+ <div class="form-group">
<label class="col-md-4 control-label" for="login-username">[% l('Username') %]</label>
<div class="col-md-8">
<input type="text" id="login-username" class="form-control"
</div>
</div>
- <div class="form-group row">
+ <div class="form-group">
<label class="col-md-4 control-label" for="login-password">[% l('Password') %]</label>
<div class="col-md-8">
<input type="password" id="login-password" class="form-control"
</div>
</div>
- <div class="form-group row">
- <label class="col-md-4 control-label" for="login-workstation">[% l('Workstation') %]</label>
+ <div class="form-group">
+ <label class="col-md-4 control-label"
+ for="login-workstation">[% l('Workstation') %]</label>
<div class="col-md-8">
- <select ng-model="workstations" class="form-control">
+ <select class="form-control" ng-model="args.workstation"
+ ng-options="ws for ws in workstations">
+ <option>[% l('Select Workstation') %]</option>
</select>
- <div>
+ </div>
</div>
- <div class="form-group row">
- <div class="col-md-12">
- <button type="submit" class="btn">[% l('Sign in') %]</button>
- <span ng-show="loginFailed">[% l('Login Failed') %]</span>
+ <div class="form-group">
+ <div class="col-md-offset-4 col-md-4">
+ <button type="submit" class="btn btn-default">[% l('Sign in') %]</button>
+ </div>
+ <div class="col-md-4">
+ <span ng-show="loginFailed" class="label-warning">[% l('Login Failed') %]</span>
</div>
</div>
+
</form>
</fieldset>
</div>
}])
.controller('SplashCtrl',
- ['$scope','egPrintStore','egAuth','egOrg','egPerm','egEvent','egNet','egAppStrings',
-function($scope , egPrintStore , egAuth , egOrg , egPerm , egEvent , egNet , egAppStrings) {
+ ['$scope','$window','$location','egPrintStore','egAuth','egOrg','egPerm','egEvent','egNet','egAppStrings',
+function($scope , $window , $location , egPrintStore , egAuth , egOrg , egPerm , egEvent , egNet , egAppStrings) {
+ var allWorkstations = [];
var permMap = {};
var wsPerms = [
'ADMIN_WORKSTATION', //FIXME: create
'DELETE_WORKSTATION'
]
+ $scope.contextOrg = egOrg.get(egAuth.user().ws_ou());
+
$scope.userHasAdminPerm = false;
- egPerm.hasPermAt(wsPerms)
- .then(function(permMap) {
- //$scope.userHasAdminPerm = bool
+ egPerm.hasPermAt('REGISTER_WORKSTATION', true)
+ .then(function(orgList) {
+
+ // hide orgs in the context org selector where this login
+ // does not have the reg_ws perm
+ $scope.wsOrgHidden = function(id) {
+ return orgList.indexOf(id) == -1;
+ }
+ $scope.userHasRegPerm =
+ orgList.indexOf($scope.contextOrg.id()) > -1;
});
// fetch the stored WS info
egPrintStore.getItem('eg.conf.workstation.all')
.then(function(all) {
- $scope.workstations = all || [];
+ allWorkstations = all || [];
+ $scope.workstations =
+ allWorkstations.map(function(w) { return w.name });
return egPrintStore.getItem('eg.conf.workstation.default');
})
.then(function(def) {
- console.log('loaded default WS ' + ws);
- $scope.defaultWS = def
+ $scope.defaultWS = def;
+ $scope.activeWS = $scope.selectedWS = egAuth.workstation() || def;
});
- if (ws = egAuth.workstation()) {
- $scope.activeWS = ws;
- $scope.contextOrg = egOrg.get(ws.owning_lib);
- }
-
$scope.getWSLabel = function(ws) {
- return ws.name; // FIXME: appstrings
+ return ws; // FIXME: appstrings
}
$scope.setDefaultWS = function() {
- console.log('selected ' + $scope.selectedWS);
- var ws = $scope.workstations.filter(
- function(w) { return w.id == $scope.selectedWS })[0];
egPrintStore.setItem(
- 'eg.conf.workstation.default',
- // avoid storing angular $$hashkey
- {id : ws.id, name : ws.name, owning_lib : ws.owning_lib})
- .then(function() { $scope.defaultWS = ws });
+ 'eg.conf.workstation.default', $scope.selectedWS)
+ .then(function() { $scope.defaultWS = $scope.selectedWS });
+ }
+
+ // redirect the user to the login page using the current
+ // workstation as the workstation URL param
+ $scope.useWS = function() {
+ $window.location.href = $location
+ .path('/login')
+ .search({ws : $scope.selectedWS})
+ .absUrl();
}
$scope.registerWS = function() {
var evt = egEvent.parse(resp);
if (evt) {
if (evt.textcode == 'WORKSTATION_NAME_EXISTS') {
+ console.log(evt);
// TODO: override call
} else {
// TODO: improvide permission error display
alert(evt);
}
} else if (resp) {
- $scope.workstations.push(
- { id : resp,
- name : newName,
- owning_lib : $scope.contextOrg.id()
+ $scope.workstations.push(newName);
+ allWorkstations.push({
+ id : resp,
+ name : newName,
+ owning_lib : $scope.contextOrg.id()
+ });
+
+ egPrintStore.setItem(
+ 'eg.conf.workstation.all', allWorkstations)
+ .then(function() {
+ if (allWorkstations.length == 1) {
+ // first one registerd, also mark it as the default
+ $scope.selectedWS = newName;
+ $scope.setDefaultWS();
}
- );
- return egPrintStore.setItem(
- 'eg.conf.workstation.all', $scope.workstations);
+ });
}
});
}
egPrintStore.getItem('eg.conf.workstation.all')
.then(function(all) {
- $scope.workstations = ['abc', 'dev', 'foo']; // TODO
if (all && all.length) {
$scope.workstations = all.map(function(a) { return a.name });
}
} else {
// no workstation requested; use the default
- egPrintStore.get('eg.conf.workstation.all.default')
+ egPrintStore.getItem('eg.conf.workstation.default')
.then(function(ws) {
- $scope.args = {workstation : ws.name}
+ $scope.args = {workstation : ws}
});
}
}
* done inside a promise resolver, another $digest() loop will
* run and pick up our changes. No $scope.$apply() needed.
*/
- egStartup.go().then(
- function() {
-
-
- // login page will not have a cached user
- if (!egAuth.user()) return;
-
- $scope.username = egAuth.user().usrname();
-
- // TODO: move workstation into egAuth
- if (ws = egAuth.workstation())
- $scope.workstation = ws.name();
- }
- );
+ if ($location.path() != '/login') {
+ // avoiding rending user info on the login page
+
+ egStartup.go().then(
+ function() {
+ $scope.username = egAuth.user().usrname();
+ $scope.workstation = egAuth.workstation();
+ }
+ );
+ }
}
// minify-safe dependency injection
.constant('EG_AUTH_COOKIE', 'ses')
.factory('egAuth',
- ['$q','$cookies','egNet','EG_AUTH_COOKIE',
-function($q , $cookies , egNet , EG_AUTH_COOKIE) {
+ ['$q','$cookies','egNet','EG_AUTH_COOKIE','egPrintStore',
+function($q , $cookies , egNet , EG_AUTH_COOKIE , egPrintStore) {
var service = {
- // the currently active user object
+ // the currently active user (au) object
user : function() {
return this._user;
},
return $cookies[EG_AUTH_COOKIE];
},
- // the currently active workstation
- workstation : function(ws) {
- if (ws) this._workstation = ws;
- return this._workstation;
+ // the currently active workstation name
+ // For ws_ou or wsid(), see egAuth.user().ws_ou(), etc.
+ workstation : function() {
+ return this.ws;
}
};
var token = service.token();
if (token) {
+
egNet.request(
'open-ils.auth',
- 'open-ils.auth.session.retrieve', token).then(
- function(user) {
- if (user && user.classname) {
- service._user = user;
- deferred.resolve();
+ 'open-ils.auth.session.retrieve', token)
+
+ .then(function(user) {
+ if (user && user.classname) {
+ // authtoken test succeeded
+ service._user = user;
+
+ if (user.wsid()) {
+ // user previously logged in with a workstation.
+ // Find the workstation name from the list
+ // of configured workstations
+ egPrintStore.getItem('eg.conf.workstation.all')
+ .then(function(all) {
+ if (all) {
+ var ws = all.filter(
+ function(w) {return w.id == user.wsid()})[0];
+ if (ws) service.ws = ws.name;
+ }
+ deferred.resolve(); // found WS
+ });
} else {
- delete $cookies[EG_AUTH_COOKIE];
- deferred.reject();
+ deferred.resolve(); // no WS
}
+ } else {
+ // authtoken test failed
+ delete $cookies[EG_AUTH_COOKIE];
+ deferred.reject();
}
- );
+ });
} else {
+ // no authtoken to test
deferred.reject();
}
'open-ils.auth.authenticate.complete', args).then(
function(evt) {
if (evt.textcode == 'SUCCESS') {
+ service.ws = args.workstation;
$cookies[EG_AUTH_COOKIE] = evt.payload.authtoken;
deferred.resolve();
} else {
* hash of perm => orgList maps. If a string, the response is the
* org list for the requested perm.
*/
- service.hasPermAt = function(permList) {
+ service.hasPermAt = function(permList, asId) {
var deferred = $q.defer();
var isArray = true;
if (!angular.isArray(permList)) {
angular.forEach(permList, function(perm) {
var all = [];
angular.forEach(resp[perm], function(oneOrg) {
- all = all.concat(egOrg.descendants(oneOrg));
+ all = all.concat(egOrg.descendants(oneOrg, asId));
});
answer[perm] = all;
});
ws_ou = egAuth.user().ws_ou();
- return service.hasPermAt(permList)
+ return service.hasPermAt(permList, true)
.then(function(orgMap) {
- angular.forEach(orgMap, function(orgs, perm) {
- // each permission is mapped to a flat list of org units,
+ angular.forEach(orgMap, function(orgIds, perm) {
+ // each permission is mapped to a flat list of org unit ids,
// including descendants. See if our workstation org unit
// is in the list.
- angular.forEach(orgs, function(org) {
- if ((''+org.id()) == (''+ws_ou))
- response[perm] = true;
- });
- if (response[perm] !== true)
- response[perm] = false;
+ response[perm] = orgIds.indexOf(ws_ou) > -1;
});
if (!isArray) response = response[permList[0]];
return response;
* list of classes to load on every page, regardless of whether
* a page-specific list is provided.
*/
- service.loadClasses = ['aou', 'aws'];
+ service.loadClasses = ['aou'];
/*
* Default class loaders. Only add classes directly to this file
function(tree) {service.absorbTree(tree, 'aou')}
);
},
- aws : function() {
- // FIXME: this will come from local storage, not the server
- // load thee workstation for the authenticated user and
- // insert the value into egAuth.workstation().
- // TODO: auth.session.retrieve should be capable of returning
- // the session with the workstation fleshed.
- if (!egAuth.user().wsid()) {
- // nothing to fetch.
- return $q.when();
- }
- return egPCRUD.retrieve('aws', egAuth.user().wsid())
- .then(function(ws) {egAuth.workstation(ws)});
- }
};
return service;
return deferred.promise;
}
-
return service;
}]);
$rootScope.$on('egAuthExpired', function() {service.expiredAuthHandler()});
service.go = function () {
- if (this.promise) {
+ if (service.promise) {
// startup already started, return our existing promise
- return this.promise;
+ return service.promise;
}
// create a new promise and fire off startup
var deferred = $q.defer();
- this.promise = deferred.promise;
+ service.promise = deferred.promise;
// IDL parsing is sync. No promises required
egIDL.parseIDL();
}
);
- return this.promise;
+ return service.promise;
}
return service;
transclude : true,
scope : {
selected : '=', // defaults to workstation or root org
- orgChanged : '=' // called when selected org changes
+
+ // Each org unit is passed into this function and, for
+ // any org units where the response value is true, the
+ // org unit will not be added to the selector.
+ hiddenTest : '=',
},
// any reason to move this into a TT2 template?
+ '<span class="caret"></span>'
+ '</button>'
+ '<ul class="dropdown-menu">'
- + '<li ng-repeat="org in orgList">'
+ + '<li ng-repeat="org in orgList" ng-hide="hiddenTest(org.id)">'
+ '<a href="" ng-click="orgChanged(org)"'
+ 'style="padding-left: {{org.depth * 10 + 5}}px">'
+ '{{org.shortname}}'