<eg-grid
idl-class="au" sort="[]" id-field="id"
- main-label="[% l('Patron Search Resuts') %]"
+ initial-offset="cachedSearchOffset"
+ features="-sort,-display"
+ main-label="[% l('Patron Search Results') %]"
items-provider="patronSearchGridProvider"
persist-key="eg.staff.circ.patron.search">
- <eg-grid-field label="[% ('ID') %]" path='id'></eg-grid-field>
- <eg-grid-field label="[% ('Card') %]" path='card.barcode'></eg-grid-field>
- <eg-grid-field label="[% ('Last Name') %]" path='family_name'></eg-grid-field>
- <eg-grid-field label="[% ('First Name') %]" path='first_given_name'></eg-grid-field>
- <eg-grid-field label="[% ('Middle Name') %]" path='second_given_name'></eg-grid-field>
- <eg-grid-field label="[% ('DoB') %]" path='dob'></eg-grid-field>
- <eg-grid-field label="[% ('Home Library') %]" path='home_ou.shortname'></eg-grid-field>
- <eg-grid-field label="[% ('Created On') %]" path='create_date'></eg-grid-field>
+ <eg-grid-field label="[% ('ID') %]" path='id' visible></eg-grid-field>
+ <eg-grid-field label="[% ('Card') %]" path='card.barcode' visible></eg-grid-field>
+ <eg-grid-field label="[% ('Last Name') %]" path='family_name' visible sortable></eg-grid-field>
+ <eg-grid-field label="[% ('First Name') %]" path='first_given_name' visible sortable></eg-grid-field>
+ <eg-grid-field label="[% ('Middle Name') %]" path='second_given_name' visible sortable></eg-grid-field>
+ <eg-grid-field label="[% ('DoB') %]" path='dob' visible sortable></eg-grid-field>
+ <eg-grid-field label="[% ('Home Library') %]" path='home_ou.shortname' visible></eg-grid-field>
+ <eg-grid-field label="[% ('Created On') %]" path='create_date' visible sortable></eg-grid-field>
- <eg-grid-field label="[% ('Mailing:Street 1') %]" path='mailing_address.street1'></eg-grid-field>
- <eg-grid-field label="[% ('Mailing:Street 2') %]" path='mailing_address.street2' display="false"></eg-grid-field>
- <eg-grid-field label="[% ('Mailing:City') %]" path='mailing_address.city' display="false"></eg-grid-field>
- <eg-grid-field label="[% ('Mailing:County') %]" path='mailing_address.county' display="false"></eg-grid-field>
- <eg-grid-field label="[% ('Mailing:State') %]" path='mailing_address.state' display="false"></eg-grid-field>
- <eg-grid-field label="[% ('Mailing:Zip') %]" path='mailing_address.post_code' display="false"></eg-grid-field>
+ <eg-grid-field label="[% ('Mailing:Street 1') %]" path='mailing_address.street1' visible></eg-grid-field>
+ <eg-grid-field label="[% ('Mailing:Street 2') %]" path='mailing_address.street2'></eg-grid-field>
+ <eg-grid-field label="[% ('Mailing:City') %]" path='mailing_address.city'></eg-grid-field>
+ <eg-grid-field label="[% ('Mailing:County') %]" path='mailing_address.county'></eg-grid-field>
+ <eg-grid-field label="[% ('Mailing:State') %]" path='mailing_address.state'></eg-grid-field>
+ <eg-grid-field label="[% ('Mailing:Zip') %]" path='mailing_address.post_code'></eg-grid-field>
- <eg-grid-field label="[% ('Billing:Street 1') %]" path='billing_address.street1' display="false"></eg-grid-field>
- <eg-grid-field label="[% ('Billing:Street 2') %]" path='billing_address.street2' display="false"></eg-grid-field>
- <eg-grid-field label="[% ('Billing:City') %]" path='billing_address.city' display="false"></eg-grid-field>
- <eg-grid-field label="[% ('Billing:County') %]" path='billing_address.county' display="false"></eg-grid-field>
- <eg-grid-field label="[% ('Billing:State') %]" path='billing_address.state' display="false"></eg-grid-field>
- <eg-grid-field label="[% ('Billing:Zip') %]" path='billing_address.post_code' display="false"></eg-grid-field>
+ <eg-grid-field label="[% ('Billing:Street 1') %]" path='billing_address.street1'></eg-grid-field>
+ <eg-grid-field label="[% ('Billing:Street 2') %]" path='billing_address.street2'></eg-grid-field>
+ <eg-grid-field label="[% ('Billing:City') %]" path='billing_address.city'></eg-grid-field>
+ <eg-grid-field label="[% ('Billing:County') %]" path='billing_address.county'></eg-grid-field>
+ <eg-grid-field label="[% ('Billing:State') %]" path='billing_address.state'></eg-grid-field>
+ <eg-grid-field label="[% ('Billing:Zip') %]" path='billing_address.post_code'></eg-grid-field>
</eg-grid>
.config(function($routeProvider, $locationProvider, $compileProvider) {
$locationProvider.html5Mode(true);
- $compileProvider.aHrefSanitizationWhitelist(/^\s*(blob):/); // grid export
+ $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
checkout_overrides : {},
// keep a cache of the patron search results
- patrons : egList.create({indexFieldAsFunction : true}), // patron.id()
+ patrons : [],
checkouts : egList.create(),
items_out : egList.create({indexFieldAsFunction : true}), // circ.id()
holds : egList.create(),
$scope.initTab('search');
$scope.focusMe = true;
- $scope.patrons = patronSvc.patrons;
+ $scope.args = $location.search();
+
+ console.log('PatronSearchCtrl');
// our data provider is a modified flat data provider
var provider = egGridFlatDataProvider.instance({});
- provider.get = function(index, count, onitem) {
- angular.forEach(
- $scope.patrons.items.slice(index, index + count),
- function(item) { onitem(item) }
+ provider.select = function(items) {
+ if (items[0]) {
+ var user = items[0];
+ patronSvc.setDefault(null, user);
+ }
+ }
+
+ provider.get = function(offset, count, onitem) {
+ console.log('get ' + $location.search() + ' : ' + provider._revision);
+ var deferred = $q.defer();
+
+ /*
+ if (args.id) {
+ retrieveUsers([args.id]);
+ egUser.get(id).then(function(user) {
+ patronSvc.localFlesh(user);
+ $scope.patrons.items[idx] = user;
+ });
+
+ } else {
+ sendSearch(args);
+ }
+ */
+
+ var search = compileSearch($location.search());
+
+ /*
+ if (Object.keys(search).length == 0 &&
+ offset == patronSvc.cachedSearchOffset &&
+ patronSvc.patrons.length) {
+ // accessing the page without a cached search
+ // see if we have a cached result set
+ angular.forEach(patronSvc.patrons, function(p) { onitem(p) });
+ return;
+ }
+ */
+
+ //patronSvc.cachedSearchOffset = offset;
+ patronSvc.patrons = [];
+
+ var home_ou = search.home_ou;
+ delete search.home_ou;
+ var inactive = search.inactive;
+ delete search.inactive;
+
+ console.debug('patron search ' + js2JSON(search));
+ egNet.request(
+ 'open-ils.actor',
+ 'open-ils.actor.patron.search.advanced.fleshed',
+ egAuth.token(),
+ search,
+ count,
+ compileSort(),
+ inactive,
+ home_ou,
+ egUser.defaultFleshFields,
+ offset
+
+ ).then(
+ function() { deferred.resolve() },
+ null, // onerror
+ function(user) {
+ patronSvc.localFlesh(user); // inline
+ deferred.notify(user);
+ }
);
+
+ return deferred.promise;
};
+
provider.itemFieldValue = function(item, column) {
return provider.nestedItemFieldValue(item, column);
};
$scope.org_units = egEnv.aou.list.map(
function(org) {return {shortname : org.shortname(), id : org.id() }})
- // TODO: experiment
- // if this is useful, it should be moved into a service.
- $scope.tips = {
- dismiss : function(tip) {
- $window.localStorage.setItem('eg.tips.' + tip, 1);
- },
- dismissed : function(tip) {
- return $window.localStorage.getItem('eg.tips.' + tip);
- }
- // TODO: function to reset all tips
- };
-
// TODO:
// another experiment -- user prefs in localStorage -- this should
// be a service, which can also check (certain) user/org settings
$scope.showExtras = JSON.parse($window.localStorage.getItem(
'eg.prefs.circ.patron.search.showExtras')) || false;
+
// map form arguments into search params
function compileSearch(args) {
var search = {};
angular.forEach(args, function(val, key) {
if (!val) return;
if (key == 'profile') {
- search.profile = {value : args.profile.id, group : 0};
+ //search.profile = {value : args.profile.id, group : 0};
+ search.profile = {value : search.profile, group : 0};
} else if (key == 'home_ou') {
- search.home_ou = args.home_ou.id; // passed separately
+ //search.home_ou = args.home_ou.id; // passed separately
} else if (key == 'inactive') {
search.inactive = val;
} else {
return search;
}
- // send compiled search; get user IDs
- /*
- function __sendSearch(args) {
- search = compileSearch(args);
-
- var home_ou = search.home_ou;
- delete search.home_ou;
- var inactive = search.inactive;
- delete search.inactive;
+ function compileSort() {
- console.debug('patron search ' + js2JSON(search));
- egNet.request(
- 'open-ils.actor',
- 'open-ils.actor.patron.search.advanced',
- egAuth.token(), search, 100,
- [ // sort
+ if (!$scope.patronSearchGridProvider.sort.length) {
+ return [ // default
"family_name ASC",
"first_given_name ASC",
"second_given_name ASC",
"dob DESC"
- ],
- inactive,
- home_ou
+ ];
+ }
- ).then(function(ids) {
- retrieveUsers(ids);
- });
- };
- */
+ var sort = [];
+ angular.forEach(
+ $scope.patronSearchGridProvider.sort,
+ function(sortdef) {
+ if (angular.isObject(sortdef)) {
+ var name = Object.keys(sortdef)[0];
+ var dir = sortdef[name];
+ sort.push(name + ' ' + dir);
+ } else {
+ sort.push(sortdef);
+ }
+ }
+ );
+
+ console.log('sort = ' + js2JSON(sort));
+ return sort;
+ }
// alt form which receives fleshed user objects
+ /*
function sendSearch(args) {
search = compileSearch(args);
egNet.request(
'open-ils.actor',
'open-ils.actor.patron.search.advanced.fleshed',
- egAuth.token(), search, 50 /* limit */,
- [ /* sort */
- "family_name ASC",
- "first_given_name ASC",
- "second_given_name ASC",
- "dob DESC"
- ],
+ egAuth.token(),
+ search,
+ 50 //
+ compileSort(),
inactive,
home_ou,
egUser.defaultFleshFields
$scope.patronSearchGridProvider.increment();
});
};
-
+ */
// fetch users by id and add them to the patrons list
+ /*
function retrieveUsers(ids) {
angular.forEach(ids, function(id, idx) {
// capture idx to maintain search results order
});
});
}
+ */
// collect form args fire patron search
$scope.search = function(args) {
if (args && Object.keys(args).length) {
+ //$scope.searchArgs = args;
+ //$scope.patronSearchGridProvider.increment();
+
+ if (args.profile) args.profile = args.profile.id;
+ if (args.home_ou) args.home_ou = args.home_ou.id;
+
+ $location.search(args);
+
+ /*
+ $scope.
$scope.patrons.reset();
if (args.id) {
retrieveUsers([args.id]);
} else {
sendSearch(args);
}
+ */
}
}
// manage table row selection
+ /*
$scope.onPatronClick = function($event, user) {
$scope.lastSelected = user;
patronSvc.setDefault(null, user);
}
}
+ */
$scope.onPatronDblClick = function($event, user) {
$location.path('/circ/patron/' + user.id() + '/checkout');
// http://stackoverflow.com/questions/16749907/window-open-behaviour-in-chrome-tabs-windows
// for now, skip this feature and support control-click to open
// multiple patrons instead.
+ /*
$scope.openSelectedPatrons = function() {
angular.forEach(
$scope.patrons.selectedItems(),
}
);
}
+ */
// handled up/down arrow events while the patrons results table is focused.
// disabled for now, since there are some UI issues to work out first:
// hover in its original position, making the hovered row appear to be
// selected (style-wise) even when it's not. Disabling table-hover
// CSS works, but table-hover is useful, so...
+
+ /* TODO: MOVE ME INTO GRID.js
$scope.navigateResults = function($event) {
// we can't select the next/previous user if we don't know
// which user was selected last. this should never happen, though.
if (user) $scope.onPatronClick($event, user);
}
+ */
}])