]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/web/js/ui/default/staff/cat/z3950/app.js
webstaff: implement saving default Z39.50 targets
[Evergreen.git] / Open-ILS / web / js / ui / default / staff / cat / z3950 / app.js
1 /*
2  * Z39.50 search and import
3  */
4
5 angular.module('egCatZ3950Search',
6     ['ngRoute', 'ui.bootstrap', 'egCoreMod', 'egUiMod', 'egGridMod', 'egZ3950Mod', 'egMarcMod'])
7
8 .config(function($routeProvider, $locationProvider, $compileProvider) {
9     $locationProvider.html5Mode(true);
10     $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|blob):/); // grid export
11
12     var resolver = {delay : function(egStartup) {return egStartup.go()}};
13
14     // search page shows the list view by default
15     $routeProvider.when('/cat/z3950/search', {
16         templateUrl: './cat/z3950/t_list',
17         controller: 'Z3950SearchCtrl',
18         resolve : resolver
19     });
20
21     // default page / bucket view
22     $routeProvider.otherwise({redirectTo : '/cat/z3950/search'});
23 })
24
25 /**
26  * List view - grid stuff
27  */
28 .controller('Z3950SearchCtrl',
29        ['$scope','$q','$location','$timeout','$window','egCore','egGridDataProvider','egZ3950TargetSvc','$modal',
30 function($scope , $q , $location , $timeout , $window,  egCore , egGridDataProvider,  egZ3950TargetSvc,  $modal) {
31
32     // get list of targets
33     egZ3950TargetSvc.loadTargets();
34     egZ3950TargetSvc.loadActiveSearchFields();
35
36     $scope.field_strip_groups = [];
37     egCore.startup.go().then(function() {
38         // and list of field strip groups; need to ensure
39         // that enough of the startup has happened so that
40         // we have the user WS
41         egCore.pcrud.search('vibtg',
42             {
43                 always_apply : 'f',
44                 owner : {
45                     'in' : {
46                         select : {
47                             aou : [{
48                                 column : 'id',
49                                 transform : 'actor.org_unit_ancestors',
50                                 result_field : 'id'
51                             }]
52                         },
53                         from : 'aou',
54                         where : {
55                             id : egCore.auth.user().ws_ou()
56                         }
57                     }
58                 }
59             },
60             { order_by : { vibtq : ['label'] } }
61         ).then(null, null, function(strip_group) {
62             strip_group.selected = false;
63             $scope.field_strip_groups.push(strip_group);
64         });
65     });
66
67     $scope.total_hits = 0;
68
69     var provider = egGridDataProvider.instance({});
70
71     provider.get = function(offset, count) {
72         var deferred = $q.defer();
73
74         var query = egZ3950TargetSvc.currentQuery();
75         if (!query.raw_search && Object.keys(query.search).length == 0) {
76             return $q.when();
77         }
78
79         var method = query.raw_search ?
80                        'open-ils.search.z3950.search_service' :
81                        'open-ils.search.z3950.search_class';
82
83         if (query.raw_search) {
84             query.query = query.raw_search;
85             delete query['search'];
86             delete query['raw_search'];
87             query.service = query.service[0];
88             query.username = query.username[0];
89             query.password = query.password[0];
90         }
91
92         query['limit'] = count;
93         query['offset'] = offset;
94
95         var resultIndex = offset;
96         $scope.total_hits = 0;
97         $scope.searchInProgress = true;
98         egCore.net.request(
99             'open-ils.search',
100             method,
101             egCore.auth.token(),
102             query
103         ).then(
104             function() { $scope.searchInProgress = false; deferred.resolve() },
105             null, // onerror
106             function(result) {
107                 // FIXME when the search offset is > 0, the
108                 // total hits count can be wrong if one of the
109                 // Z39.50 targets has fewer than $offset hits; in that
110                 // case, result.count is not supplied.
111                 $scope.total_hits += (result.count || 0);
112                 for (var i in result.records) {
113                     result.records[i].mvr['service'] = result.service;
114                     result.records[i].mvr['index'] = resultIndex++;
115                     result.records[i].mvr['marcxml'] = result.records[i].marcxml;
116                     deferred.notify(result.records[i].mvr);
117                 }
118             }
119         );
120
121         return deferred.promise;
122     };
123
124     $scope.z3950SearchGridProvider = provider;
125     $scope.gridControls = {};
126
127     $scope.search = function() {
128         $scope.z3950SearchGridProvider.refresh();
129     };
130     $scope.clearForm = function() {
131         egZ3950TargetSvc.clearSearchFields();
132     };
133
134     $scope.saveDefaultZ3950Targets = function() {
135         egZ3950TargetSvc.saveDefaultZ3950Targets();
136     }
137
138     var display_form = true;
139     $scope.show_search_form = function() {
140         return display_form;
141     }
142     $scope.toggle_search_form = function() {
143         display_form = !display_form;
144     }
145
146     $scope.raw_search_impossible = function() {
147         return egZ3950TargetSvc.rawSearchImpossible();
148     }
149     $scope.showRawSearchForm = function() {
150         $modal.open({
151             templateUrl: './cat/z3950/t_raw_search',
152             size: 'md',
153             controller:
154                 ['$scope', '$modalInstance', function($scope, $modalInstance) {
155                 egZ3950TargetSvc.setRawSearch('');
156                 $scope.focusMe = true;
157                 $scope.ok = function(args) { $modalInstance.close(args) }
158                 $scope.cancel = function () { $modalInstance.dismiss() }
159             }]
160         }).result.then(function (args) {
161             if (!args || !args.raw_search) return;
162             $scope.clearForm();
163             egZ3950TargetSvc.setRawSearch(args.raw_search);
164             $scope.z3950SearchGridProvider.refresh();
165         });
166     }
167
168     $scope.showInCatalog = function() {
169         var items = $scope.gridControls.selectedItems();
170         // relying on cant_showInCatalog to protect us
171         var url = egCore.env.basePath +
172                   'cat/catalog/record/' + items[0].tcn();
173         $timeout(function() { $window.open(url, '_blank') });        
174     };
175     $scope.cant_showInCatalog = function() {
176         var items = $scope.gridControls.selectedItems();
177         if (items.length != 1) return true;
178         if (items[0]['service'] == 'native-evergreen-catalog') return false;
179         return true;
180     };
181
182     $scope.local_overlay_target = egCore.hatch.getLocalItem('eg.cat.marked_overlay_record') || 0;
183     $scope.mark_as_overlay_target = function() {
184         var items = $scope.gridControls.selectedItems();
185         if ($scope.local_overlay_target == items[0].tcn()) {
186             $scope.local_overlay_target = 0;
187         } else {
188             $scope.local_overlay_target = items[0].tcn();
189         }
190         egCore.hatch.setLocalItem('eg.cat.marked_overlay_record',$scope.local_overlay_target);
191     }
192     $scope.cant_overlay = function() {
193         if (!$scope.local_overlay_target) return true;
194         var items = $scope.gridControls.selectedItems();
195         if (items.length != 1) return true;
196         if (
197                 items[0]['service'] == 'native-evergreen-catalog' &&
198                 items[0].tcn() == $scope.local_overlay_target
199            ) return true;
200         return false;
201     }
202
203     $scope.selectFieldStripGroups = function() {
204         var groups = [];
205         angular.forEach($scope.field_strip_groups, function(grp, idx) {
206             if (grp.selected) {
207                 groups.push(grp.id());
208             }
209         });
210         return groups;
211     };
212     $scope.import = function() {
213         var deferred = $q.defer();
214         var items = $scope.gridControls.selectedItems();
215         egCore.net.request(
216             'open-ils.cat',
217             'open-ils.cat.biblio.record.xml.import',
218             egCore.auth.token(),
219             items[0]['marcxml'],
220             null, // FIXME bib source
221             null,
222             null,
223             $scope.selectFieldStripGroups()
224         ).then(
225             function() { deferred.resolve() },
226             null, // onerror
227             function(result) {
228                 console.debug('imported');
229             }
230         );
231
232         return deferred.promise;
233     };
234     $scope.need_one_selected = function() {
235         var items = $scope.gridControls.selectedItems();
236         if (items.length == 1) return false;
237         return true;
238     };
239
240     $scope.spawn_editor = function() {
241         var items = $scope.gridControls.selectedItems();
242         $modal.open({
243             templateUrl: './cat/z3950/t_marc_edit',
244             size: 'lg',
245             controller:
246                 ['$scope', '$modalInstance', function($scope, $modalInstance) {
247                 $scope.focusMe = true;
248                 $scope.record_id = 0;
249                 $scope.dirty_flag = false;
250                 $scope.marc_xml = items[0]['marcxml'];
251                 $scope.ok = function(args) { $modalInstance.close(args) }
252                 $scope.cancel = function () { $modalInstance.dismiss() }
253             }]
254         }).result.then(function (args) {
255             if (!args || !args.name) return;
256         });
257     }
258
259     $scope.view_marc = function() {
260         var items = $scope.gridControls.selectedItems();
261         $modal.open({
262             templateUrl: './cat/z3950/t_marc_html',
263             size: 'lg',
264             controller:
265                 ['$scope', '$modalInstance', function($scope, $modalInstance) {
266                 $scope.focusMe = true;
267                 $scope.marc_xml = items[0]['marcxml'];
268                 $scope.isbn = (items[0].isbn() || '').replace(/ .*/, '');
269                 $scope.ok = function(args) { $modalInstance.close(args) }
270                 $scope.cancel = function () { $modalInstance.dismiss() }
271             }]
272         }).result.then(function (args) {
273             if (!args || !args.name) return;
274         });
275     }
276
277     $scope.overlay_record = function() {
278         var items = $scope.gridControls.selectedItems();
279         var overlay_target = $scope.local_overlay_target;
280         var args = {
281             'marc_xml' : items[0]['marcxml']
282         };
283         $modal.open({
284             templateUrl: './cat/z3950/t_overlay',
285             size: 'lg',
286             controller:
287                 ['$scope', '$modalInstance', function($scope, $modalInstance) {
288                 $scope.focusMe = true;
289                 $scope.overlay_target = overlay_target;
290                 $scope.args = args;
291                 $scope.ok = function(args) { $modalInstance.close(args) };
292                 $scope.cancel = function () { $modalInstance.dismiss() };
293                 $scope.editOverlayRecord = function() {
294                     $modal.open({
295                         templateUrl: './cat/z3950/t_edit_overlay_record',
296                         size: 'lg',
297                         controller:
298                             ['$scope', '$modalInstance', function($scope, $modalInstance) {
299                             $scope.focusMe = true;
300                             $scope.record_id = 0;
301                             $scope.dirty_flag = false;
302                             $scope.args = args;
303                             $scope.ok = function(args) { $modalInstance.close(args) }
304                             $scope.cancel = function () { $modalInstance.dismiss() }
305                         }]
306                     }).result.then(function (args) {
307                         if (!args || !args.name) return;
308                     });
309                 };
310             }]
311         }).result.then(function (args) {
312             egCore.net.request(
313                 'open-ils.cat',
314                 'open-ils.cat.biblio.record.marc.replace',
315                 egCore.auth.token(),
316                 overlay_target,
317                 args.marc_xml,
318                 null, // FIXME bib source
319                 null,
320                 $scope.selectFieldStripGroups()
321             ).then(
322                 function(result) {
323                     console.debug('overlay complete');
324                 }
325             );            
326         });
327     }
328 }])