]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/web/js/ui/default/conify/global/actor/org_unit_custom_tree.js
Custom Org Tree : Admin UI honors "activate" on new trees
[working/Evergreen.git] / Open-ILS / web / js / ui / default / conify / global / actor / org_unit_custom_tree.js
1 dojo.require('dijit.form.Button');
2 dojo.require('dijit.form.FilteringSelect');
3 dojo.require('dojo.data.ItemFileReadStore');
4 dojo.require('dojo.data.ItemFileWriteStore');
5 dojo.require('dijit.Tree');
6 dojo.require('dijit.tree.TreeStoreModel');
7 dojo.require("dijit._tree.dndSource");
8 dojo.require('fieldmapper.Fieldmapper');
9 dojo.require('fieldmapper.OrgUtils');
10 dojo.require('openils.User');
11 dojo.require('openils.Util');
12 dojo.require('openils.PermaCrud');
13 dojo.require('openils.widget.ProgressDialog');
14
15 var realTree; // dijit.Tree
16 var magicTree; // dijit.Tree
17 var mTree; // aouct object
18 var pcrud;
19 var virtId = -1;
20 var realOrgList = [];
21 var ctNodes = [];
22
23 dojo.declare(
24     'openils.actor.OrgUnitCustomTreeSource', dijit._tree.dndSource, {
25     itemCreator : function(nodes, etc) {
26         var items = this.inherited(arguments);
27         dojo.forEach(items, function(item) {item.shortname = item.name});
28         return items;
29     }
30 });
31
32 dojo.declare(
33     'openils.actor.OrgUnitCustomTreeStoreModel', dijit.tree.TreeStoreModel, {
34     mayHaveChildren : function(item) { return true },
35 });
36
37 function drawPage() {
38     pcrud = new openils.PermaCrud({authtoken : openils.User.authtoken});
39
40     // real org unit list.  Not write-able.  Used only as a source.
41     realOrgList = openils.Util.objectValues(
42         fieldmapper.aou.OrgCache).map(function(obj) { return obj.org });
43
44     var store = new dojo.data.ItemFileReadStore(
45         {data : fieldmapper.aou.toStoreData(realOrgList)});
46             
47     var model = new dijit.tree.TreeStoreModel({
48         store: store,
49         query: {_top : 'true'}
50     });
51
52     realTree = new dijit.Tree(
53         {   model: model,
54             expandAll: function() {treeDoAll(this)},
55             collapseAll: function() {treeDoAll(this, true)},
56             dndController : dijit._tree.dndSource,
57             persist : false,
58         }, 
59         'real-tree'
60     );
61
62     realTree.expandAll();
63     drawMagicTree();
64 }
65
66
67 // composed of org units.  Write-able.
68 function drawMagicTree() {
69     var orgList = realOrgList;
70     var query = {_top : 'true'};
71
72     var mTreeRes = pcrud.search('aouct', 
73         {purpose : treePurposeSelector.attr('value')});
74
75     if (mTreeRes.length) {
76         mTree = mTreeRes[0];
77         if (openils.Util.isTrue(mTree.active())) {
78             openils.Util.hide(dojo.byId('activate-tree'));
79             openils.Util.show(dojo.byId('deactivate-tree'), 'inline');
80         }
81         ctNodes = pcrud.search('aouctn', {tree : mTree.id()});
82         if (ctNodes.length) {
83             orgList = [];
84             // create an org tree from the custom tree nodes
85            
86             dojo.forEach(ctNodes, 
87                 function(node) {
88                     // deep clone to avoid globalOrgTree clobbering
89                     var org = JSON2js(js2JSON( 
90                         fieldmapper.aou.findOrgUnit(node.org_unit())
91                     ));
92                     org.parent_ou(null);
93                     org.children([]);
94                     if (node.parent_node()) {
95                         org.parent_ou(
96                             ctNodes.filter(
97                                 function(n) {return n.id() == node.parent_node()}
98                             )[0].org_unit()
99                         );
100                     }
101                     orgList.push(org);
102                 }
103             );
104             var root = ctNodes.filter(function(n) {return n.parent_node() == null})[0];
105             query = {id : root.org_unit()+''}
106         }
107     } else {
108
109         mTree = new fieldmapper.aouct();
110         mTree.isnew(true);
111         mTree.purpose(treePurposeSelector.attr('value'));
112         mTree.active(false);
113     }
114
115     var store = new dojo.data.ItemFileWriteStore(
116         {data : fieldmapper.aou.toStoreData(orgList)});
117
118     var model = new openils.actor.OrgUnitCustomTreeStoreModel({
119         store : store,
120         query : query
121     });
122
123     magicTree = new dijit.Tree(
124         {   model: model,
125             expandAll: function() {treeDoAll(this)},
126             collapseAll: function() {treeDoAll(this, true)},
127             dndController : openils.actor.OrgUnitCustomTreeSource,
128             dragThreshold : 8,
129             betweenThreshold : 5,
130             persist : false,
131         }, 
132         'magic-tree'
133     );
134
135     magicTree.expandAll();
136 }
137
138 // 1. create the tree if necessary
139 // 2. translate the dijit.tree nodes into aouctn's
140 // 3. delete the existing aouctn's
141 // 4. create the new aouctn's
142 function applyChanges() {
143     progressDialog.show();
144
145     if (mTree.isnew()) {
146
147         pcrud.create(mTree, {
148             oncomplete : function(r, objs) {
149                 mTree = objs[0];
150                 applyChanges2();
151             }
152         });
153     
154     } else {
155         if (ctNodes.length) { 
156             console.log('Deleting ' + ctNodes.length + ' nodes');
157             pcrud.eliminate(ctNodes, {oncomplete : applyChanges2});
158         } else {
159             applyChanges2();
160         }
161     }
162 }
163
164 function applyChanges2() {
165     ctNodes = [];
166     var newCtNodes = [];
167     var nodeList = [];
168     var sorder = 0;
169     var prevTn;
170     var progress = 0;
171
172     function flatten(node) {
173         nodeList.push(node);
174         dojo.forEach(node.getChildren(), flatten);
175     }
176     flatten(magicTree.rootNode);
177
178     // traverse the nodes, creating new aoucnt's as we go
179     function traverseAndCreate(node) {
180         var item = node.item;
181
182         var tn = new fieldmapper.aouctn();
183         tn.tree(mTree.id());
184         tn.org_unit(item.id[0])
185
186         var pnode = node.getParent();
187         if (pnode) {
188             // find the newly created parent node and extract the ID 
189             var ptn = ctNodes.filter(function(n) {
190                 return n.org_unit() == pnode.item.id[0]})[0];
191             tn.parent_node(ptn.id());
192         }
193
194         // if the last node was our previous sibling
195         if (prevTn && prevTn.parent_node() == tn.parent_node()) {
196             tn.sibling_order(++sorder);
197         } else { sorder = 0; }
198
199         console.log("Creating new node for org unit " + tn.org_unit());
200
201         // create the new node, then process the children
202         pcrud.create(tn, {
203             oncomplete : function(r, objs) {
204                 var newTn = objs[0];
205                 ctNodes.push(newTn);
206                 prevTn = newTn;
207                 if (nodeList.length == 0) {
208                     progressDialog.hide();
209                     location.href = location.href;
210                 } else {
211                     progressDialog.update({maximum : nodeList.length, progress : ++progress});
212                     traverseAndCreate(nodeList.shift());
213                 }
214             }
215         });
216     }
217     traverseAndCreate(nodeList.shift());
218 }
219
220 function deleteSelected() {
221     var toDelete = [];
222
223     function collectChildren(item) {
224         toDelete.push(item);
225         magicTree.model.store.fetch({
226             query : {parent_ou : item.id[0]+''},
227             onComplete : function(list) { 
228                 dojo.forEach(list, collectChildren) 
229             }
230         });
231     }
232
233     magicTree.dndController.getSelectedItems().forEach(
234         function(item) {
235             if (item === magicTree.model.root) return
236             collectChildren(item);
237             // delete node plus children, starting at the leaf nodes
238             dojo.forEach(toDelete.reverse(),
239                 function(i) {
240                     console.log('Deleting item ' + i.id);
241                     magicTree.model.store.deleteItem(i)
242                 }
243             );
244         }
245     );
246 }
247
248 function activateTree() {
249     mTree.active('t');
250
251     if (mTree.isnew()) {
252         // before the tree exists, we can only activate the local copy
253         // the next save event will activate it
254         openils.Util.hide(dojo.byId('activate-tree'));
255         openils.Util.show(dojo.byId('deactivate-tree'), 'inline');
256         return;
257     }
258
259     pcrud.update(mTree, {
260         oncomplete : function() {
261             openils.Util.hide(dojo.byId('activate-tree'));
262             openils.Util.show(dojo.byId('deactivate-tree'), 'inline');
263         }
264     });
265 }
266
267 function deactivateTree() {
268     mTree.active('f');
269
270     if (mTree.isnew()) {
271         openils.Util.hide(dojo.byId('deactivate-tree'));
272         openils.Util.show(dojo.byId('activate-tree'), 'inline');
273         return;
274     }
275
276     pcrud.update(mTree, {
277         oncomplete : function() {
278             openils.Util.hide(dojo.byId('deactivate-tree'));
279             openils.Util.show(dojo.byId('activate-tree'), 'inline');
280         }
281     });
282 }
283
284 // modified from 
285 // http://stackoverflow.com/questions/2161032/expanding-all-nodes-in-dijit-tree
286 function treeDoAll(tree, collapse) {
287     function expand(node) {
288         if (collapse) tree._collapseNode(node);
289         else tree._expandNode(node);
290         var childBranches = dojo.filter(node.getChildren() || [], 
291             function(node) { return node.isExpandable });
292         var def = new dojo.Deferred();
293         defs = dojo.map(childBranches, expand);
294     }
295     return expand(tree.rootNode);
296 }
297
298 openils.Util.addOnLoad(drawPage);