2 # Copyright (C) 2008 Georgia Public Library Service / Equinox Software, Inc
3 # Mike Rylander <miker@esilibrary.com>
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License
7 # as published by the Free Software Foundation; either version 2
8 # of the License, or (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
16 "-//W3C//DTD XHTML 1.0 Transitional//EN"
17 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" [
18 <!--#include virtual="/opac/locale/${locale}/conify.dtd"-->
20 <html xmlns="http://www.w2.org/1999/xhtml">
22 <title>&conify.grp_tree.group_tree.title;</title>
24 <style type="text/css">
25 @import url('/js/dojo/dojox/grid/_grid/tundraGrid.css');
26 @import url('/js/dojo/dojo/resources/dojo.css');
27 @import url('/js/dojo/dijit/themes/tundra/tundra.css');
28 @import url('/js/dojo/dojox/widget/Toaster/Toaster.css');
31 <style type="text/css">
36 margin: 0px 0px 0px 0px;
37 padding: 0px 0px 0px 0px;
60 /* this is a hack to get the right pane to display
61 in recent browsers when using this interface
62 embedded in the web staff client
64 .dijitLayoutContainer {
70 <!-- The OpenSRF API writ JS -->
71 <script language='javascript' src='/IDL2js' type='text/javascript'></script>
72 <script language='javascript' src='/opac/common/js/utils.js' type='text/javascript'></script>
73 <script language='javascript' src='/opac/common/js/CGI.js' type='text/javascript'></script>
74 <script language='javascript' src='/opac/common/js/JSON_v1.js' type='text/javascript'></script>
76 <!-- Dojo goodness -->
77 <script type="text/javascript" src="../admin.js"></script>
78 <script type="text/javascript" src="/js/dojo/dojo/dojo.js"></script>
79 <script type="text/javascript" src="/js/dojo/dojo/openils_dojo.js"></script>
80 <script type="text/javascript" src="/js/dojo/dijit/dijit.js"></script>
82 <script type="text/javascript" src="grp_tree.js"></script>
84 <script type="text/javascript"><![CDATA[
88 var _group_list = server.pcrud.retrieveAll('pgt', { order_by : { pgt : 'name' } });
89 var _group_data = pgt.toStoreData( _group_list );
90 var group_store = new dojo.data.ItemFileWriteStore({ data : _group_data });
92 group_store.onSet = function (item, attr, o, n) {
93 if (attr == 'ischanged') return;
95 this.setValue( item, 'ischanged', 1);
98 dojo.addOnUnload( function (event) {
101 query : { ischanged : 1 },
102 queryOptions : { deep : true },
103 onItem : function (item, req) { try { if (this.isItem( item )) dirtyStore.push( item ); } catch (e) { /* meh */ } },
107 if (dirtyStore.length > 0) {
108 var confirmation = confirm( pgt_strings.CONFIRM_EXIT_PGT );
111 for (var i in dirtyStore) {
112 current_group = dirtyStore[i];
120 var _ou_type_list = server.pcrud.retrieveAll('aout', { order_by : { aout : 'depth' } });
121 var _ou_type_data = aout.toStoreData( _ou_type_list );
122 var ou_type_store = new dojo.data.ItemFileReadStore({ data : _ou_type_data });
124 var _perm_list = server.pcrud.retrieveAll('ppl', { order_by : { ppl : 'code' } });
125 var _perm_data = ppl.toStoreData( _perm_list, 'code' );
126 var _perm_name_data = ppl.toStoreData( _perm_list, 'code', { identifier : 'code' } );
128 var perm_store = new dojo.data.ItemFileWriteStore({ data : _perm_data });
129 var perm_name_store = new dojo.data.ItemFileWriteStore({ data : _perm_name_data });
131 var _perm_map_list = server.pcrud.retrieveAll('pgpm');
132 var _perm_map_data = pgpm.toStoreData( _perm_map_list, 'id' );
133 var perm_map_store = new dojo.data.ItemFileWriteStore({ data : _perm_map_data });
135 perm_map_store.onSet = function (item, attr, o, n) {
136 if (attr == 'ischanged') return;
139 this.setValue( item, 'ischanged', 1);
141 if (attr == 'grantable' && (typeof (n) != 'string'))
142 this.setValue(item, 'grantable', n ? 't' : 'f');
145 dojo.addOnUnload( function (event) { save_them_all(); });
151 <body class="tundra" id='pagebody'>
153 <div dojoType="dijit.layout.SplitContainer" orientation="horizontal" style="height: 100%">
155 <div dojoType="dijit.layout.ContentPane" sizeShare="100">
158 label="&conify.grp_tree.permission_groups.label;"
159 dojoType="dijit.Tree"
161 query="{'_top':'true'}"
166 <script type="dojo/method" event="onClick" args="item,node">
168 right_pane_toggler.show();
170 current_group = item;
171 window.current_fm_group = new pgt().fromStoreItem(item);
173 perm_map_model.query = { grp : current_group ? group_store.getValue(current_group,'id') : -1 };
174 perm_map_model.refresh();
177 highlighter.editor_pane.green.play();
178 status_update( dojo.string.substitute( pgt_strings.STATUS_EDITING, [this.store.getValue( item, 'name' )]) );
180 new_kid_button.disabled = false;
181 save_group_button.disabled = false;
182 delete_group_button.disabled = false;
184 var main_settings_fields = [ 'name', 'perm_interval', 'description'];
185 for ( var i in main_settings_fields ) {
186 var field = main_settings_fields[i];
187 var value = this.store.getValue( current_group, field );
190 window["editor_pane_" + field].setValue( '' ); // unset the value
191 if (field != 'description') window["editor_pane_" + field].setDisplayedValue( '' ); // unset the value
192 } else window["editor_pane_" + field].setValue( value );
195 if ( this.store.getValue( current_group, '_trueRoot' ) == 'true' ) {
196 editor_pane_parent.disabled = true;
197 editor_pane_parent.setValue(null);
198 editor_pane_parent.setDisplayedValue('');
199 editor_pane_parent.validate(false);
201 editor_pane_parent.disabled = false;
202 editor_pane_parent.validate(true);
203 editor_pane_parent.setValue( this.store.getValue( current_group, 'parent' ) );
206 editor_pane_application_perm.setValue( this.store.getValue( current_group, 'application_perm' ) );
207 editor_pane_hold_priority.setValue( this.store.getValue( current_group, 'hold_priority' ) );
209 editor_pane_usergroup.setChecked( this.store.getValue( current_group, 'usergroup' ) == 't' ? true : false );
213 <script type="dojo/method" event="getLabel" args="item,pI">
214 var label = this.store.getValue(item,'name');
215 if (this.store.getValue(item,'ischanged') == 1) label = '* ' + label;
222 <div id="right_pane" dojoType="dijit.layout.ContentPane" sizeShare="300">
223 <script type="dojo/method">
224 window.right_pane_toggler = new dojo.fx.Toggler({ node: 'right_pane'});
225 window.right_pane_toggler.hide();
228 <div dojoType="dijit.layout.TabContainer">
229 <div id="editor_pane" dojoType="dijit.layout.ContentPane" title="&conify.grp_tree.group_config.label;">
230 <script type="dojo/method">
231 highlighter.group_tree = {};
232 highlighter.editor_pane = {};
233 highlighter.group_tree.green = dojox.fx.highlight( { color : '#B4FFB4', node : 'group_tree', duration : 500 } );
234 highlighter.group_tree.red = dojox.fx.highlight( { color : '#FF2018', node : 'group_tree', duration : 500 } );
235 highlighter.editor_pane.green = dojox.fx.highlight( { color : '#B4FFB4', node : 'editor_pane', duration : 500 } );
236 highlighter.editor_pane.red = dojox.fx.highlight( { color : '#FF2018', node : 'editor_pane', duration : 500 } );
239 <table class="tundra" style="margin:10px;">
241 <th>&conify.grp_tree.group_name.label;</th>
243 <span id="editor_pane_name" dojoType="dijit.form.ValidationTextBox" jsId="editor_pane_name" regExp=".+" required="true">
244 <script type="dojo/connect" event="onChange">
246 group_store.setValue( current_group, "name", this.getValue() );
250 <span dojoType="openils.widget.TranslatorPopup" targetObject="current_fm_group" field="name"></span>
254 <th>&conify.grp_tree.description.label;</th>
258 id="editor_pane_description"
259 dojoType="dijit.form.Textarea"
260 jsId="editor_pane_description"
261 onChange="if (current_group) group_store.setValue( current_group, 'description', this.getValue() );"
264 <span dojoType="openils.widget.TranslatorPopup" targetObject="current_fm_group" field="description"></span>
268 <th>&conify.grp_tree.permission_interval.label;</th>
270 <span id="editor_pane_perm_interval" dojoType="dijit.form.ValidationTextBox" jsId="editor_pane_perm_interval" regExp="^\d+ (?:y.*|mo.*|d.*)$" required="true">
271 <script type="dojo/connect" event="onChange">
273 group_store.setValue( current_group, "perm_interval", this.getValue() );
280 <th>&conify.grp_tree.editing_permission.label;</th>
283 id="editor_pane_application_perm"
284 dojoType="dijit.form.FilteringSelect"
285 store="perm_name_store"
287 jsId="editor_pane_application_perm"
289 <script type="dojo/connect" event="onChange">
291 if (current_group && this.getValue()) {
292 group_store.setValue( current_group, "application_perm", this.getValue() );
300 <th>&conify.grp_tree.hold_priority.label;</th>
303 id="editor_pane_hold_priority"
304 dojoType="dijit.form.NumberSpinner"
305 jsId="editor_pane_hold_priority"
307 <script type="dojo/connect" event="onChange">
309 if (current_group && this.getValue()) {
310 group_store.setValue( current_group, "hold_priority", this.getValue() );
318 <th>&conify.grp_tree.parent_group.label;</th>
321 id="editor_pane_parent"
322 dojoType="dijit.form.FilteringSelect"
323 jsId="editor_pane_parent"
329 <script type="dojo/connect" event="onChange">
331 if (current_group && this.getValue()) {
332 this.store.setValue( current_group, "parent", this.getValue() );
340 <th>&conify.grp_tree.user_group.label;</th>
343 id="editor_pane_usergroup"
344 jsId="editor_pane_usergroup"
346 dojoType="dijit.form.CheckBox"
347 onChange="if (current_group) group_store.setValue( current_group, 'usergroup', this.checked ? 't' : 'f' );"
353 <div dojoType="dijit.layout.ContentPane" orientation="horizontal" style="margin-bottom: 20px;">
355 <button jsId="save_group_button" dojoType="dijit.form.Button" label="&conify.grp_tree.save_button.label;" onClick="save_group()">
356 <script type="dojo/connect" event="startup">
357 this.disabled = true;
361 <button jsId="delete_group_button" dojoType="dijit.form.Button" label="&conify.grp_tree.delete_button.label;">
362 <script type="dojo/connect" event="startup">
363 this.disabled = true;
365 <script type="dojo/connect" event="onClick">
368 if (group_store.getValue( current_group, '_trueRoot' ) == 'true') {
369 highlighter.editor_pane.red.play();
370 status_update( dojo.string.substitute( pgt_strings.STATUS_ERR_DELETING, [group_store.getValue( current_group, 'name' )]) );
374 if ( current_group.children ) {
375 var kids = current_group.children;
376 if (!dojo.isArray(kids)) kids = [kids];
378 var existing_kids = dojo.filter(
380 function(kid){ return kid.isdeleted[0] != 1 }
382 if ( existing_kids.length > 0) {
383 highlighter.editor_pane.red.play();
384 status_update( dojo.string.substitute( pgt_strings.STATUS_ERR_DELETING_DEPENDENCY, [group_store.getValue( current_group, 'name' ), existing_kids.length]) );
389 if ( confirm( dojo.string.substitute( pgt_strings.CONFIRM_DELETE, [current_group.name]) ) ) {
390 group_store.setValue( current_group, 'isdeleted', 1 );
392 var modified_pgt = new pgt().fromStoreItem( current_group );
393 modified_pgt.isdeleted( 1 );
395 server.pcrud.eliminate( modified_pgt, {
396 onerror : function (r) {
397 highlighter.editor_pane.red.play();
398 status_update( dojo.string.substitute( pgt_strings.CONFIRM_DELETE, [group_store.getValue( current_group, 'name' )]) );
400 oncomplete : function (r) {
401 var old_name = group_store.getValue( current_group, 'name' );
404 query : { id : group_store.getValue( current_group, 'id' ) },
405 queryOptions : { deep : true },
406 onItem : function (item, req) { try { if (this.isItem( item )) this.deleteItem( item ); } catch (e) { /* meh */ } },
410 current_group = null;
412 new_kid_button.disabled = true;
413 save_group_button.disabled = true;
414 delete_group_button.disabled = true;
416 var main_settings_fields = [ 'name', 'perm_interval', 'description' ];
417 for ( var i in main_settings_fields ) {
418 var field = main_settings_fields[i];
419 window["editor_pane_" + field].setValue( '' ); // unset the value
420 window["editor_pane_" + field].setDisplayedValue( '' ); // unset the value
423 window["editor_pane_usergroup"].setChecked( false ); // unset the value
425 highlighter.editor_pane.green.play();
426 status_update( dojo.string.substitute( pgt_strings.STATUS_DELETED, [old_name]) );
437 <button jsId="new_kid_button" dojoType="dijit.form.Button" label="&conify.grp_tree.new_child_button.label;">
438 <script type="dojo/connect" event="startup">
439 this.disabled = true;
441 <script type="dojo/connect" event="onClick">
444 var new_fm_obj = new pgt().fromHash({
446 name : pgt_strings.LABEL_NEW_GROUP,
448 parent : group_store.getValue( current_group, 'id' )
453 server.pcrud.create( new_fm_obj, {
454 onerror : function (r) {
455 highlighter.editor_pane.red.play();
456 status_update( pgt_strings.ERROR_CALLING_METHOD_PGT );
459 oncomplete : function (r,list) {
460 group_store.newItem( list[0].toStoreItem(), { parent : current_group, attribute : 'children' } );
465 highlighter.editor_pane.green.play();
466 highlighter.group_tree.green.play();
467 status_update( dojo.string.substitute( pgt_strings.SUCCESS_NEW_CHILD_GROUP, [group_store.getValue( current_group, 'name' )]) );
475 <div id="perm_pane" dojoType="dijit.layout.ContentPane" title="&conify.grp_tree.group_permissions.title;">
476 <script type="dojo/connect" event="onShow">
477 perm_map_model.query = { grp : current_group ? group_store.getValue(current_group,'id') : -1 };
478 perm_map_model.refresh();
481 <div dojoType="dijit.layout.LayoutContainer" orientation="horizontal" style="width:100%; height:100%; min-height: 250px">
482 <div id="grid_container" dojoType="dijit.layout.ContentPane" sizeShare="1" layoutAlign="left">
483 <div dojoType="dojox.grid.data.DojoData" id="perm_map_model" jsId="perm_map_model" store="perm_map_store"></div>
485 <div id="perm_grid" dojoType="dojox.Grid" model="perm_map_model" jsId="perm_grid">
486 <script type="dojo/connect" event="startup">
488 function get_item_part(model_field, item_search_field, item_part, model, store, datum, row) {
489 var formatter = true;
491 if (!row && row != '0') {
496 if(!model.getRow(row)) return null;
499 if(!formatter) { //this.editor && (this.editor.alwaysOn || (this.grid.edit.info.rowIndex==row && this.grid.edit.info.cell==this))) {
500 return model.getRow(row)[model_field];
504 q[item_search_field] = model.getRow(row)[model_field];
508 onItem : function (item) { value = store.getValue( item, item_part ) }
514 window.current_perm_grid_layout = [
517 { name : pgt_strings.LABEL_CODE,
519 formatter : dojo.partial(get_item_part, "perm", "id", "code", perm_map_model, perm_store),
522 { name : pgt_strings.LABEL_DEPTH,
524 formatter : dojo.partial(get_item_part, "depth", "depth", "name", perm_map_model, ou_type_store),
525 editor : dojox.grid.editors.select,
526 options : dojo.map( _ou_type_list, function (x) { return x.name() } ),
527 values : dojo.map( _ou_type_list, function (x) { return x.depth() } )
529 { name : pgt_strings.LABEL_GRANTABLE,
531 editor : dojox.grid.editors.bool,
532 get : function (row) {
533 var gr = get_item_part("id", "id", "grantable", perm_map_model, perm_map_model.store, row, row);
534 if (gr == 't' || gr === true) return true;
543 perm_grid.setStructure(window.current_perm_grid_layout);
549 <div id="new_perm_container" dojoType="dijit.layout.ContentPane" sizeShare="1" layoutAlign="client">
551 <div dojoType="dijit.form.DropDownButton" id="new_popup" jsId="new_popup">
552 <span>&conify.grp_tree.new_mapping.label;</span>
553 <div dojoType="dijit.TooltipDialog">
554 <table class="tundra">
556 <td>&conify.grp_tree.permission.label;</td>
559 dojoType="dijit.form.FilteringSelect"
561 jsId="new_perm_select"
565 required="true"></div>
569 <td>&conify.grp_tree.depth.label;</td>
572 dojoType="dijit.form.FilteringSelect"
573 Id="new_depth_select"
574 jsId="new_depth_select"
575 store="ou_type_store"
578 required="true"></div>
582 <td>&conify.grp_tree.grantable.label;</td>
586 dojoType="dijit.form.CheckBox"
587 Id="new_grant_checkbox"
588 jsId="new_grant_checkbox"
594 <button dojoType="dijit.form.Button" jsId="new_mapping_add" label="&conify.grp_tree.add_mapping_button.label;">
595 <script type="dojo/connect" event="onClick">
597 var new_perm = new_perm_select.getValue();
598 if (!new_perm) return;
600 var new_type_id = new_depth_select.getValue();
601 if (!new_type_id) return;
604 window.ou_type_store.fetch({
605 query : { id : new_type_id },
606 onItem : function (item, req) { try { new_type = item } catch (e) { /* meh */ } },
609 var new_depth = ou_type_store.getValue( new_type, 'depth')
610 var new_grant = new_grant_checkbox.getValue();
612 var new_fm_obj = new pgpm().fromHash({
616 grp : group_store.getValue( current_group, 'id' ),
617 grantable : new_grant ? 't' : 'f'
621 server.pcrud.create(new_fm_obj, {
622 onerror : function (r) {
623 highlighter.group_tree.red.play();
624 status_update( pgt_strings.ERROR_CALLING_METHOD_PERM_MAP );
627 oncomplete : function (r, list) {
629 var new_item_hash = list[0].toStoreItem();
630 perm_map_store.newItem( new_item_hash );
631 status_update( pgt_strings.SUCCESS_NEW_PERM_MAP );
632 highlighter.group_tree.green.play();
634 perm_map_model.query = { grp : current_group ? group_store.getValue(current_group,'id') : -1 };
635 perm_grid.model.sort(-1);
636 perm_map_model.refresh();
642 new_popup._closeDropDown();
650 <button jsId="save_pgpm_button" dojoType="dijit.form.Button" label="&conify.grp_tree.save_changes.label;" onClick="save_them_all()"></button><br/>
652 <button jsId="delete_pgpm_button" dojoType="dijit.form.Button" label="&conify.grp_tree.remove_selected.label;">
653 <script type="dojo/connect" event="onClick">
655 var selected_rows = perm_grid.selection.getSelected();
657 var selected_items = [];
658 for (var i in selected_rows) {
660 perm_grid.model.getRow( selected_rows[i] ).__dojo_data_item
664 perm_grid.selection.clear();
666 for (var i in selected_items) {
667 window.current_perm_map = selected_items[i];
669 perm_map_store.setValue( window.current_perm_map, 'isdeleted', 1 );
671 var modified_pgpm = new pgpm().fromStoreItem( window.current_perm_map );
672 modified_pgpm.isdeleted( 1 );
674 server.pcrud.eliminate( modified_pgpm, {
675 onerror : function (r) {
676 highlighter.editor_pane.red.play();
677 status_update( dojo.string.substitute( pgt_strings.ERROR_DELETING_PERM_MAPPING, [perm_map_store.getValue( window.current_perm_map, 'id' )] ) );
679 oncomplete : function (r, list) {
681 perm_map_store.fetch({
682 query : { id : perm_map_store.getValue( window.current_perm_map, 'id' ) },
683 onItem : function (item, req) { try { if (this.isItem( item )) this.deleteItem( item ); } catch (e) { /* meh */ } },
684 scope : perm_map_store
687 window.current_perm_map = null;
689 highlighter.editor_pane.green.play();
690 status_update( pgt_strings.SUCCESS_DELETED_PERM_MAP );