]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/xul/staff_client/server/patron/info_group.xul
merge users from patron search and patron group interfaces. getting db error from...
[working/Evergreen.git] / Open-ILS / xul / staff_client / server / patron / info_group.xul
1 <?xml version="1.0"?>
2 <!-- Application: Evergreen Staff Client -->
3 <!-- Screen: Patron Display -->
4
5 <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
6 <!-- STYLESHEETS -->
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 <?xml-stylesheet href="/xul/server/skin/global.css" type="text/css"?>
10 <?xml-stylesheet href="/xul/server/skin/patron_display.css" type="text/css"?>
11
12 <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
13 <!-- LOCALIZATION -->
14 <!DOCTYPE window PUBLIC "" ""[
15         <!--#include virtual="/opac/locale/${locale}/lang.dtd"-->
16 ]>
17
18 <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
19 <!-- OVERLAYS -->
20 <?xul-overlay href="/xul/server/OpenILS/util_overlay.xul"?>
21
22 <window id="patron_info_group_win" width="700" height="550"
23         onload="try{ my_init(); font_helper(); } catch(E) { alert(E); }"
24         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
25
26         <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
27         <!-- BEHAVIOR -->
28         <script type="text/javascript">var myPackageDir = 'open_ils_staff_client'; var IAMXUL = true; var g = {};</script>
29         <scripts id="openils_util_scripts"/>
30
31         <script type="text/javascript" src="/xul/server/main/JSAN.js"/>
32         <script>
33         <![CDATA[
34
35                 function $(id) { return document.getElementById(id); }
36
37                 function my_init() {
38                         try {
39                                 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
40                                 if (typeof JSAN == 'undefined') { throw( $("commonStrings").getString('common.jsan.missing') ); }
41                                 JSAN.errorLevel = "die"; // none, warn, or die
42                                 JSAN.addRepository('/xul/server/');
43
44                                 JSAN.use('util.error'); g.error = new util.error();
45                                 JSAN.use('util.network'); g.network = new util.network();
46                                 JSAN.use('util.date'); JSAN.use('util.money'); JSAN.use('patron.util'); JSAN.use('util.functional');
47                                 JSAN.use('OpenILS.data'); g.data = new OpenILS.data(); g.data.init({'via':'stash'});
48
49                                 g.error.sdump('D_TRACE','my_init() for patron_info_group.xul');
50
51                                 g.patron_id = xul_param('patron_id');
52
53                                 tree_init();
54
55                                 refresh();
56
57                         } catch(E) {
58                                 var err_msg = $("commonStrings").getFormattedString('common.exception', ['patron/info_group.xul', E]);
59                                 try { g.error.sdump('D_ERROR',err_msg); } catch(E) { dump(err_msg); }
60                                 alert(err_msg);
61                         }
62                 }
63
64                 function tree_init() {
65                                 JSAN.use('OpenILS.data'); g.OpenILS = {}; 
66                                 g.OpenILS.data = new OpenILS.data(); g.OpenILS.data.init({'via':'stash'});
67
68                                 JSAN.use('util.list'); g.list = new util.list('patron_list');
69
70                                 JSAN.use('patron.util');
71                                 var columns = patron.util.columns(
72                                         {
73                                                 'active' : { 'hidden' : 'false' },
74                                                 'barred' : { 'hidden' : 'false' },
75                                                 'family_name' : { 'hidden' : 'false' },
76                                                 'first_given_name' : { 'hidden' : 'false' },
77                                                 'second_given_name' : { 'hidden' : 'false' },
78                                                 'dob' : { 'hidden' : 'false' },
79                                                 'master_account' : { 'hidden' : 'false' },
80                                         }
81                                 );
82                                 g.list.init(
83                                         {
84                                                 'columns' : columns,
85                                                 'map_row_to_columns' : patron.util.std_map_row_to_columns(),
86                                                 'retrieve_row' : function(params) {
87                                                         var id = params.retrieve_id;
88                                                         var au_obj = patron.util.retrieve_au_via_id( ses(), id );
89
90                                                         var row = params.row;
91                                                         if (typeof row.my == 'undefined') row.my = {};
92                                                         row.my.au = au_obj;
93                                                         if (typeof params.on_retrieve == 'function') {
94                                                                 params.on_retrieve(row);
95                                                         }
96                                                         return row;
97                                                 },
98                                                 'on_select' : function(ev) {
99                                                         JSAN.use('util.functional');
100                                                         var sel = g.list.retrieve_selection();
101                                                         g.sel_list = util.functional.map_list(
102                                                                 sel,
103                                                                 function(o) { return o.getAttribute('retrieve_id'); }
104                                                         );
105                                                         if (g.sel_list.length > 0) {
106                                                                 $('retrieve_p').disabled = false;
107                                                                 $('retrieve_p').setAttribute('disabled','false');
108                                 if (g.sel_list.length > 1) {
109                                                                     $('merge_p').disabled = false;
110                                                                 $('merge_p').setAttribute('disabled','false');
111                                 }
112                                                                 $('clone').disabled = false;
113                                                                 $('clone').setAttribute('disabled','false');
114                                                                 $('remove').disabled = false;
115                                                                 $('remove').setAttribute('disabled','false');
116                                                                 $('move').disabled = false;
117                                                                 $('move').setAttribute('disabled','false');
118                                                         } else {
119                                                                 $('retrieve_p').disabled = true;
120                                                                 $('retrieve_p').setAttribute('disabled','true');
121                                                                 $('merge_p').disabled = true;
122                                                                 $('merge_p').setAttribute('disabled','true');
123                                                                 $('clone').disabled = true;
124                                                                 $('clone').setAttribute('disabled','true');
125                                                                 $('remove').disabled = true;
126                                                                 $('remove').setAttribute('disabled','true');
127                                                                 $('move').disabled = true;
128                                                                 $('move').setAttribute('disabled','true');
129                                                         }
130                                                 }
131                                         }
132                                 );
133                                 $('retrieve_p').disabled = true;
134                                 $('retrieve_p').setAttribute('disabled','true');
135                                 $('merge_p').disabled = true;
136                                 $('merge_p').setAttribute('disabled','true');
137                                 $('clone').disabled = true;
138                                 $('clone').setAttribute('disabled','true');
139                                 $('remove').disabled = true;
140                                 $('remove').setAttribute('disabled','true');
141                                 $('move').disabled = true;
142                                 $('move').setAttribute('disabled','true');
143                                 setTimeout( function() { $('patron_list').focus(); }, 0 );
144                 }
145
146                 function refresh() {
147                         retrieve_group_members();
148                 }
149
150                 function retrieve_group_members() {
151                         try {
152                                 JSAN.use('util.functional'); JSAN.use('patron.util');
153                                 g.group_members = [];
154                                 var p = patron.util.retrieve_au_via_id(ses(),g.patron_id);
155                                 if ((p == null) || (typeof p.ilsevent != 'undefined') ) throw(p);
156                                 var robj = g.network.simple_request(
157                                         'FM_AU_LIST_RETRIEVE_VIA_GROUP.authoritative',
158                                         [ ses(), p.usrgroup() ]
159                                 );
160                                 if ((robj == null) || (typeof robj.ilsevent != 'undefined') ) throw(robj);
161                                 var ids = util.functional.filter_list( robj, function(o) { return o != g.patron_id; });
162
163                                 g.list.clear();
164
165                                 var funcs = [];
166
167                                         function gen_func(r) {
168                                                 return function() {
169                                                         g.list.append( { 'retrieve_id' : r, 'row' : {} } );
170                                                 }
171                                         }
172
173                                 funcs.push( gen_func(g.patron_id) );
174                                 for (var i = 0; i < ids.length; i++) {
175                                         funcs.push( gen_func(ids[i]) );
176                                 }
177                                 JSAN.use('util.exec'); var exec = new util.exec(4);
178                                 exec.chain( funcs );
179
180                         } catch(E) {
181                                 g.error.standard_unexpected_error_alert($("patronStrings").getString('staff.patron.info_group.retrieve_group_members.failure'),E);
182                         }
183                 }
184
185                 function retrieve_patron() {
186                         try {
187                                 if (! g.sel_list ) return;
188                                 if (typeof window.xulG == 'object' && typeof window.xulG.new_tab == 'function') {
189                                         for (var i = 0; i < g.sel_list.length; i++) {   
190                                                 try {
191                                                         var url = urls.XUL_PATRON_DISPLAY// + '?id=' + window.escape( g.sel_list[i] );
192                                                         window.xulG.new_tab(
193                                                                 url, 
194                                                                 { 'tab_name' : $("patronStrings").getString('staff.patron.info_group.retrieve_patron.tab_name') }, 
195                                                                 { 
196                                                                         'id' : g.sel_list[i],
197                                                                         'url_prefix' : xulG.url_prefix,
198                                                                         'new_tab' : xulG.new_tab,
199                                     'set_tab' : xulG.set_tab
200                                                                 }
201                                                         );
202                                                 } catch(E) {
203                                                         g.error.standard_unexpected_error_alert($("patronStrings").getString('staff.patron.info_group.retrieve_patron.failed_retrieving_patron'),E);
204                                                 }
205                                         }
206                                 }
207                         } catch(E) {
208                                 g.error.standard_unexpected_error_alert($("patronStrings").getString('staff.patron.info_group.retrieve_patron.failed_retrieving_patrons'),E);
209                         }
210                 }
211
212         function merge_patrons() {
213                         try {
214                                 if (! g.sel_list ) return;
215                 JSAN.use('patron.util'); 
216                 var result = patron.util.merge(g.sel_list);
217                 if (result) {
218                     if (result != g.patron_id && g.sel_list.indexOf( g.patron_id ) != -1) {
219                         xulG.set_tab(
220                             urls.XUL_PATRON_DISPLAY,
221                             { 'tab_name' : $("patronStrings").getString('staff.patron.info_group.retrieve_patron.tab_name') }, 
222                             {
223                                 'id' : result,
224                                 'url_prefix' : xulG.url_prefix,
225                                 'new_tab' : xulG.new_tab,
226                                 'set_tab' : xulG.set_tab
227                             } 
228                         );
229                     } else {
230                         refresh();
231                     }
232                 }
233                         } catch(E) {
234                                 g.error.standard_unexpected_error_alert($("patronStrings").getString('staff.patron.info_group.merge_patrons.failed_merging_patrons'),E);
235                         }
236         }
237
238                 function clone_patron() {
239                         if (! g.sel_list ) return;
240                         try {
241                                 for (var i = 0; i < g.sel_list.length; i++) {   
242                                         var loc = xulG.url_prefix( urls.XUL_REMOTE_BROWSER ); 
243                                                 //+ '?url=' + window.escape( urls.XUL_PATRON_EDIT + '?ses=' 
244                                                 //+ window.escape( ses() ) + '&clone=' + g.sel_list[i] );
245                                         if (typeof window.xulG == 'object' && typeof window.xulG.new_tab == 'function') xulG.new_tab(
246                                                 loc, 
247                                                 {}, 
248                                                 { 
249                                                         'url' : urls.XUL_PATRON_EDIT, // + '?ses=' + window.escape(ses()) + '&clone=' + g.sel_list[i],
250                                                         'show_print_button' : true , 
251                                                         'tab_name' : $("patronStrings").getString('staff.patron.info_group.clone_patron.register_clone.tab_name'),
252                                                         'passthru_content_params' : {
253                                                                 'ses' : ses(),
254                                                                 'clone' : g.sel_list[i],
255                                                                 'spawn_search' : spawn_search,
256                                                                 'spawn_editor' : spawn_editor,
257                                                                 'on_save' : function() { refresh(); },
258                                                                 'url_prefix' : xulG.url_prefix,
259                                                                 'new_tab' : xulG.new_tab,
260                                                         },
261                                                         'url_prefix' : xulG.url_prefix,
262                                                         'new_tab' : xulG.new_tab,
263                                                 }
264                                         );
265                                 }
266                         } catch(E) {
267                                 g.error.standard_unexpected_error_alert($("patronStrings").getString('staff.patron.info_group.clone_patron.error_spawning_editors'),E);
268                         }
269                 }
270
271                 function spawn_editor(p) {
272                         var url = urls.XUL_PATRON_EDIT;
273                         var passthru = {
274                                 'spawn_search' : spawn_search,
275                                 'spawn_editor' : spawn_editor,
276                                 'on_save' : function() { refresh(); },
277                                 'url_prefix' : xulG.url_prefix,
278                                 'new_tab' : xulG.new_tab,
279                         };
280                         for (var i in p) {
281                                 passthru[i] = p[i];
282                         }
283                         var loc = xulG.url_prefix( urls.XUL_REMOTE_BROWSER ); // + '?url=' + window.escape( url );
284                         if (typeof window.xulG == 'object' && typeof window.xulG.new_tab == 'function') xulG.new_tab(
285                                 loc, 
286                                 {}, 
287                                 { 
288                                         'url' : url,
289                                         'show_print_button' : true , 
290                                         'tab_name' : $("patronStrings").getString('staff.patron.info_group.spwan_editor.editing_patron'),
291                                         'passthru_content_params' : passthru,
292                                         'url_prefix' : xulG.url_prefix,
293                                         'new_tab' : xulG.new_tab,
294                                 }
295                         );
296
297                 }
298
299                 function spawn_search(s) {
300                         try {
301                                 g.error.sdump('D_TRACE', 'Editor would like to search for: ' + js2JSON(s) ); 
302                                 var loc = xulG.url_prefix(urls.XUL_PATRON_DISPLAY);
303                                         //loc += '?doit=1&query=' + window.escape(js2JSON(s));
304                                 if (typeof window.xulG == 'object' && typeof window.xulG.new_tab == 'function') 
305                                         xulG.new_tab( loc, {}, {'doit':1,'query':s} );
306                         } catch(E) {
307                                 g.error.standard_unexpected_error_alert($("patronStrings").getString('staff.patron.info_group.spwan_search'),E);
308                         }
309                 }
310
311                 function remove_patron() {
312                         if (! g.sel_list ) return;
313                         var msg = '';
314                         for (var i = 0 ; i < g.sel_list.length; i++)
315                                 if (g.sel_list[i] == g.patron_id)
316                                         msg = $("patronStrings").getString('staff.patron.info_group.remove_patron.warning_message');
317                                         
318                         var c = window.confirm($("patronStrings").getFormattedString('staff.patron.info_group.remove_patron.warning_message_confirm', [msg]));
319                         if (c) {
320                                 for (var i = 0; i < g.sel_list.length; i++) {   
321                                         var robj = g.network.simple_request('FM_AU_NEW_USERGROUP', [ ses(), g.sel_list[i], get_db_true() ]);
322                                         if (typeof robj.ilsevent != 'undefined') {
323                                                 g.error.standard_unexpected_error_alert($("patronStrings").getFormattedString('staff.patron.info_group.remove_patron.error_removing_patron', [g.sel_list[i]]), robj);
324                                         }
325                                 }
326                                 alert($("patronStrings").getString('staff.patron.info_group.remove_patron.patrons_removed_from_group')); 
327                                 /* FIXME - xulrunner bug if this alert comes after refresh? */
328                                 /* that's okay, because now that we're on a distributed database, we want human delay to mitigate race conditions */
329                                 refresh();
330                         } else {
331                                 alert($("patronStrings").getString('staff.patron.info_group.remove_patron.patrons_not_removed_from_group'));
332                         }
333                 }
334
335                 function link_patron(direction) {
336                         try {
337                                 if (! g.sel_list ) { g.sel_list = []; g.sel_list[0] = g.patron_id; }
338                                 if (direction == null) throw($("patronStrings").getString('staff.patron.info_group.link_patron.null_not_allowed'));
339                                 var first_msg; var second_msg;
340                                 switch(direction) {
341                                         case true:
342                                                 first_msg = "-->";
343                                                 break;
344                                         case false:
345                                                 first_msg = "<--";
346                                                 break;
347                                         default:
348                                                 throw($("patronStrings").getString('staff.patron.info_group.link_patron.invalid_parameter'));
349                                                 break;
350                                 }
351                                 var barcode = window.prompt($("patronStrings").getString('staff.patron.info_group.link_patron.scan_patron_barcode'),'',first_msg);
352                                 if (!barcode) return;
353                                 JSAN.use('patron.util');
354                                 var patron_b = patron.util.retrieve_fleshed_au_via_barcode(ses(),barcode);
355                                 if (typeof patron_b.ilsevent != 'undefined') throw(patron_b);
356
357                                 if (g.sel_list.length == 0) g.sel_list[0] = g.patron_id;
358                                 for (var i = 0; i < g.sel_list.length; i++) {   
359
360                                         var patron_a = patron.util.retrieve_fleshed_au_via_id(ses(),g.sel_list[i]);
361                                         if (typeof patron_a.ilsevent != 'undefined') throw(patron_a);
362                                         switch(direction) {
363                                                 case true:
364                                                         second_msg = $("patronStrings").getFormattedString('staff.patron.info_group.link_patron.move_patron_to_new_usergroup',[patron_a.card().barcode(), patron_b.card().barcode()]);
365                                                         break;
366                                                 case false:
367                                                         second_msg = $("patronStrings").getFormattedString('staff.patron.info_group.link_patron.move_patron_to_new_usergroup',[patron_b.card().barcode(), patron_a.card().barcode()]);
368                                                         break;
369                                         }
370
371                                         netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserWrite');
372                                         var top_xml = '<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" flex="1" style="overflow: auto"><description>' + second_msg + '</description>';
373                                         top_xml += '<hbox><spacer flex="1"/><button label="'+$("patronStrings").getString('staff.patron.info_group.link_patron.move.label')+'"';
374                                         top_xml += ' accesskey="'+$("patronStrings").getString('staff.patron.info_group.link_patron.move.accesskey')+'" name="fancy_submit"/>';
375                                         top_xml += '<button label="'+$("patronStrings").getString('staff.patron.info_group.link_patron.done.label')+'"';
376                                         top_xml += ' accesskey="'+$("patronStrings").getString('staff.patron.info_group.link_patron.done.accesskey')+'" name="fancy_cancel"/></hbox></vbox>';
377                                         var xml = '<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" flex="1" style="overflow: vertical"><hbox flex="1">';
378                                         /************/
379                                         xml += '<vbox flex="1">';
380                                         xml += '<hbox><spacer flex="1"/>';
381                                         if (direction) {
382                                                 xml += '<image src="/xul/server/skin/media/images/patron_right_arrow.png"/>';
383                                         } else {
384                                                 xml += '<image src="/xul/server/skin/media/images/patron_left_arrow.png"/>';
385                                         }
386                                         xml += '</hbox>';
387                                         xml += '<iframe style="min-height: 100px" flex="1" src="' + xulG.url_prefix( urls.XUL_PATRON_SUMMARY );
388                                         xml += '?show_name=1&amp;id=' + g.sel_list[i] + '"/>';
389                                         xml += '</vbox>';
390                                         xml += '<vbox flex="1">';
391                                         xml += '<hbox>';
392                                         if (direction) {
393                                                 xml += '<image src="/xul/server/skin/media/images/patron_right_arrow.png"/>';
394                                         } else {
395                                                 xml += '<image src="/xul/server/skin/media/images/patron_left_arrow.png"/>';
396                                         }
397                                         xml += '<spacer flex="1"/></hbox>';
398                                         xml += '<iframe style="min-height: 100px" flex="1" src="' + xulG.url_prefix( urls.XUL_PATRON_SUMMARY );
399                                         xml += '?show_name=1&amp;id=' + patron_b.id() + '"/>';
400                                         xml += '</vbox>';
401                                         /************/
402                                         xml += '</hbox></vbox>';
403                                         
404                                         var bot_xml = '<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" flex="1" style="overflow: auto"><hbox>';
405                                         bot_xml += '</hbox></vbox>';
406                 
407                                         //g.data.temp_top = top_xml; g.data.stash('temp_top');
408                                         //g.data.temp_mid = xml; g.data.stash('temp_mid');
409                                         //g.data.temp_bot = bot_xml; g.data.stash('temp_bot');
410                                         JSAN.use('util.window'); var win = new util.window();
411                                         var fancy_prompt_data = win.open(
412                                                 urls.XUL_FANCY_PROMPT,
413                                                 //+ '?xml_in_stash=temp_mid'
414                                                 //+ '&top_xml_in_stash=temp_top'
415                                                 //+ '&bottom_xml_in_stash=temp_bot'
416                                                 //+ '&title=' + window.escape('Move Patron into a Usergroup'),
417                                                 'fancy_prompt', 'chrome,resizable,modal,width=700,height=500',
418                                                 { 'xml' : xml, 'top_xml' : top_xml, 'bottom_xml' : bot_xml, 'title' : $("patronStrings").getString('staff.patron.info_group.link_patron.move_patron_to_usergroup')}
419                                         );
420                                         if (fancy_prompt_data.fancy_status == 'incomplete') { continue; }
421                                         else {
422                                                 var patron_c;
423                                                 switch(direction) {
424                                                         case true:
425                                                                 patron_a.usrgroup( patron_b.usrgroup() );
426                                                                 patron_a.ischanged( '1' );
427                                                                 patron_c = patron_a;
428                                                         break;
429                                                         case false:
430                                                                 patron_b.usrgroup( patron_a.usrgroup() );
431                                                                 patron_b.ischanged( '1' );
432                                                                 patron_c = patron_b;
433                                                         break;
434                                                 }
435                                                 var robj = g.network.simple_request('FM_AU_UPDATE',[ ses(), patron_c ]);
436                                                 if (typeof robj.ilsevent != 'undefined') g.error.standard_unexpected_error_alert($("patronStrings").getFormattedString('staff.patron.info_group.link_patron.error_linking_patron', [g.sel_list[i]]), robj);
437                                         }
438                                 }
439                                 alert($("patronStrings").getString('staff.patron.info_group.link_patron.usergroups_updated'));
440                                 refresh();
441                         } catch(E) {
442                                 g.error.standard_unexpected_error_alert($("patronStrings").getString('staff.patron.info_group.link_patron.error_linking_patrons'),E);
443                                 refresh();
444                         }
445                 }
446
447         ]]>
448         </script>
449         
450         <messagecatalog id="patronStrings" src="/xul/server/locale/<!--#echo var='locale'-->/patron.properties"/>
451
452         <commandset id="info_group_cmds">
453                 <command id="clone" accesskey="&staff.patron.info_group.clone.accesskey;" label="&staff.patron.info_group.clone.label;" oncommand="try{clone_patron();}catch(E){alert('FIXME:'+E);}"/>
454                 <command id="remove" accesskey="&staff.patron.info_group.remove.accesskey;" label="&staff.patron.info_group.remove.label;" oncommand="try{remove_patron();}catch(E){alert('FIXME:'+E);}"/>
455                 <command id="move" accesskey="&staff.patron.info_group.move.accesskey;" label="&staff.patron.info_group.move.label;" oncommand="try{link_patron(true);}catch(E){alert('FIXME:'+E);}"/>  
456                 <command id="add" accesskey="&staff.patron.info_group.add.accesskey;" label="&staff.patron.info_group.add.label;" oncommand="try{link_patron(false);}catch(E){alert('FIXME:'+E);}"/>    
457                 <command id="retrieve_p" label="&staff.patron.info_group.retrieve_p.label;" accesskey="&staff.patron.info_group.retrieve_p.accesskey;" oncommand="try{retrieve_patron();}catch(E){alert(E);}"/>
458                 <command id="merge_p" label="&staff.patron.info_group.merge_patrons.label;" accesskey="&staff.patron.info_group.merge_patrons.accesskey;" oncommand="try{merge_patrons();}catch(E){alert(E);}"/>
459         </commandset>
460
461         <popupset id="info_group_popupset">
462                 <popup id="info_group_actions" position="at_pointer"> 
463                         <menuitem command="clone" />
464                         <menuitem command="remove" />
465                         <menuitem command="move" />
466                         <menuitem command="add" />
467                         <menuitem command="retrieve_p" />
468                         <menuitem command="merge_p" />
469                 </popup>
470         </popupset>
471
472         <vbox flex="1" class="my_overflow" id="group_panel">
473                 <groupbox flex="1">
474                         <caption label="&staff.patron.info_group.group_member.label;"/>
475                         <hbox>
476                                 <spacer flex="1"/>
477                                 <menubar id="ml">
478                                         <menu label="&staff.patron.info_group.choose_an_action.label;" accesskey="&staff.patron.info_group.choose_an_action.accesskey;" value="0">
479                                                 <menupopup>
480                                                         <menuitem command="clone" />
481                                                         <menuitem command="remove" />
482                                                         <menuitem command="move" />
483                                                         <menuitem command="add" />
484                                                         <menuitem command="retrieve_p" />
485                                                         <menuitem command="merge_p" />
486                                                 </menupopup>
487                                         </menu>
488                                 </menubar>
489                         </hbox>
490                         <tree id="patron_list" flex="1" enableColumnDrag="true" seltype="multiple" context="info_group_actions"/>
491                 </groupbox>
492         </vbox>
493
494
495 </window>
496