]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/xul/staff_client/server/admin/toolbar.js
LP2061136 - Stamping 1405 DB upgrade script
[Evergreen.git] / Open-ILS / xul / staff_client / server / admin / toolbar.js
1 var g = {};
2
3 function my_init() {
4     try {
5         if (typeof JSAN == 'undefined') { throw( "The JSAN library object is missing."); }
6         JSAN.errorLevel = "die"; // none, warn, or die
7         JSAN.addRepository('/xul/server/');
8         JSAN.use('util.error'); g.error = new util.error();
9         g.error.sdump('D_TRACE','my_init() for toolbar.xul');
10
11         JSAN.use('OpenILS.data'); g.data = new OpenILS.data();
12         g.data.stash_retrieve();
13
14         JSAN.use('util.widgets');
15         JSAN.use('util.functional');
16
17         dojo.require('openils.PermaCrud');
18
19         g.pcrud = new openils.PermaCrud({
20             authtoken :ses()
21         });
22
23         if (typeof window.xulG == 'object' && typeof window.xulG.set_tab_name == 'function') {
24             try { window.xulG.set_tab_name($('adminStrings').getString('staff.admin.toolbar.tab_name')); } catch(E) { alert(E); }
25         }
26
27         init_lists();
28         $('list_actions').appendChild( g.list1.render_list_actions() );
29         g.list1.set_list_actions();
30         populate_list1();
31         render_lib_menu();
32
33         // toolbutton manipulators
34         $('Add').addEventListener('command',Add,'false');
35         $('Remove').addEventListener('command',Remove,'false');
36         $('Up').addEventListener('command',Up,'false');
37         $('Down').addEventListener('command',Down,'false');
38
39         // toolbar manipulators
40         $('Delete').addEventListener('command',Delete,'false');
41         $('New').addEventListener('command',New,'false');
42         $('Cancel').addEventListener('command',Cancel,'false');
43         $('Save').addEventListener('command',Save,'false');
44
45         // restore the toolbar selection
46         window.addEventListener(
47             'unload',
48             function(ev) {
49                 xulG.render_toolbar_layout();
50             },
51             false
52         );
53
54         // i18n
55         $('context_org').setAttribute('label', fieldmapper.IDL.fmclasses.atb.field_map.org.label);
56         $('context_usr').setAttribute('label', fieldmapper.IDL.fmclasses.atb.field_map.usr.label);
57         $('context_ws').setAttribute('label', fieldmapper.IDL.fmclasses.atb.field_map.ws.label);
58
59
60         var perms_not_had = perm_check();
61         if (perms_not_had.length == 3) { // has none of those perms
62             $('New').disabled = true;
63         }
64
65     } catch(E) {
66         try { g.error.standard_unexpected_error_alert('admin/toolbar.xul',E); } catch(F) { alert(E); }
67     }
68 }
69
70 function perm_check(use_this_org, use_these_perms) {
71     try {
72         // poor man's perm check - just a screen door to keep the honest folk out
73
74         var context_org = use_this_org || ses('ws_ou');
75         var perms_to_check = use_these_perms || [ 'ADMIN_TOOLBAR_FOR_ORG', 'ADMIN_TOOLBAR_FOR_WORKSTATION', 'ADMIN_TOOLBAR_FOR_USER' ];
76
77         JSAN.use('util.network');
78         var net = new util.network();
79         var robj = net.simple_request(
80             'PERM_CHECK',[
81                 ses(),
82                 ses('staff_id'),
83                 context_org,
84                 perms_to_check
85             ]
86         );
87         if (typeof robj.ilsevent != 'undefined') {
88             throw(robj);
89         }
90         return robj;
91     } catch(E) {
92         try { g.error.standard_unexpected_error_alert('admin/toolbar.xul',E); } catch(F) { alert(E); }
93         return perms_to_check; // assume failure so return the perms
94     }
95 }
96
97 function init_lists() {
98     try {
99         JSAN.use('util.list'); JSAN.use('patron.util');
100
101         // list1 = main list containing the action.toolbar entries
102         // list2 = left list containing available toolbar buttons
103         // list3 = right list containing selected toolbar buttons
104
105         init_list1();
106         init_list2();
107         init_list3();
108
109     } catch(E) {
110         alert('Error in toolbar.js, init_lists(): ' + E);
111     }
112 }
113
114 function init_list1() {
115     try {
116         g.list1 = new util.list('atb_tree');
117
118         var list1_columns = g.list1.fm_columns('atb',{
119             '*':{'hidden':true, 'flex':0},
120             'atb_usr' : {
121                 'hidden' : false,
122                 'render' : function(my) {
123                     if (! my.atb.usr()) return;
124                     return my.atb.usr() == ses('staff_id')
125                         ? ses('staff_usrname')
126                         : patron.util.retrieve_au_via_id(ses(),my.atb.usr()).usrname();
127                 }
128             },
129             'atb_org' : {
130                 'hidden' : false,
131                 'fleshed_display_field' : 'shortname'
132             },
133             'atb_ws' : {
134                 'hidden' : false,
135                 'render' : function(my) {
136                     if (! my.atb.ws()) return;
137                     return my.atb.ws() == ses('ws_id')
138                         ? ses('ws_name')
139                         : my.atb.ws();
140                 }
141             },
142             'atb_label' : { 'hidden' : false, 'flex' : 1 },
143             'atb_layout' : { 'hidden' : false, 'flex' : 2 }
144         });
145
146         g.list1.init({
147             'columns' : list1_columns,
148             'on_select' : handle_list1_selection
149         });
150     } catch(E) {
151         alert('Error in toolbar.js, init_list1(): ' + E);
152     }
153 }
154
155 function handle_list1_selection(ev) {
156     try {
157         if (oils_lock > 0) {
158             if (g.list1.node.currentIndex != g.list1_last_index) {
159                 alert( $('adminStrings').getString('staff.admin.toolbar.unsaved_changes') );
160                 g.list1.node.view.selection.select( g.list1_last_index );
161             }
162             return util.widgets.stop_event(ev);
163         }
164         g.list1_last_index = g.list1.node.currentIndex;
165         g.selected_atb = get_atb_from_selection();
166         if (!g.selected_atb) { return; }
167         if (g.selected_atb.org()) {
168             $('lib_menu').value = g.selected_atb.org();
169             $('context').selectedIndex = 0;
170         }
171         if (g.selected_atb.ws()) { $('context').selectedIndex = 1; }
172         if (g.selected_atb.usr()) { $('context').selectedIndex = 2; }
173         g.layout = JSON2js(g.selected_atb.layout());
174         populate_list2_list3();
175         xulG.render_toolbar_layout(g.layout);
176
177         // permission checks
178
179         var perms_not_had = perm_check( g.selected_atb.org() );
180         var disable_editing = false;
181         for (var i = 0; i < perms_not_had.length; i++) {
182             if (perms_not_had[i] == 'ADMIN_TOOLBAR_FOR_ORG' && g.selected_atb.org()) {
183                 disable_editing = true;
184             }
185             if (perms_not_had[i] == 'ADMIN_TOOLBAR_FOR_WORKSTATION' && g.selected_atb.ws()) {
186                 disable_editing = true;
187             }
188             if (perms_not_had[i] == 'ADMIN_TOOLBAR_FOR_USER' && g.selected_atb.usr()) {
189                 disable_editing = true;
190             }
191         }
192         if (g.selected_atb.usr() && ( g.selected_atb.usr() != ses('staff_id') ) ) {
193             disable_editing = true; // if a user toolbar, only allow editing of your own toolbars (just in case)
194         }
195
196         if (disable_editing) {
197             ['Add','Remove','Up','Down','Delete','Save','context_org','context_ws','context_usr'].forEach(
198                 function(e,i,a) {
199                     $(e).disabled = true;
200                 }
201             );
202         } else {
203             ['Add','Remove','Up','Down','Delete','Save','context_org','context_ws','context_usr'].forEach(
204                 function(e,i,a) {
205                     $(e).disabled = false;
206                 }
207             );
208         }
209
210         // don't allow changing ownership axis without perm
211         for (var i = 0; i < perms_not_had.length; i++) {
212             if (perms_not_had[i] == 'ADMIN_TOOLBAR_FOR_ORG') {
213                 $('context_org').disabled = true;
214             }
215             if (perms_not_had[i] == 'ADMIN_TOOLBAR_FOR_WORKSTATION') {
216                 $('context_ws').disabled = true;
217             }
218             if (perms_not_had[i] == 'ADMIN_TOOLBAR_FOR_USER') {
219                 $('context_usr').disabled = true;
220             }
221         }
222
223     } catch(E) {
224         alert('Error in toolbar.js, handle_list1_selection(): ' + E);
225     }
226 }
227
228 function get_atb_from_selection() {
229     try {
230
231         var selected = g.list1.retrieve_selection();
232         if (selected.length > 0) {
233             var treeitem = selected[0]; // seltype="single", so can be only one
234             return g.list1_map[ treeitem.getAttribute('unique_row_counter') ].row.my.atb;
235         } else {
236             return null;
237         }
238
239     } catch(E) {
240         alert('Error in toolbar.js, get_atb_id_from_selection(): ' + E);
241     }
242 }
243
244 function init_list2() {
245     try {
246         g.list2 = new util.list('left');
247
248         var list2_columns = [
249             {
250                 'id' : 'value',
251                 'label' : $('adminStrings').getString('staff.admin.toolbar.button_id.header'),
252                 'render' : function(my) { return my.value; },
253                 'flex' : 1
254             },
255             {
256                 'id' : 'label',
257                 'label' : $('adminStrings').getString('staff.admin.toolbar.label.header'),
258                 'render' : function(my) { return my.label; },
259                 'flex' : 1
260             }
261         ];
262
263         g.list2.init({
264             'columns' : list2_columns
265         });
266
267     } catch(E) {
268         alert('Error in toolbar.js, init_list2(): ' + E);
269     }
270 }
271
272 function get_list2_values_from_selection() {
273     try {
274         var values = [];
275         var selected = g.list2.retrieve_selection();
276         for (var i = 0; i < selected.length; i++) {
277             var treeitem = selected[i];
278             values.push( g.list2_map[ treeitem.getAttribute('unique_row_counter') ].row.my.value );
279         }
280         return values;
281     } catch(E) {
282         alert('Error in toolbar.js, get_list2_values_from_selection(): ' + E);
283     }
284 }
285
286 function init_list3() {
287     try {
288         g.list3 = new util.list('right');
289
290         var list3_columns = [
291             {
292                 'id' : 'value',
293                 'label' : $('adminStrings').getString('staff.admin.toolbar.button_id.header'),
294                 'render' : function(my) { return my.value; },
295                 'flex' : 1
296             },
297             {
298                 'id' : 'label',
299                 'label' : $('adminStrings').getString('staff.admin.toolbar.label.header'),
300                 'render' : function(my) { return my.label; },
301                 'flex' : 1
302             }
303         ];
304
305         g.list3.init({
306             'columns' : list3_columns
307         });
308
309     } catch(E) {
310         alert('Error in toolbar.js, init_list2(): ' + E);
311     }
312 }
313
314 function get_list3_values_from_selection() {
315     try {
316         var values = [];
317         var selected = g.list3.retrieve_selection();
318         for (var i = 0; i < selected.length; i++) {
319             var treeitem = selected[i];
320             values.push( g.list3_map[ treeitem.getAttribute('unique_row_counter') ].row.my.value );
321         }
322         return values;
323     } catch(E) {
324         alert('Error in toolbar.js, get_list3_values_from_selection(): ' + E);
325     }
326 }
327
328 function populate_list1() {
329     try {
330         g.list1.clear();
331         g.list1_map = {};
332         for (var i = 0; i < g.data.list.atb.length; i++) {
333             var rdata = g.list1.append({
334                 'row' : {
335                     'my' : {
336                         'atb' : g.data.list.atb[i]
337                     }
338                 }
339             });
340             g.list1_map[ rdata.unique_row_counter ] = rdata;
341         }
342     } catch(E) {
343         alert('Error in toolbar.js, populate_list1(): ' + E);
344     }
345 }
346
347 function populate_list2_list3(list3_idx) {
348     try {
349
350         g.list2.clear(); g.list2_map = {};
351         g.list3.clear(); g.list3_map = {};
352
353         var seen = {};
354
355         // populate list3, keep track of what to filter from list2
356         for (var i = 0; i < g.layout.length; i++) {
357
358             var value = g.layout[i];
359             var label;
360
361             if (value.match('toolbarseparator')) {
362                 label = $('adminStrings').getString('staff.admin.toolbar.toolbar_separator.list_entry');
363             } else if (value.match('toolbarspacer')) {
364                 label = $('adminStrings').getString('staff.admin.toolbar.toolbar_spacer.list_entry');
365             } else {
366                 label = g.data.toolbar_buttons[value];
367                 seen[value] = true;
368             }
369
370             var rdata3 = g.list3.append({
371                 'row' : {
372                     'my' : {
373                         'value' : value,
374                         'label' : label
375                     }
376                 },
377                 'to_bottom' : true,
378                 'no_auto_select' : typeof list3_idx != 'undefined' ? true : undefined
379             });
380             g.list3_map[ rdata3.unique_row_counter ] = rdata3;
381         }
382
383         if (list3_idx) {
384             if (list3_idx < 0) { list3_idx = 0; }
385             if (list3_idx >= g.list3.node.view.rowCount) { list3_idx = g.list3.node.view.rowCount - 1; }
386             g.list3.node.view.selection.select(list3_idx);
387         }
388
389         // populate list2
390         var list2_data = [];
391         for (var value in g.data.toolbar_buttons) {
392             if (seen[value]) { continue; }
393             list2_data.push( { 'value' : value, 'label' : g.data.toolbar_buttons[value] } );
394         }
395         list2_data.sort(
396             function(a,b) {
397                 if (a.label < b.label) { return -1; }
398                 if (a.label > b.label) { return 1; }
399                 return 0;
400             }
401         );
402         list2_data = [
403             { 'value' : 'toolbarseparator', 'label' : $('adminStrings').getString('staff.admin.toolbar.toolbar_separator.list_entry') },
404             { 'value' : 'toolbarspacer', 'label' : $('adminStrings').getString('staff.admin.toolbar.toolbar_spacer.list_entry') }
405             //,{ 'value' : null, 'label' : '---' } // if we want to visually separate the spacer/separator from the other actions
406         ].concat(list2_data);
407
408         for (var i = 0; i < list2_data.length; i++) {
409             var rdata2 = g.list2.append({
410                 'row' : {
411                     'my' : list2_data[i]
412                 },
413                 'to_bottom' : true
414             });
415             g.list2_map[ rdata2.unique_row_counter ] = rdata2;
416         }
417
418     } catch(E) {
419         alert('Error in toolbar.js, populate_list2_list3(): ' + E);
420     }
421 }
422
423 function render_lib_menu() {
424     try {
425         var list = util.functional.map_list(
426             g.data.list.aou,
427             function(o) {
428                 var sname = o.shortname(); for (i = sname.length; i < 20; i++) sname += ' ';
429                 return [
430                     o.name() ? sname + ' ' + o.name() : o.shortname(),
431                     o.id(),
432                     false,
433                     ( g.data.hash.aout[ o.ou_type() ].depth() * 2),
434                 ];
435             }
436         );
437         var ml = util.widgets.make_menulist( list, ses('ws_ou') );
438         ml.setAttribute('id','lib_menu');
439
440         var x = $('lib_menu_placeholder');
441         if (x) {
442             util.widgets.remove_children(x);
443             x.appendChild(ml);
444         }
445
446     } catch(E) {
447         alert('Error in toolbar.js, render_lib_menu(): ' + E);
448     }
449 }
450
451 function lock_top_buttons() {
452     try {
453         oils_lock_page();
454         $('New').disabled = true;
455         $('Delete').disabled = true;
456         $('Save').disabled = false;
457         $('Cancel').disabled = false;
458     } catch(E) {
459         alert('Error in toolbar.js, lock_top_buttons(): ' + E);
460     }
461 }
462
463 function unlock_top_buttons() {
464     try {
465         oils_unlock_page();
466         $('New').disabled = false;
467         $('Delete').disabled = false;
468         $('Save').disabled = true;
469         $('Cancel').disabled = true;
470     } catch(E) {
471         alert('Error in toolbar.js, lock_top_buttons(): ' + E);
472     }
473 }
474
475 function Add(ev) {
476     try {
477         lock_top_buttons();
478         var values_to_add = get_list2_values_from_selection();
479         var temp = get_list3_values_from_selection();
480         var add_after_this_value = temp[ temp.length - 1 ]; // last selected value from list3
481         var add_after_this_position = g.layout.indexOf(add_after_this_value) + 1;
482
483         for (var i = values_to_add.length - 1; i >= 0; i--) { // iterate backwards so that we add them forwards
484             if (!values_to_add[i]) { continue; }
485             if (values_to_add[i].match('toolbarseparator') || values_to_add[i].match('toolbarspacer')) {
486                 values_to_add[i] = values_to_add[i] + '.' + (new Date()).getTime();
487             }
488             g.layout.splice(add_after_this_position,0,values_to_add[i]);
489         }
490
491         populate_list2_list3();
492         xulG.render_toolbar_layout(g.layout);
493
494     } catch(E) {
495         alert('Error in toolbar.js, Add(): ' + E);
496     }
497 }
498
499 function Remove(ev) {
500     try {
501         lock_top_buttons();
502         var values_to_remove = get_list3_values_from_selection();
503         for (var i = 0; i < values_to_remove.length; i++) {
504             var idx = g.layout.indexOf(values_to_remove[i]);
505             g.layout.splice(idx,1);
506         }
507
508         populate_list2_list3();
509         xulG.render_toolbar_layout(g.layout);
510
511     } catch(E) {
512         alert('Error in toolbar.js, Remove(): ' + E);
513     }
514 }
515
516 function Up(ev) {
517     try {
518         lock_top_buttons();
519         var values_to_move = get_list3_values_from_selection();
520         var idx;
521         for (var i = 0; i < values_to_move.length; i++) {
522             idx = g.layout.indexOf(values_to_move[i]);
523             if (idx == 0) { continue; }
524             g.layout.splice(idx,1);
525             g.layout.splice(idx-1,0,values_to_move[i]);
526         }
527
528         populate_list2_list3(idx-1);
529         xulG.render_toolbar_layout(g.layout);
530
531     } catch(E) {
532         alert('Error in toolbar.js, Up(): ' + E);
533     }
534 }
535
536 function Down(ev) {
537     try {
538         lock_top_buttons();
539         var values_to_move = get_list3_values_from_selection();
540         var idx;
541         for (var i = values_to_move.length - 1; i >= 0; i--) {
542             idx = g.layout.indexOf(values_to_move[i]);
543             g.layout.splice(idx+2,0,values_to_move[i]);
544             g.layout.splice(idx,1);
545         }
546
547         populate_list2_list3(idx+1);
548         xulG.render_toolbar_layout(g.layout);
549
550     } catch(E) {
551         alert('Error in toolbar.js, Down(): ' + E);
552     }
553 }
554
555 function Delete(ev) {
556     try {
557         g.selected_atb.isdeleted(1);
558
559         g.pcrud.apply(g.selected_atb);
560
561         delete g.data.hash.atb[ g.selected_atb.id() ];
562
563         var idx;
564         for (var i = 0; i < g.data.list.atb.length; i++) {
565             if ( g.data.list.atb[i].id() == g.selected_atb.id() ) { idx = i; } 
566         }
567         g.data.list.atb.splice(idx,1);
568
569         g.data.stash('hash','list');
570
571         unlock_top_buttons();
572
573         populate_list1();
574
575
576     } catch(E) {
577         alert('Error in toolbar.js, Delete(): ' + E);
578     }
579 }
580
581 function New(ev) {
582     try {
583         var perms_not_had = perm_check();
584         if (perms_not_had.length == 3) {
585             return; // we do disable the New button, but Operator Change can get around that
586         }
587
588         var name = window.prompt('Enter label for toolbar:');
589         if (!name) { return; }
590
591         var new_atb = new atb();
592         new_atb.isnew('1');
593         new_atb.label(name);
594         new_atb.layout('[]');
595         if (perms_not_had.indexOf('ADMIN_TOOLBAR_FOR_USER') == -1) {
596             new_atb.usr(ses('staff_id'));
597         } else if (perms_not_had.indexOf('ADMIN_TOOLBAR_FOR_WORKSTATION') == -1) {
598             new_atb.ws(ses('ws_id'));
599         } else if (perms_not_had.indexOf('ADMIN_TOOLBAR_FOR_ORG') == -1) {
600             new_atb.org($('lib_menu').value);
601         }
602
603         var rdata = g.list1.append({
604             'row' : {
605                 'my' : {
606                     'atb' : new_atb
607                 }
608             }
609         });
610         g.list1_map[ rdata.unique_row_counter ] = rdata;
611
612         setTimeout(
613             function() {
614                 lock_top_buttons();
615             }, 1000
616         );
617
618     } catch(E) {
619         alert('Error in toolbar.js, New(): ' + E);
620     }
621 }
622
623 function Cancel(ev) {
624     try {
625         unlock_top_buttons();
626         g.selected_atb = get_atb_from_selection();
627         if (!g.selected_atb) { return; }
628
629         if (g.selected_atb.id()) { // existing atb
630
631             g.layout = JSON2js(g.selected_atb.layout());
632             populate_list2_list3();
633             xulG.render_toolbar_layout(g.layout);
634
635         } else { // new atb
636
637             populate_list1();
638             populate_list2_list3();
639         }
640
641     } catch(E) {
642         alert('Error in toolbar.js, Cancel(): ' + E);
643     }
644 }
645
646 function Save(ev) {
647     try {
648         g.selected_atb.layout( js2JSON( g.layout ) );
649         switch($('context').selectedIndex) {
650             case 0: // org
651                 g.selected_atb.org($('lib_menu').value);
652                 g.selected_atb.ws(null);
653                 g.selected_atb.usr(null);
654             break;
655             case 1: // ws
656                 g.selected_atb.org(null);
657                 g.selected_atb.ws(ses('ws_id'));
658                 g.selected_atb.usr(null);
659             break;
660             case 2: // usr
661                 g.selected_atb.org(null);
662                 g.selected_atb.ws(null);
663                 g.selected_atb.usr(ses('staff_id'));
664             break;
665         }
666         g.selected_atb.ischanged(1);
667
668         g.pcrud.apply(g.selected_atb);
669
670         setTimeout( // is pcrud implicitly authoritative?
671             function() {
672                 JSAN.use('util.network');
673                 var net = new util.network;
674                 var r = net.simple_request(
675                     'FM_ATB_RETRIEVE_VIA_PCRUD',
676                     [
677                         ses(),
678                         {
679                             "-or": [
680                                 { "ws" : g.data.list.au[0].wsid() },
681                                 { "usr" : g.data.list.au[0].id() },
682                                 { "org" : util.functional.map_list( g.data.list.my_aou, function(o) { return o.id(); } ) }
683                             ]
684                         },
685                         {
686                             "order_by":{"atb":"label"}
687                         }
688                     ]
689                 );
690                 g.data.hash.atb = util.functional.convert_object_list_to_hash(r,null);
691                 g.data.list.atb = r;
692
693                 g.data.stash('hash','list');
694
695                 unlock_top_buttons();
696
697                 populate_list1();
698             }, 1000
699         );
700
701     } catch(E) {
702         alert('Error in toolbar.js, Save(): ' + E);
703     }
704 }
705
706