From 64377d5b2aae1c6cbd8c085079f5a7e101ceec36 Mon Sep 17 00:00:00 2001 From: Galen Charlton Date: Thu, 9 Jul 2015 16:25:25 +0000 Subject: [PATCH] WIP: add more Z39.50 search functionality to webstaff - can now select targets - search field form now active - can now retrieve results Next steps: - start adding actions to the results grid - add estimated hits count - add caching of results already retrieved - add ability to move the search field and target list out of the way Signed-off-by: Galen Charlton --- Open-ILS/src/templates/staff/cat/z3950/t_list.tt2 | 37 +++++- .../templates/staff/cat/z3950/t_search_fields.tt2 | 8 ++ .../src/templates/staff/cat/z3950/t_target.tt2 | 21 +++- .../web/js/ui/default/staff/cat/services/z3950.js | 139 ++++++++++++++++----- Open-ILS/web/js/ui/default/staff/cat/z3950/app.js | 74 +++++++++++ 5 files changed, 240 insertions(+), 39 deletions(-) create mode 100644 Open-ILS/src/templates/staff/cat/z3950/t_search_fields.tt2 create mode 100644 Open-ILS/web/js/ui/default/staff/cat/z3950/app.js diff --git a/Open-ILS/src/templates/staff/cat/z3950/t_list.tt2 b/Open-ILS/src/templates/staff/cat/z3950/t_list.tt2 index 5f12a1fd7c..0158c45e38 100644 --- a/Open-ILS/src/templates/staff/cat/z3950/t_list.tt2 +++ b/Open-ILS/src/templates/staff/cat/z3950/t_list.tt2 @@ -1,18 +1,43 @@ -
-[% l('Search') %] +
+
+ [% l('Query') %] + +
+
+ [% l('Service and Credentials') %] + +
-
-[% l('Targets') %] - +
+
+
+ + + +
+
+ + + + + + + + + diff --git a/Open-ILS/src/templates/staff/cat/z3950/t_search_fields.tt2 b/Open-ILS/src/templates/staff/cat/z3950/t_search_fields.tt2 new file mode 100644 index 0000000000..377695e478 --- /dev/null +++ b/Open-ILS/src/templates/staff/cat/z3950/t_search_fields.tt2 @@ -0,0 +1,8 @@ +
+
+ +
+ +
+
+
diff --git a/Open-ILS/src/templates/staff/cat/z3950/t_target.tt2 b/Open-ILS/src/templates/staff/cat/z3950/t_target.tt2 index 52903002b4..9365ec225b 100644 --- a/Open-ILS/src/templates/staff/cat/z3950/t_target.tt2 +++ b/Open-ILS/src/templates/staff/cat/z3950/t_target.tt2 @@ -1,4 +1,19 @@ -
- {{target.code}} / {{target.settings.label}}} - requires auth +
+
+ +
+
[% l('Local Catalog') %]
+
{{target.settings.label}}
+
+
+ + +
+
+ + +
+
+
+
diff --git a/Open-ILS/web/js/ui/default/staff/cat/services/z3950.js b/Open-ILS/web/js/ui/default/staff/cat/services/z3950.js index 1d6d9182ec..9cd97afc35 100644 --- a/Open-ILS/web/js/ui/default/staff/cat/services/z3950.js +++ b/Open-ILS/web/js/ui/default/staff/cat/services/z3950.js @@ -1,5 +1,95 @@ angular.module('egZ3950Mod', ['egCoreMod', 'ui.bootstrap']) +.factory('egZ3950TargetSvc', + ['$q', 'egCore', 'egAuth', +function($q, egCore, egAuth) { + + var service = { + targets : [ ], + searchFields : { } + }; + + service.loadTargets = function() { + egCore.net.request( + 'open-ils.search', + 'open-ils.search.z3950.retrieve_services', + egAuth.token() + ).then(function(res) { + service.targets = []; + // native Evergreen search goes first + var localTarget = res['native-evergreen-catalog']; + delete res['native-evergreen-catalog']; + angular.forEach(res, function(value, key) { + this.push({ + code: key, + settings: value, + selected: false, + username: '', + password: '' + }); + }, service.targets); + service.targets.sort(function (a, b) { + a = a.settings.label; + b = b.settings.label; + return a < b ? -1 : (a > b ? 1 : 0); + }); + service.targets.unshift({ + code: 'native-evergreen-catalog', + settings: localTarget, + selected: false, + username: '', + password: '' + }); + }); + }; + service.loadActiveSearchFields = function() { + // don't want to throw away the reference, otherwise + // directives bound to searchFields won't + // refresh + for (var field in service.searchFields) { + delete service.searchFields[field]; + } + angular.forEach(service.targets, function(target, idx) { + if (target.selected) { + angular.forEach(target.settings.attrs, function(attr, key) { + if (!(key in service.searchFields)) service.searchFields[key] = { + label : attr.label, + query : '' + }; + }); + } + }); + }; + + // return the selected Z39.50 targets and search strings + // in a format suitable for passing directly to + // open-ils.search.z3950.search_class + service.currentQuery = function() { + var query = { + service : [], + username : [], + password : [], + search : {} + }; + + angular.forEach(service.targets, function(target, idx) { + if (target.selected) { + query.service.push(target.code); + query.username.push(target.username); + query.password.push(target.password); + } + }); + angular.forEach(service.searchFields, function(value, key) { + if (value.query && value.query.trim()) { + query.search[key] = value.query.trim(); + } + }); + + return query; + } + + return service; +}]) .directive("egZ3950TargetList", function () { return { transclude: true, @@ -9,36 +99,25 @@ angular.module('egZ3950Mod', ['egCoreMod', 'ui.bootstrap']) }, templateUrl: './cat/z3950/t_target', controller: - ['$scope','egCore','egAuth', - function($scope , egCore, egAuth) { - function loadTargets() { - egCore.net.request( - 'open-ils.search', - 'open-ils.search.z3950.retrieve_services', - egAuth.token() - ).then(function(res) { - $scope.targets = []; - // native Evergreen search goes first - var localTarget = res['native-evergreen-catalog']; - delete res['native-evergreen-catalog']; - angular.forEach(res, function(value, key) { - this.push({ - code: key, - settings: value - }); - }, $scope.targets); - $scope.targets.sort(function (a, b) { - a = a.settings.label; - b = b.settings.label; - return a < b ? -1 : (a > b ? 1 : 0); - }); - $scope.targets.unshift({ - code: 'native-evergreen-catalog', - settings: localTarget - }); - }); - } - loadTargets(); + ['$scope','egZ3950TargetSvc', + function($scope , egZ3950TargetSvc) { + $scope.targets = egZ3950TargetSvc.targets; + $scope.$watch('targets', function(oldVal, newVal) { + egZ3950TargetSvc.loadActiveSearchFields(); + }, true); }] } }) +.directive("egZ3950SearchFieldList", ['egZ3950TargetSvc', + function(egZ3950TargetSvc) { + return { + restrict: 'AE', + scope: { + }, + templateUrl: './cat/z3950/t_search_fields', + link: function(scope, elem, attr) { + scope.fields = egZ3950TargetSvc.searchFields; + } + }; + } +]); diff --git a/Open-ILS/web/js/ui/default/staff/cat/z3950/app.js b/Open-ILS/web/js/ui/default/staff/cat/z3950/app.js new file mode 100644 index 0000000000..1e63d4e084 --- /dev/null +++ b/Open-ILS/web/js/ui/default/staff/cat/z3950/app.js @@ -0,0 +1,74 @@ +/* + * Z39.50 search and import + */ + +angular.module('egCatZ3950Search', + ['ngRoute', 'ui.bootstrap', 'egCoreMod', 'egUiMod', 'egGridMod', 'egZ3950Mod']) + +.config(function($routeProvider, $locationProvider, $compileProvider) { + $locationProvider.html5Mode(true); + $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|blob):/); // grid export + + var resolver = {delay : function(egStartup) {return egStartup.go()}}; + + // search page shows the list view by default + $routeProvider.when('/cat/z3950/search', { + templateUrl: './cat/z3950/t_list', + controller: 'Z3950SearchCtrl', + resolve : resolver + }); + + // default page / bucket view + $routeProvider.otherwise({redirectTo : '/cat/z3950/search'}); +}) + +/** + * List view - grid stuff + */ +.controller('Z3950SearchCtrl', + ['$scope','$q','$location','$timeout','egCore','egGridDataProvider','egZ3950TargetSvc', +function($scope , $q , $location , $timeout , egCore , egGridDataProvider, egZ3950TargetSvc ) { + + // get list of targets + egZ3950TargetSvc.loadTargets(); + egZ3950TargetSvc.loadActiveSearchFields(); + + var provider = egGridDataProvider.instance({}); + + provider.get = function(offset, count) { + var deferred = $q.defer(); + + var query = egZ3950TargetSvc.currentQuery(); + console.debug(query); + if (query.search.length == 0) { + return $q.when(); + } + + query['limit'] = count; + query['offset'] = offset; + + egCore.net.request( + 'open-ils.search', + 'open-ils.search.z3950.search_class', + egCore.auth.token(), + query + ).then( + function() { deferred.resolve() }, + null, // onerror + function(result) { + for (var i in result.records) { + result.records[i].mvr['service'] = result.service; + deferred.notify(result.records[i].mvr); + } + } + ); + + return deferred.promise; + }; + + $scope.z3950SearchGridProvider = provider; + + $scope.search = function() { + $scope.z3950SearchGridProvider.refresh(); + }; +}]) -- 2.11.0