custom org tree : admin ui 1
authorBill Erickson <berick@esilibrary.com>
Tue, 20 Mar 2012 19:16:09 +0000 (15:16 -0400)
committerBill Erickson <berick@esilibrary.com>
Wed, 21 Mar 2012 18:19:36 +0000 (14:19 -0400)
Signed-off-by: Bill Erickson <berick@esilibrary.com>
Open-ILS/src/templates/conify/global/actor/org_unit_custom_tree.tt2 [new file with mode: 0644]
Open-ILS/web/js/ui/default/conify/global/actor/org_unit_custom_tree.js [new file with mode: 0644]

diff --git a/Open-ILS/src/templates/conify/global/actor/org_unit_custom_tree.tt2 b/Open-ILS/src/templates/conify/global/actor/org_unit_custom_tree.tt2
new file mode 100644 (file)
index 0000000..c136700
--- /dev/null
@@ -0,0 +1,43 @@
+[% WRAPPER base.tt2 %]
+[% ctx.page_title = l('Org Unit Custom Tree') %]
+<script type="text/javascript" src='[% ctx.media_prefix %]/js/ui/default/conify/global/actor/org_unit_custom_tree.js'> </script>
+<link rel='stylesheet' type='text/css' href='[% ctx.media_prefix %]/js/dojo/dojo/resources/dnd.css'/>
+<link rel='stylesheet' type='text/css' href='[% ctx.media_prefix %]/js/dojo/dojo/resources/dndDefault.css'/>
+
+<style>
+    #wrapper     {width : 100%; height: 100%}
+    .block       {max-width : 45%; height: 100%; float : left; vertical-align : top; overflow: auto;}
+    #left-block  {border-right: 2px solid #333; margin-right: 20px; padding-right: 40px;}
+    .tree-actions {width : 95%; border-bottom: 1px solid #333; padding: 5px; margin: 5px;}
+</style>
+
+<h2>[% l('Org Unit Custom Tree') %]</h2>
+
+<!-- 'opac' is currently the only purpose -->
+<select jsId='treePurposeSelector' dojoType='dijit.form.FilteringSelect' disabled='disabled' onChange='drawMagicTree()'>
+    <option value='opac'>[% l('OPAC') %]</option>
+</select>
+
+<hr/>
+
+<div id='wrapper'>
+    <div id='left-block' class='block'>
+        <div class='tree-actions'>
+            <button dojoType='dijit.form.Button' onClick='realTree.expandAll()'>[% l('Expand All') %]</button>
+            <button dojoType='dijit.form.Button' onClick='realTree.collapseAll()'>[% l('Collapse All') %]</button>
+        </div>
+        <div id='real-tree'></div>
+    </div>
+    <div id='right-block' class='block'>
+        <div class='tree-actions'>
+            <button dojoType='dijit.form.Button' onClick='magicTree.expandAll()'>[% l('Expand All') %]</button>
+            <button dojoType='dijit.form.Button' onClick='magicTree.collapseAll()'>[% l('Collapse All') %]</button>
+            <button dojoType='dijit.form.Button' onClick='applyChanges()'>[% l('Apply Changes') %]</button>
+        </div>
+        <div id='magic-tree'></div>
+    </div>
+</div>
+
+[% END %]
+
+
diff --git a/Open-ILS/web/js/ui/default/conify/global/actor/org_unit_custom_tree.js b/Open-ILS/web/js/ui/default/conify/global/actor/org_unit_custom_tree.js
new file mode 100644 (file)
index 0000000..514f07a
--- /dev/null
@@ -0,0 +1,153 @@
+dojo.require('dijit.form.Button');
+dojo.require('dijit.form.FilteringSelect');
+dojo.require('dojo.data.ItemFileReadStore');
+dojo.require('dojo.data.ItemFileWriteStore');
+dojo.require('dijit.Tree');
+dojo.require('dijit.tree.TreeStoreModel');
+dojo.require("dijit._tree.dndSource");
+dojo.require('fieldmapper.Fieldmapper');
+dojo.require('fieldmapper.OrgUtils');
+dojo.require('openils.User');
+dojo.require('openils.Util');
+dojo.require('openils.PermaCrud');
+
+var realTree;
+var magicTree;
+var pcrud;
+var virtId = -1;
+
+dojo.declare(
+    'openils.actor.OrgUnitCustomTreeSource', dijit._tree.dndSource, {
+    itemCreator : function(nodes, etc) {
+        var items = this.inherited(arguments);
+        dojo.forEach(items, function(item) {item.shortname = item.name});
+        return items;
+    }
+});
+
+dojo.declare(
+    'openils.actor.OrgUnitCustomTreeStoreModel', dijit.tree.TreeStoreModel, {
+    mayHaveChildren : function(item) { return true },
+});
+
+function drawPage() {
+    pcrud = new openils.PermaCrud({authtoken : openils.User.authtoken});
+
+    // real org unit list
+    var orgList = openils.Util.objectValues(
+        fieldmapper.aou.OrgCache).map(function(obj) { return obj.org });
+
+    var store = new dojo.data.ItemFileReadStore(
+        {data : fieldmapper.aou.toStoreData(orgList)});
+            
+    var model = new dijit.tree.TreeStoreModel({
+        store: store,
+        query: {_top : 'true'}
+    });
+
+    realTree = new dijit.Tree(
+        {   model: model,
+            expandAll: function() {treeDoAll(this)},
+            collapseAll: function() {treeDoAll(this, true)},
+            dndController : dijit._tree.dndSource,
+            persist : false,
+        }, 
+        'real-tree'
+    );
+
+    realTree.expandAll();
+    drawMagicTree();
+}
+
+
+/**
+ * The magicTree is composed of aouctn items and uses the 
+ * linked org unit shortname as the tree item label
+ */
+function drawMagicTree() {
+
+    var orgList = [];
+    var query = {};
+
+    var mTree = pcrud.search('aouct', 
+        {active : 't', purpose : treePurposeSelector.attr('value')});
+    
+    if (mTree.length) {
+        nodes = pcrud.search('aouctn', {tree : mTree[0].id()});
+
+        // create an org tree from the custom tree nodes
+        dojo.forEach(nodes, 
+            function(node) {
+                var org = JSON2js(js2JSON( // deep clone
+                    fieldmapper.aou.findOrgUnit(node.org_unit())
+                ));
+                org.parent_ou(null);
+                org.children([]);
+                if (node.parent_node()) {
+                    org.parent_ou(
+                        nodes.filter(
+                            function(n) {return n.id() == node.parent_node()}
+                        )[0].org_unit()
+                    );
+                }
+                orgList.push(org);
+            }
+        );
+        var root = nodes.filter(function(n) {return n.parent_node() == null})[0];
+        query = {id : root.org_unit()+''}
+    }
+
+    var store = new dojo.data.ItemFileWriteStore(
+        {data : fieldmapper.aou.toStoreData(orgList)});
+
+    var model = new openils.actor.OrgUnitCustomTreeStoreModel({
+        store : store,
+        query : query
+    });
+
+    magicTree = new dijit.Tree(
+        {   model: model,
+            expandAll: function() {treeDoAll(this)},
+            collapseAll: function() {treeDoAll(this, true)},
+            dndController : openils.actor.OrgUnitCustomTreeSource,
+            dragThreshold : 8,
+            betweenThreshold : 5,
+            persist : false,
+        }, 
+        'magic-tree'
+    );
+
+    magicTree.expandAll();
+}
+
+function applyChanges() {
+    var list = [];
+    function traverse(pnode, node) {
+        var item = node.item;
+        list.push({
+            name : item.name,
+            org_id : item.id,
+            parent_node : pnode ? pnode.item.id : null
+        });
+        dojo.forEach(node.getChildren(), function(child) {traverse(node, child)});
+    }
+    traverse(null, magicTree.rootNode);
+    console.log(js2JSON(list));
+}
+
+
+// modified from 
+// http://stackoverflow.com/questions/2161032/expanding-all-nodes-in-dijit-tree
+function treeDoAll(tree, collapse) {
+    function expand(node) {
+        if (collapse) tree._collapseNode(node);
+        else tree._expandNode(node);
+        var childBranches = dojo.filter(node.getChildren() || [], 
+            function(node) { return node.isExpandable });
+        var def = new dojo.Deferred();
+        defs = dojo.map(childBranches, expand);
+    }
+    return expand(tree.rootNode);
+}
+
+openils.Util.addOnLoad(drawPage);