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.
15 <html xmlns="http://www.w2.org/1999/xhtml">
17 <title>Conify :: Global :: Permission :: Group Tree</title>
19 <style type="text/css">
20 @import url('/js/dojo/dojox/grid/_grid/tundraGrid.css');
21 @import url('/js/dojo/dojo/resources/dojo.css');
22 @import url('/js/dojo/dijit/themes/tundra/tundra.css');
23 @import url('/js/dojo/dojox/widget/Toaster/Toaster.css');
31 margin: 0px 0px 0px 0px;
32 padding: 0px 0px 0px 0px;
57 <!-- The OpenSRF API writ JS -->
58 <script language='javascript' src='/opac/common/js/utils.js' type='text/javascript'></script>
59 <script language='javascript' src='/opac/common/js/Cookies.js' type='text/javascript'></script>
60 <script language='javascript' src='/opac/common/js/CGI.js' type='text/javascript'></script>
61 <script language='javascript' src='/opac/common/js/JSON_v1.js' type='text/javascript'></script>
63 <!-- Dojo goodness -->
64 <script type="text/javascript" src="../admin.js"></script>
65 <script type="text/javascript" src="/js/dojo/dojo/dojo.js"></script>
66 <script type="text/javascript" src="/js/dojo/dijit/dijit.js"></script>
68 <script type="text/javascript" src="grp_tree.js"></script>
72 <body class="tundra" id='pagebody'>
74 <div dojoType="dijit.layout.SplitContainer" orientation="horizontal" style="height: 100%">
76 <div dojoType="dijit.layout.ContentPane" sizeShare="100">
77 <script type="dojo/method">
79 window.dirtyStore = [];
81 server.pCRUD.request({
82 method : 'open-ils.permacrud.search.pgt.atomic',
84 params : [ ses, { id : { "!=" : null } }, { order_by : { pgt : 'name' } } ],
85 onerror : function (r) { status_update('Problem fetching groups') },
86 oncomplete : function (r) {
87 window._group_list = r.recv().content();
88 window._group_data = pgt.toStoreData( window._group_list );
89 window.group_store = new dojo.data.ItemFileWriteStore({ data : window._group_data });
90 window.group_store.onSet = function (item, attr, o, n) {
91 if (attr == 'ischanged') return;
93 this.setValue( item, 'ischanged', 1);
95 dojo.addOnUnload( function (event) {
97 window.group_store.fetch({
98 query : { ischanged : 1 },
99 queryOptions : { deep : true },
100 onItem : function (item, req) { try { if (this.isItem( item )) window.dirtyStore.push( item ); } catch (e) { /* meh */ } },
101 scope : window.group_store
104 if (dirtyStore.length > 0) {
105 var confirmation = confirm(
106 'There are unsaved modified Groups! '+
107 'OK to save these changes, Cancel to abandon them.'
111 for (var i in window.dirtyStore) {
112 window.current_group = window.dirtyStore[i];
122 server.actor.request({
123 method : 'open-ils.actor.org_types.retrieve',
125 onerror : function (r) { status_update('Problem fetching types') },
126 oncomplete : function (r) {
127 window._ou_type_list = r.recv().content();
128 window._ou_type_data = aout.toStoreData( window._ou_type_list );
129 window.ou_type_store = new dojo.data.ItemFileReadStore({ data : window._ou_type_data });
133 server.actor.request({
134 method : 'open-ils.actor.permissions.retrieve',
136 onerror : function (r) { status_update('Problem fetching perms') },
137 oncomplete : function (r) {
139 window._perm_list = r.recv().content();
141 window._perm_data = ppl.toStoreData( window._perm_list, 'code' );
142 window._perm_name_data = ppl.toStoreData( window._perm_list, 'code', { identifier : 'code' } );
144 window.perm_store = new dojo.data.ItemFileWriteStore({ data : window._perm_data });
145 window.perm_name_store = new dojo.data.ItemFileWriteStore({ data : window._perm_name_data });
151 server.pCRUD.request({
152 method : 'open-ils.permacrud.search.pgpm.atomic',
154 params : [ ses, { id : { "!=" : null } } ],
155 onerror : function (r) { status_update('Problem fetching perm maps') },
156 oncomplete : function (r) {
157 window._perm_map_list = r.recv().content();
158 window._perm_map_data = pgpm.toStoreData( window._perm_map_list, 'id' );
159 window.perm_map_store = new dojo.data.ItemFileWriteStore({ data : window._perm_map_data });
161 window.perm_map_store.onSet = function (item, attr, o, n) {
162 if (attr == 'ischanged') return;
165 this.setValue( item, 'ischanged', 1);
167 if (attr == 'grantable' && (typeof (n) != 'string'))
168 this.setValue(item, 'grantable', n ? 't' : 'f');
171 dojo.addOnUnload( function (event) { save_them_all(); });
179 label="Permission Groups"
180 query="{'_top':'true'}"
181 dojoType="dijit.Tree"
187 <script type="dojo/method" event="onClick" args="item,node">
189 right_pane_toggler.show();
191 current_group = item;
192 window.current_fm_group = new pgt().fromStoreItem(item);
194 perm_map_model.query = { grp : current_group ? current_group.id[0] : -1 };
195 perm_map_model.refresh();
198 highlighter.editor_pane.green.play();
199 status_update( 'Now editing ' + this.store.getValue( item, 'name' ) );
201 new_kid_button.disabled = false;
202 save_group_button.disabled = false;
203 delete_group_button.disabled = false;
205 var main_settings_fields = [ 'name', 'perm_interval', 'description'];
206 for ( var i in main_settings_fields ) {
207 var field = main_settings_fields[i];
208 var value = this.store.getValue( current_group, field );
211 window["editor_pane_" + field].setValue( '' ); // unset the value
212 if (field != 'description') window["editor_pane_" + field].setDisplayedValue( '' ); // unset the value
213 } else window["editor_pane_" + field].setValue( value );
216 if ( this.store.getValue( current_group, '_trueRoot' ) == 'true' ) {
217 editor_pane_parent.disabled = true;
218 editor_pane_parent.setValue(null);
219 editor_pane_parent.setDisplayedValue('');
220 editor_pane_parent.validate(false);
222 editor_pane_parent.disabled = false;
223 editor_pane_parent.validate(true);
224 editor_pane_parent.setValue( this.store.getValue( current_group, 'parent' ) );
227 editor_pane_application_perm.setValue( this.store.getValue( current_group, 'application_perm' ) );
229 editor_pane_usergroup.setChecked( this.store.getValue( current_group, 'usergroup' ) == 't' ? true : false );
233 <script type="dojo/method" event="getLabel" args="item,pI">
234 var label = this.store.getValue(item,'name');
235 if (this.store.getValue(item,'ischanged') == 1) label = '* ' + label;
242 <div id="right_pane" dojoType="dijit.layout.ContentPane" sizeShare="300">
243 <script type="dojo/method">
244 window.right_pane_toggler = new dojo.fx.Toggler({ node: 'right_pane'});
245 window.right_pane_toggler.hide();
248 <div dojoType="dijit.layout.TabContainer">
249 <div id="editor_pane" dojoType="dijit.layout.ContentPane" title="Group Configuration">
250 <script type="dojo/method">
251 highlighter.group_tree = {};
252 highlighter.editor_pane = {};
253 highlighter.group_tree.green = dojox.fx.highlight( { color : '#B4FFB4', node : 'group_tree', duration : 500 } );
254 highlighter.group_tree.red = dojox.fx.highlight( { color : '#FF2018', node : 'group_tree', duration : 500 } );
255 highlighter.editor_pane.green = dojox.fx.highlight( { color : '#B4FFB4', node : 'editor_pane', duration : 500 } );
256 highlighter.editor_pane.red = dojox.fx.highlight( { color : '#FF2018', node : 'editor_pane', duration : 500 } );
259 <table class="tundra" style="margin:10px;">
263 <span id="editor_pane_name" dojoType="dijit.form.ValidationTextBox" jsId="editor_pane_name" regExp=".+" required="true">
264 <script type="dojo/connect" event="onChange">
266 group_store.setValue( current_group, "name", this.getValue() );
270 <span dojoType="openils.widget.TranslatorPopup" targetObject="current_fm_group" field="name"></span>
278 id="editor_pane_description"
279 dojoType="dijit.form.Textarea"
280 jsId="editor_pane_description"
281 onChange="if (current_group) group_store.setValue( current_group, 'description', this.getValue() );"
284 <span dojoType="openils.widget.TranslatorPopup" targetObject="current_fm_group" field="description"></span>
288 <th>Permission Interval</th>
290 <span id="editor_pane_perm_interval" dojoType="dijit.form.ValidationTextBox" jsId="editor_pane_perm_interval" regExp="^\d+ (?:y.*|mo.*|d.*)$" required="true">
291 <script type="dojo/connect" event="onChange">
293 group_store.setValue( current_group, "perm_interval", this.getValue() );
300 <th>Editing Permission</th>
303 id="editor_pane_application_perm"
304 dojoType="dijit.form.FilteringSelect"
305 store="perm_name_store"
307 jsId="editor_pane_application_perm"
309 <script type="dojo/connect" event="onChange">
311 if (current_group && this.getValue()) {
312 group_store.setValue( current_group, "application_perm", this.getValue() );
320 <th>Parent Group</th>
323 id="editor_pane_parent"
324 dojoType="dijit.form.FilteringSelect"
325 jsId="editor_pane_parent"
331 <script type="dojo/connect" event="onChange">
333 if (current_group && this.getValue()) {
334 this.store.setValue( current_group, "parent", this.getValue() );
345 id="editor_pane_usergroup"
346 jsId="editor_pane_usergroup"
348 dojoType="dijit.form.CheckBox"
349 onChange='if (current_group) group_store.setValue( current_group, "usergroup", this.checked ? "t" : "f" );'
355 <div dojoType="dijit.layout.ContentPane" orientation="horizontal" style="margin-bottom: 20px;">
357 <button jsId="save_group_button" dojoType="dijit.form.Button" label="Save" onClick="save_group()">
358 <script type="dojo/connect" event="startup">
359 this.disabled = true;
363 <button jsId="delete_group_button" dojoType="dijit.form.Button" label="Delete">
364 <script type="dojo/connect" event="startup">
365 this.disabled = true;
367 <script type="dojo/connect" event="onClick">
370 if (group_store.getValue( current_group, '_trueRoot' ) == 'true') {
371 highlighter.editor_pane.red.play();
372 status_update( 'Cannot delete' + group_store.getValue( current_group, 'name' ) + ', you need at least one.' );
376 if ( current_group.children ) {
377 var kids = current_group.children;
378 if (!dojo.isArray(kids)) kids = [kids];
380 var existing_kids = dojo.filter(
382 function(kid){ return kid.isdeleted[0] != 1 }
384 if ( existing_kids.length > 0) {
385 highlighter.editor_pane.red.play();
386 status_update( 'Cannot delete' + group_store.getValue( current_group, 'name' ) + ', ' + existing_kids.length + ' subordinates still exist.' );
391 if ( confirm('Are you sure you want to delete ' + current_group.name + '?')) {
392 group_store.setValue( current_group, 'isdeleted', 1 );
394 var modified_pgt = new pgt().fromStoreItem( current_group );
395 modified_pgt.isdeleted( 1 );
397 server.pCRUD.request({
398 method : 'open-ils.permacrud.delete.pgt',
400 params : [ ses, modified_pgt ],
401 onerror : function (r) {
402 highlighter.editor_pane.red.play();
403 status_update( 'Problem deleting ' + group_store.getValue( current_group, 'name' ) );
405 oncomplete : function (r) {
407 if ( res && res.content() ) {
409 var old_name = group_store.getValue( current_group, 'name' );
412 query : { id : group_store.getValue( current_group, 'id' ) },
413 queryOptions : { deep : true },
414 onItem : function (item, req) { try { if (this.isItem( item )) this.deleteItem( item ); } catch (e) { /* meh */ } },
418 current_group = null;
420 new_kid_button.disabled = true;
421 save_group_button.disabled = true;
422 delete_group_button.disabled = true;
424 var main_settings_fields = [ 'name', 'perm_interval', 'description' ];
425 for ( var i in main_settings_fields ) {
426 var field = main_settings_fields[i];
427 window["editor_pane_" + field].setValue( '' ); // unset the value
428 window["editor_pane_" + field].setDisplayedValue( '' ); // unset the value
431 window["editor_pane_usergroup"].setChecked( false ); // unset the value
433 highlighter.editor_pane.green.play();
434 status_update( old_name + ' deleted' );
436 highlighter.editor_pane.red.play();
437 status_update( 'Problem deleting ' + old_name );
449 <button jsId="new_kid_button" dojoType="dijit.form.Button" label="New Child">
450 <script type="dojo/connect" event="startup">
451 this.disabled = true;
453 <script type="dojo/connect" event="onClick">
456 var new_fm_obj = new pgt().fromHash({
460 parent : group_store.getValue( current_group, 'id' )
464 server.pCRUD.request({
465 method : 'open-ils.permacrud.create.pgt',
467 params : [ ses, new_fm_obj ],
468 onerror : function (r) {
469 highlighter.editor_pane.red.play();
470 status_update( 'Problem calling method to create child Group' );
473 oncomplete : function (r) {
475 if ( res && res.content() ) {
477 res.content().toHash(),
478 { parent : current_group, attribute : 'children' }
481 highlighter.editor_pane.red.play();
482 status_update( 'Problem creating child Group' );
489 highlighter.editor_pane.green.play();
490 highlighter.group_tree.green.play();
491 status_update( 'New child Group created for ' + group_store.getValue( current_group, 'name' ) );
499 <div id="perm_pane" dojoType="dijit.layout.ContentPane" title="Group Permissions">
500 <script type="dojo/connect" event="onShow">
501 perm_map_model.query = { grp : current_group ? current_group.id[0] : -1 };
502 perm_map_model.refresh();
505 <div dojoType="dijit.layout.LayoutContainer" orientation="horizontal" style="width:100%; height:100%;">
506 <div id="grid_container" dojoType="dijit.layout.ContentPane" sizeShare="1" layoutAlign="left">
507 <div dojoType="dojox.grid.data.DojoData" id="perm_map_model" jsId="perm_map_model" store="perm_map_store"></div>
509 <div id="perm_grid" dojoType="dojox.Grid" model="perm_map_model" jsId="perm_grid">
510 <script type="dojo/connect" event="startup">
512 function get_item_part(model_field, item_search_field, item_part, model, store, datum, row) {
513 var formatter = true;
515 if (!row && row != '0') {
520 if(!model.getRow(row)) return null;
523 if(!formatter) { //this.editor && (this.editor.alwaysOn || (this.grid.edit.info.rowIndex==row && this.grid.edit.info.cell==this))) {
524 return model.getRow(row)[model_field];
528 q[item_search_field] = model.getRow(row)[model_field];
532 onItem : function (item) { value = store.getValue( item, item_part ) }
538 window.current_perm_grid_layout = [
543 formatter : dojo.partial(get_item_part, "perm", "id", "code", perm_map_model, perm_store),
548 formatter : dojo.partial(get_item_part, "depth", "depth", "name", perm_map_model, ou_type_store),
549 editor : dojox.grid.editors.select,
550 options : dojo.map( _ou_type_list, function (x) { return x.name() } ),
551 values : dojo.map( _ou_type_list, function (x) { return x.depth() } )
553 { name : "Grantable",
555 editor : dojox.grid.editors.bool,
556 get : function (row) {
557 var gr = get_item_part("id", "id", "grantable", perm_map_model, perm_map_model.store, row, row);
558 if (gr == 't' || gr === true) return true;
567 perm_grid.setStructure(window.current_perm_grid_layout);
573 <div id="new_perm_container" dojoType="dijit.layout.ContentPane" sizeShare="1" layoutAlign="client">
575 <div dojoType="dijit.form.DropDownButton" id="new_popup" jsId="new_popup">
576 <span>New Mapping</span>
577 <div dojoType="dijit.TooltipDialog">
578 <table class="tundra">
583 dojoType="dijit.form.FilteringSelect"
585 jsId="new_perm_select"
589 required="true"></div>
596 dojoType="dijit.form.FilteringSelect"
597 Id="new_depth_select"
598 jsId="new_depth_select"
599 store="ou_type_store"
602 required="true"></div>
610 dojoType="dijit.form.CheckBox"
611 Id="new_grant_checkbox"
612 jsId="new_grant_checkbox"
618 <button dojoType="dijit.form.Button" jsId="new_mapping_add" label="Add Mapping">
619 <script type="dojo/connect" event="onClick">
621 var new_perm = new_perm_select.getValue();
623 if (!new_perm) return;
625 var new_type_id = new_depth_select.getValue();
626 if (!new_type_id) return;
629 window.ou_type_store.fetch({
630 query : { id : new_type_id },
631 onItem : function (item, req) { try { new_type = item } catch (e) { /* meh */ } },
634 var new_depth = ou_type_store.getValue( new_type, 'depth')
635 var new_grant = new_grant_checkbox.getValue();
637 var new_fm_obj = new pgpm().fromHash({
641 grp : group_store.getValue( current_group, 'id' ),
642 grantable : new_grant ? 't' : 'f'
646 server.pCRUD.request({
647 method : 'open-ils.permacrud.create.pgpm',
649 params : [ ses, new_fm_obj ],
650 onerror : function (r) {
651 highlighter.group_tree.red.play();
652 status_update( 'Problem calling method to create new Permission Map' );
655 oncomplete : function (r) {
658 if ( res && res.content() ) {
659 var new_item_hash = res.content().toHash();
660 perm_map_store.newItem( new_item_hash );
661 status_update( 'New permission map created' );
662 highlighter.group_tree.green.play();
664 perm_map_model.query = { grp : current_group ? current_group.id[0] : -1 };
665 perm_grid.model.sort(-1);
666 perm_map_model.refresh();
670 highlighter.group_tree.red.play();
671 status_update( 'Problem creating new Permission Map' );
677 new_popup._closeDropDown();
685 <button jsId="save_pgpm_button" dojoType="dijit.form.Button" label="Save Changes" onClick="save_them_all()"></button><br/>
687 <button jsId="delete_pgpm_button" dojoType="dijit.form.Button" label="Remove Selected">
688 <script type="dojo/connect" event="onClick">
690 var selected_rows = perm_grid.selection.getSelected();
692 var selected_items = [];
693 for (var i in selected_rows) {
695 perm_grid.model.getRow( selected_rows[i] ).__dojo_data_item
699 perm_grid.selection.clear();
701 for (var i in selected_items) {
702 window.current_perm_map = selected_items[i];
704 perm_map_store.setValue( window.current_perm_map, 'isdeleted', 1 );
706 var modified_pgpm = new pgpm().fromStoreItem( window.current_perm_map );
707 modified_pgpm.isdeleted( 1 );
709 server.pCRUD.request({
710 method : 'open-ils.permacrud.delete.pgpm',
712 params : [ ses, modified_pgpm ],
713 onerror : function (r) {
714 highlighter.editor_pane.red.play();
715 status_update( 'Problem deleting permission mapping ' + perm_map_store.getValue( window.current_perm_map, 'id' ) );
717 oncomplete : function (r) {
719 if ( res && res.content() ) {
721 perm_map_store.fetch({
722 query : { id : perm_map_store.getValue( window.current_perm_map, 'id' ) },
723 onItem : function (item, req) { try { if (this.isItem( item )) this.deleteItem( item ); } catch (e) { /* meh */ } },
724 scope : perm_map_store
727 window.current_perm_map = null;
729 highlighter.editor_pane.green.play();
730 status_update( 'Permission mapping deleted' );
732 highlighter.editor_pane.red.play();
733 status_update( 'Problem deleting permission mapping ' + perm_map_store.getValue( window.current_perm_map, 'id' ));