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