26bb501f8729091b7d00627988661b77cf1c4cd8
[Evergreen.git] / Open-ILS / xul / staff_client / chrome / content / legacy / _browse.xul
1 <?xml version="1.0"?>
2 <!-- Application: Evergreen Staff Client -->
3 <!-- Screen: Cataloger's Search Result Screen -->
4
5 <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
6 <!-- PRESENTATION -->
7 <?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
8 <?xml-stylesheet href="chrome://open_ils_staff_client/skin/global.css" type="text/css"?>
9
10 <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
11 <!-- LOCALIZATION -->
12 <!DOCTYPE window SYSTEM "chrome://open_ils_staff_client/locale/lang.dtd">
13
14 <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
15 <!-- OVERLAYS -->
16 <?xul-overlay href="chrome://open_ils_staff_client/content/OpenILS/util_overlay.xul"?>
17 <?xul-overlay href="chrome://open_ils_staff_client/content/legacy/browse_list_overlay.xul"?>
18
19 <window id="browse_list_win"
20         orient="vertical" style="overflow: scroll" 
21         onload="try { my_pre_init(); } catch(E) { alert(E); }"
22         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
23
24         <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
25         <!-- BEHAVIOR -->
26         <script type="text/javascript">var myPackageDir = 'open_ils_staff_client'; var IAMXUL = true; var g = {};</script>
27         <script type="text/javascript" src="chrome://open_ils_staff_client/content/main/JSAN.js"/>
28         <script type="text/javascript" src="chrome://open_ils_staff_client/content/main/constants.js"/>
29         <script type="text/javascript" src="chrome://open_ils_staff_client/content/OpenILS/util/fmall.js"/>
30         <scripts id="openils_util_scripts"/>
31         <script type="text/javascript">
32         <![CDATA[
33
34                 var parentWindow = {};
35                 var params = {};
36                 var mw = {};
37                 var find_this_id;
38
39                 var org_shortname2id = {};
40                 var my_treerow;
41                 var browse_meter_per = 0;
42                 var orgs_with_copies = [];
43                 var orgs_with_copies_hash = {};
44
45                 function my_pre_init() {
46                         try {
47                                 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
48                                 if (typeof JSAN == 'undefined') { throw( "The JSAN library object is missing."); }
49                                 JSAN.errorLevel = "die"; // none, warn, or die
50                                 JSAN.addRepository('..');
51                                 JSAN.use('util.error'); g.error = new util.error();
52                                 g.error.sdump('D_TRACE','my_pre_init() for legacy/_browse.xul');
53
54                                 mw.G = {};
55                                 mw.G.main_test_variable = 'Hello World';
56                                 g.cgi = new CGI();
57                                 g.session = g.cgi.param('session');
58                                 mw.G.auth_ses = [ g.session ];
59                                 mw.sdump = function(a,b) { g.error.sdump(a,b); }
60
61                                 find_this_id = g.cgi.param('docid');
62
63                                 JSAN.use('util.network');
64                                 g.network = new util.network();
65
66                                 JSAN.use('OpenILS.data');
67                                 g.data = new OpenILS.data(); g.data.init({'via':'stash'});
68                                 mw.G.my_orgs = g.data.list.my_aou;
69                                 mw.G.my_orgs_hash = g.data.hash.my_aou;
70                                 mw.G.org_tree = g.data.tree.aou;
71                                 mw.G.user_ou = g.data.hash.aou[ g.data.list.au[0].home_ou() ];
72                                 mw.G.aout_list = g.data.list.aout;
73                                 mw.G.aout_hash = g.data.hash.aout;
74                                 mw.G.ccs_list = g.data.list.ccs;
75                                 mw.G.ccs_hash = g.data.hash.ccs;
76
77                                 var x = document.getElementById('cmd_copy_edit');
78                                 x.setAttribute('oncommand','try{spawn_copy_editor();}catch(E){alert(E);}');
79
80                                 x = document.getElementById('cmd_copy_add');
81                                 x.setAttribute('oncommand','try{spawn_copy_add_wizard();}catch(E){alert(E);}');
82
83                                 x = document.getElementById('cmd_volume_edit');
84                                 x.setAttribute('oncommand','try{spawn_volume_editor();}catch(E){alert(E);}');
85
86                                 x = document.getElementById('cmd_volume_add');
87                                 x.setAttribute('oncommand','try{spawn_volume_add_wizard();}catch(E){alert(E);}');
88
89                                 x = document.getElementById('browse_list_tree');
90                                 x.setAttribute('seltype','multiple');
91
92                                 my_init();
93         
94                         } catch(E) {
95                                 var err_msg = "!! This software has encountered an error.  Please tell your friendly " +
96                                         "system administrator or software developer the following:\nlegacy/_browse.xul\n" + E + '\n';
97                                 try { g.error.sdump('D_ERROR',err_msg); } catch(E) { dump(err_msg); }
98                                 alert(err_msg);
99                         }
100                 }
101
102                 function timer_init() {
103                         return '';
104                 }
105
106                 function timer_elapsed() {
107                         return '';
108                 }
109
110                 function handle_error(err) {
111                         try { alert(js2JSON(err)); } catch(E) { alert(err); }
112                 }
113
114                 function user_request(a,b,c,d) {
115                         return [ g.network.request(a,b,c,d) ];
116                 }
117
118                 function user_async_request(a,b,c,d) {
119                         return [ g.network.request(a,b,c,d) ];
120                 }
121
122                 var counter = {};
123
124                 function counter_init(id) {
125                         counter[id] = 0;
126                 }
127
128                 function counter_incr(id) {
129                         if (! counter[id]) { counter_init(id); }
130                         return ++counter[id];
131                 }
132
133                 function counter_peek(id) {
134                         if (! counter[id]) { return 0; }
135                         return counter[id];
136                 }
137
138                 function disable_widgets() {
139                         var d = document; var idx = 0;
140                         if (arguments[0].nodeName == '#document') {
141                                 idx = 1; d = arguments[0];
142                         }
143                         for (var i = idx; i < arguments.length; i++) {
144                                 if (typeof(arguments[i]) == 'object') {
145                                         arguments[i].disabled = true;
146                                 } else {
147                                         var w = d.getElementById( arguments[i] );
148                                         if (w) { 
149                                                 w.disabled = true; 
150                                         }
151                                 }
152                         }
153                 }
154
155                 function enable_widgets() {
156                         var d = document; var idx = 0;
157                         if (arguments[0].nodeName == '#document') {
158                                 idx = 1; d = arguments[0];
159                         }
160                         for (var i = idx; i < arguments.length; i++) {
161                                 if (typeof(arguments[i]) == 'object') {
162                                         arguments[i].disabled = false;
163                                 } else {
164                                         var w = d.getElementById( arguments[i] );
165                                         if (w) { 
166                                                 w.disabled = false; 
167                                         }
168                                 }
169                         }
170                 }
171
172                 function find_ou(tree,id) {
173                         if (typeof(id)=='object') { id = id.id(); }
174                         if (tree.id()==id) {
175                                 return tree;
176                         }
177                         for (var i in tree.children()) {
178                                 var child = tree.children()[i];
179                                 ou = find_ou( child, id );
180                                 if (ou) { return ou; }
181                         }
182                         return null;
183                 }
184
185                 function yesno(value) {
186                         switch(value) {
187                                 case true: case 'true': case '1': case 'on':
188                                         return 'Yes';
189                                 default: 
190                                         return 'No';
191                         }
192                 }
193
194                 function empty_widget() {
195                         var d; var e;
196                         if (arguments.length == 1) {
197                                 e = arguments[0];
198                         } else {
199                                 d = arguments[0];
200                                 e = arguments[1];
201                                 if (typeof(e) != 'object') { e = d.getElementById(e); }
202                         }
203                         if (typeof(e) != 'object') { dump('Failed on empty_widget\n'); return null; }
204                         while (e.lastChild) { e.removeChild(e.lastChild); }
205                 }
206
207                 function get_list_from_tree_selection() {
208                         var d = document; var tree_w;
209                         if (arguments.length == 1) {
210                                 tree_w = arguments[0];
211                         } else {
212                                 d = arguments[0];
213                                 tree_w = arguments[1];
214                         }
215                         var hitlist;
216                         if (typeof(tree_w) != 'object') {
217                                 hitlist = d.getElementById(tree_w);
218                         } else {
219                                 hitlist = tree_w;
220                         }
221                         var list = [];
222                         var start = new Object();
223                         var end = new Object();
224                         var numRanges = hitlist.view.selection.getRangeCount();
225                         for (var t=0; t<numRanges; t++){
226                                 hitlist.view.selection.getRangeAt(t,start,end);
227                                 for (var v=start.value; v<=end.value; v++){
228                                         var i = hitlist.contentView.getItemAtIndex(v);
229                                         //sdump('D_WIDGETS',i.tagName + '\n');
230                                         list.push( i );
231                                 }
232                         }
233                         return list;
234                 }
235
236                 function filter_list(list,f) {
237                         var new_list = [];
238                         for (var i in list) {
239                                 var t = f( list[i] );
240                                 if (t) new_list.push( list[i] );
241                         }
242                         return new_list;
243                 }
244
245                 function cycle_attribute() {
246                         var d; var e; var a; var v;
247                         if (arguments.length == 3) {
248                                 e = arguments[0];
249                                 a = arguments[1];
250                                 v = arguments[2];
251                         } else {
252                                 d = arguments[0];
253                                 e = arguments[1];
254                                 a = arguments[2];
255                                 v = arguments[3];
256                                 if (typeof(e) != 'object') { e = d.getElementById(e); }
257                         }
258                         try {
259                                 if (typeof(e) != 'object') { throw('typeof e != object : typeof e = ' + typeof(e)); }
260                                 if (!a) { throw('!a : a = ' + a); }
261                                 if (! e.getAttribute(a) ) { throw(' ! e.getAttribute(a) : a = ' + a); }
262                                 if (typeof(v) != 'object') { throw('typeof v != object : typeof v = ' + typeof(v)); }
263
264                                 var toggle = e.getAttribute(a);
265                                 var next_one = false;
266                                 for (var i = 0; i < v.length; i++) {
267                                         if (next_one) {
268                                                 e.setAttribute(a,v[i]);
269                                                 return v[i];
270                                         }
271                                         if (toggle == v[i]) {
272                                                 next_one = true;
273                                         }
274                                 }
275                                 if (next_one) {
276                                         e.setAttribute(a,v[0]);
277                                         return v[0];
278                                 } else {
279                                         throw('current value not in list');
280                                 }
281                         } catch(E) {
282                                 return null;
283                         }
284                 }
285
286
287                 function mapChrome(chrome) {
288                         switch(chrome) {
289                                 case 'chrome://open_ils_staff_client/content/cat/volume_copy_add_wizard.xul':
290                                         return 'chrome://open_ils_staff_client/content/legacy/_volume_copy_add_wizard.xul'; break;
291                                 case 'chrome://open_ils_staff_client/content/cat/copy_add_wizard.xul':
292                                         return 'chrome://open_ils_staff_client/content/legacy/_copy_add_wizard.xul'; break;
293                                 case 'chrome://open_ils_staff_client/content/cat/volume_edit_wizard.xul':
294                                         return 'chrome://open_ils_staff_client/content/legacy/_volume_edit_wizard.xul'; break;
295                         }
296                         return '';
297                 }
298
299                 parentWindow.new_tab = function() { };
300
301                 parentWindow.replace_tab = function(a,b,c) {
302                         if (window.xulG && typeof window.xulG.new_tab == 'function') {
303                                 try {
304                                         var f = window.xulG.new_tab( mapChrome(c), { 'tab_name' : b }, {} );
305                                         return f.contentWindow;
306                                 } catch(E) {
307                                         alert(E);
308                                 }
309                         }
310                 }
311
312                 mw.new_window = function(a,b,c) {
313                         netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
314                         JSAN.use('util.window'); var win = new util.window();
315                         return win.open( mapChrome(a), b, c );
316                 }
317
318                 function spawn_copy_editor() {
319
320                         JSAN.use('util.widgets'); JSAN.use('util.functional');
321
322                         var list = util.widgets.get_list_from_tree_selection('browse_list_tree');
323                         list = util.functional.filter_list(
324                                 list,
325                                 function (obj) {
326                                         return obj.getAttribute('object_type') == 'copy';
327                                 }
328                         );
329
330                         var edit = 0;
331                         try {
332                                 edit = g.network.request(
333                                         api.PERM_MULTI_ORG_CHECK.app,
334                                         api.PERM_MULTI_ORG_CHECK.method,
335                                         [ 
336                                                 g.session, 
337                                                 g.data.list.au[0].id(), 
338                                                 util.functional.map_list(
339                                                         list,
340                                                         function (obj) {
341                                                                 return obj.getAttribute('ou_id');
342                                                         }
343                                                 ),
344                                                 [ 'UPDATE_COPY', 'UPDATE_BATCH_COPY' ]
345                                         ]
346                                 ).length == 0 ? 1 : 0;
347                         } catch(E) {
348                                 g.error.sdump('batch permission check: ' + E);
349                         }
350
351                         list = util.functional.map_list(
352                                 list,
353                                 function (obj) {
354                                         return obj.getAttribute('copy_id');
355                                 }
356                         );
357
358                         var title = list.length == 1 ? 'Copy' : 'Copies';
359
360                         JSAN.use('util.window'); var win = new util.window();
361                         g.data.temp = '';
362                         g.data.stash('temp');
363                         var w = win.open(
364                                 window.xulG.url_prefix(urls.XUL_COPY_EDITOR)
365                                         +'?session='+window.escape(g.session)
366                                         +'&copy_ids='+window.escape(js2JSON(list))
367                                         +'&docid='+window.escape(find_this_id)
368                                         +'&edit='+edit,
369                                 title,
370                                 'chrome,modal,resizable'
371                         );
372                         /* FIXME -- need to unique the temp space, and not rely on modalness of window */
373                         g.data.stash_retrieve();
374                         var copies = JSON2js( g.data.temp );
375                         g.error.sdump('D_CAT','in browse, copies =\n<<' + copies + '>>');
376                         if (edit=='1' && copies!='' && typeof copies != 'undefined') {
377                                 try {
378                                         var r = g.network.request(
379                                                 api.FM_ACP_FLESHED_BATCH_UPDATE.app,
380                                                 api.FM_ACP_FLESHED_BATCH_UPDATE.method,
381                                                 [ g.session, copies ]
382                                         );
383                                         /* FIXME -- revisit the return value here */
384                                 } catch(E) {
385                                         alert('copy update error: ' + js2JSON(E));
386                                 }
387                                 refresh_browse_list();
388                         }
389                 }
390
391                 function spawn_volume_editor() {
392                         JSAN.use('util.widgets'); JSAN.use('util.functional');
393                         var list = util.widgets.get_list_from_tree_selection('browse_list_tree');
394                         list = util.functional.filter_list(
395                                 list,
396                                 function (obj) {
397                                         return obj.getAttribute('object_type') == 'volume';
398                                 }
399                         );
400                         
401                         var edit = 0;
402                         try {
403                                 edit = g.network.request(
404                                         api.PERM_MULTI_ORG_CHECK.app,
405                                         api.PERM_MULTI_ORG_CHECK.method,
406                                         [ 
407                                                 g.session, 
408                                                 g.data.list.au[0].id(), 
409                                                 util.functional.map_list(
410                                                         list,
411                                                         function (obj) {
412                                                                 return obj.getAttribute('ou_id');
413                                                         }
414                                                 ),
415                                                 [ 'UPDATE_VOLUME' ]
416                                         ]
417                                 ).length == 0 ? 1 : 0;
418                         } catch(E) {
419                                 g.error.sdump('batch permission check: ' + E);
420                         }
421
422                         if (edit==0) return; // no read-only view for this interface
423
424                         list = util.functional.map_list(
425                                 list,
426                                 function (obj) {
427                                         return [ obj.getAttribute('ou_id'), obj.getAttribute('volume_id'), obj.getAttribute('callnumber') ];
428                                 }
429                         );
430
431                         var title = list.length == 1 ? 'Volume' : 'Volumes';
432
433                         JSAN.use('util.window'); var win = new util.window();
434                         g.data.temp = '';
435                         g.data.stash('temp');
436                         var w = win.open(
437                                 window.xulG.url_prefix(urls.XUL_VOLUME_EDITOR)
438                                         +'?session='+window.escape(g.session)
439                                         +'&ou_id_volume_id_callnumber_tuples=' + window.escape( js2JSON(list) ),
440                                 title,
441                                 'chrome,modal,resizable'
442                         );
443
444                         /* FIXME -- need to unique the temp space, and not rely on modalness of window */
445                         g.data.stash_retrieve();
446                         var volumes = JSON2js( g.data.temp );
447                         g.error.sdump('D_CAT','in browse, g.data.temp =\n' + g.data.temp);
448                         if (volumes=='') return;
449                 
450                         volumes = util.functional.filter_list(
451                                 volumes,
452                                 function (obj) {
453                                         return obj.ischanged() == '1';
454                                 }
455                         );
456
457                         volumes = util.functional.map_list(
458                                 volumes,
459                                 function (obj) {
460                                         obj.record( find_this_id ); // staff client 2 didn't do this.  Does it matter?
461                                         return obj;
462                                 }
463                         );
464
465                         if (volumes.length == 0) return;
466
467                         try {
468                                 var r = g.network.request(
469                                         api.FM_ACN_TREE_UPDATE.app,
470                                         api.FM_ACN_TREE_UPDATE.method,
471                                         [ g.session, volumes ]
472                                 );
473                                 /* FIXME -- revisit the return value here */
474                         } catch(E) {
475                                 alert('volume update error: ' + js2JSON(E));
476                         }
477                         refresh_browse_list();
478
479                 }
480
481                 function spawn_volume_add_wizard() {
482                         JSAN.use('util.widgets'); JSAN.use('util.functional');
483                         var list = util.widgets.get_list_from_tree_selection('browse_list_tree');
484                         list = util.functional.filter_list(
485                                 list,
486                                 function (obj) {
487                                         return obj.getAttribute('object_type') == 'org_unit';
488                                 }
489                         );
490                         list = util.functional.map_list(
491                                 list,
492                                 function (obj) {
493                                         return obj.getAttribute('ou_id');
494                                 }
495                         )               
496                         var edit = 0;
497                         try {
498                                 edit = g.network.request(
499                                         api.PERM_MULTI_ORG_CHECK.app,
500                                         api.PERM_MULTI_ORG_CHECK.method,
501                                         [ 
502                                                 g.session, 
503                                                 g.data.list.au[0].id(), 
504                                                 list,
505                                                 [ 'CREATE_VOLUME', 'CREATE_COPY' ]
506                                         ]
507                                 ).length == 0 ? 1 : 0;
508                         } catch(E) {
509                                 g.error.sdump('batch permission check: ' + E);
510                         }
511
512                         if (edit==0) return; // no read-only view for this interface
513
514                         var title = 'Add Volume/Copy';
515
516                         JSAN.use('util.window'); var win = new util.window();
517                         var w = win.open(
518                                 window.xulG.url_prefix(urls.XUL_VOLUME_COPY_CREATOR)
519                                         +'?session='+window.escape(g.session)
520                                         +'&doc_id=' + window.escape(find_this_id)
521                                         +'&ou_ids=' + window.escape( js2JSON(list) ),
522                                 title,
523                                 'chrome,modal,resizable'
524                         );
525
526                         refresh_browse_list();
527                 }
528
529                 function spawn_copy_add_wizard() {
530                         /* <command id="cmd_copy_add" oncommand="copy_add(false,{ 'tree' : 'browse_list_tree', 'refresh_func' : refresh_browse_list });"/> */
531                         JSAN.use('util.widgets'); JSAN.use('util.functional');
532                         var list = util.widgets.get_list_from_tree_selection('browse_list_tree');
533                         list = util.functional.filter_list(
534                                 list,
535                                 function (obj) {
536                                         return obj.getAttribute('object_type') == 'volume';
537                                 }
538                         );
539                         list = util.functional.map_list(
540                                 list,
541                                 function (obj) {
542                                         return obj.getAttribute('volume_id');
543                                 }
544                         );
545
546
547                         alert('spawn copy add wizard with volume_ids = ' + js2JSON(list));
548                 }
549         ]]>
550         </script>
551
552         <!-- The logic for this app -->
553         <Evergreen id="browse_list_js" />
554
555         <!-- XUL'ified abstraction for logic to attach to widgets -->
556         <commandset id="browse_list_cmds" />
557
558         <!-- Accelerator Keys (Accessor Keys are in DTD's) -->
559         <keyset id="browse_list_keys" />
560
561         <!-- Context menus -->
562         <popupset id="browse_list_popupset" />
563
564         <!-- Layout to be filled in by overlays and javascript -->
565         <groupbox flex="1">
566                 <caption label="Copy Browser"/>
567                 <vbox id="browse_list_vbox" class="test_class"/>
568         </groupbox>
569
570 </window>
571