[open-ils-commits] r17459 - in branches/rel_2_0/Open-ILS: src/perlmods/OpenILS/Application/Acq web/images web/js/dojo/openils/conify/nls web/js/ui/default/conify/global/acq web/templates/default/conify/global/acq (erickson)

svn at svn.open-ils.org svn at svn.open-ils.org
Thu Sep 2 17:10:10 EDT 2010


Author: erickson
Date: 2010-09-02 17:10:04 -0400 (Thu, 02 Sep 2010)
New Revision: 17459

Added:
   branches/rel_2_0/Open-ILS/web/images/dimple.png
   branches/rel_2_0/Open-ILS/web/images/licenses.txt
Modified:
   branches/rel_2_0/Open-ILS/src/perlmods/OpenILS/Application/Acq/Order.pm
   branches/rel_2_0/Open-ILS/web/js/dojo/openils/conify/nls/conify.js
   branches/rel_2_0/Open-ILS/web/js/ui/default/conify/global/acq/distribution_formula.js
   branches/rel_2_0/Open-ILS/web/templates/default/conify/global/acq/distribution_formula.tt2
Log:
back-porting: 17399 17413 => optimized distrib formula management UI

Modified: branches/rel_2_0/Open-ILS/src/perlmods/OpenILS/Application/Acq/Order.pm
===================================================================
--- branches/rel_2_0/Open-ILS/src/perlmods/OpenILS/Application/Acq/Order.pm	2010-09-02 21:08:33 UTC (rev 17458)
+++ branches/rel_2_0/Open-ILS/src/perlmods/OpenILS/Application/Acq/Order.pm	2010-09-02 21:10:04 UTC (rev 17459)
@@ -3124,4 +3124,48 @@
 }
 
 
+__PACKAGE__->register_method(
+	method => "clone_distrib_form",
+	api_name => "open-ils.acq.distribution_formula.clone",
+    stream => 1,
+	signature => {
+        desc => q/Clone a distribution formula/,
+        params => [
+            {desc => "Authentication token", type => "string"},
+            {desc => "Original formula ID", type => 'integer'},
+            {desc => "Name of new formula", type => 'string'},
+        ],
+        return => {desc => "ID of newly created formula"}
+    }
+);
+
+sub clone_distrib_form {
+    my($self, $client, $auth, $form_id, $new_name) = @_;
+
+    my $e = new_editor("xact"=> 1, "authtoken" => $auth);
+    return $e->die_event unless $e->checkauth;
+
+    my $old_form = $e->retrieve_acq_distribution_formula($form_id) or return $e->die_event;
+    return $e->die_event unless $e->allowed('ADMIN_ACQ_DISTRIB_FORMULA', $old_form->owner);
+
+    my $new_form = Fieldmapper::acq::distribution_formula->new;
+
+    $new_form->owner($old_form->owner);
+    $new_form->name($new_name);
+    $e->create_acq_distribution_formula($new_form) or return $e->die_event;
+
+    my $entries = $e->search_acq_distribution_formula_entry({formula => $form_id});
+    for my $entry (@$entries) {
+       my $new_entry = Fieldmapper::acq::distribution_formula_entry->new;
+       $new_entry->$_($entry->$_()) for $entry->real_fields;
+       $new_entry->formula($new_form->id);
+       $new_entry->clear_id;
+       $e->create_acq_distribution_formula_entry($new_entry) or return $e->die_event;
+    }
+
+    $e->commit;
+    return $new_form->id;
+}
+
 1;
+

Copied: branches/rel_2_0/Open-ILS/web/images/dimple.png (from rev 17413, trunk/Open-ILS/web/images/dimple.png)
===================================================================
--- branches/rel_2_0/Open-ILS/web/images/dimple.png	                        (rev 0)
+++ branches/rel_2_0/Open-ILS/web/images/dimple.png	2010-09-02 21:10:04 UTC (rev 17459)
@@ -0,0 +1,5 @@
+‰PNG
+
+   
+IHDR         b­MÛ   tEXtSoftware Adobe ImageReadyqÉe<   =IDAT×c```° â:(¶`N2Ü@Ìvqqñ rÔ@ÌÞ¶m[PCCƒ%ƒØÿÿÿ×â(Ö …5
+Bmª    IEND®B`‚
\ No newline at end of file

Copied: branches/rel_2_0/Open-ILS/web/images/licenses.txt (from rev 17413, trunk/Open-ILS/web/images/licenses.txt)
===================================================================
--- branches/rel_2_0/Open-ILS/web/images/licenses.txt	                        (rev 0)
+++ branches/rel_2_0/Open-ILS/web/images/licenses.txt	2010-09-02 21:10:04 UTC (rev 17459)
@@ -0,0 +1,3 @@
+dimple.png derived from:
+http://mxr.mozilla.org/mozilla-central/source/toolkit/themes/pinstripe/global/splitter/dimple.png
+Mozilla Public License/GPL/GLPL

Modified: branches/rel_2_0/Open-ILS/web/js/dojo/openils/conify/nls/conify.js
===================================================================
--- branches/rel_2_0/Open-ILS/web/js/dojo/openils/conify/nls/conify.js	2010-09-02 21:08:33 UTC (rev 17458)
+++ branches/rel_2_0/Open-ILS/web/js/dojo/openils/conify/nls/conify.js	2010-09-02 21:10:04 UTC (rev 17459)
@@ -85,6 +85,8 @@
     "SURVEY_QUESTION": "Question:",
     "SURVEY_ID": "Survey ID # ${0}",
     "SURVEY_FOOT_LABEL": "Questions & Answers",
-    "EVENT_DEF_LABEL" : "${0}: ${1}"
+    "EVENT_DEF_LABEL" : "${0}: ${1}",
+    "ACQ_DISTRIB_FORMULA_NAME_PROMPT" : "Enter new formula name",
+    "ACQ_DISTRIB_FORMULA_NAME_CLONE" : "${0} (Clone)"
 }
 

Modified: branches/rel_2_0/Open-ILS/web/js/ui/default/conify/global/acq/distribution_formula.js
===================================================================
--- branches/rel_2_0/Open-ILS/web/js/ui/default/conify/global/acq/distribution_formula.js	2010-09-02 21:08:33 UTC (rev 17458)
+++ branches/rel_2_0/Open-ILS/web/js/ui/default/conify/global/acq/distribution_formula.js	2010-09-02 21:10:04 UTC (rev 17459)
@@ -1,11 +1,23 @@
+dojo.require("dojo.dnd.Container");
+dojo.require("dojo.dnd.Source");
 dojo.require('openils.widget.AutoGrid');
 dojo.require('dijit.form.FilteringSelect');
 dojo.require('openils.PermaCrud');
-var formula;
+dojo.require('openils.widget.AutoFieldWidget');
+dojo.requireLocalization('openils.conify', 'conify');
+var localeStrings = dojo.i18n.getLocalization('openils.conify', 'conify');
+
+
 var formCache = [];
+var formula, entryTbody, entryTemplate, dndSource;
+var virtualId = -1;
+var pcrud;
 
+
 function draw() {
 
+    pcrud = new openils.PermaCrud();
+
     if(formulaId) {
         openils.Util.hide('formula-list-div');
         drawFormulaSummary();
@@ -33,18 +45,31 @@
 
     }
 }
-openils.Util.addOnLoad(draw);
 
-function drawFormulaSummary() {
-    openils.Util.show('formula-entry-div');
-    dfeListGrid.overrideEditWidgets.formula = new
-        dijit.form.TextBox({style:'display:none', value: formulaId});
-    dfeListGrid.loadAll({order_by:{acqdfe : 'formula'}}, {formula : formulaId});
-    var pcrud = new openils.PermaCrud();
-    var formulaName = pcrud.retrieve('acqdf', formulaId);
-    dojo.byId('formula_head').innerHTML = formulaName.name();
+function cloneSelectedFormula() {
+    var item = fListGrid.getSelectedItems()[0];
+    if(!item) return;
+    var formula = new fieldmapper.acqf().fromStoreItem(item);
+    fieldmapper.standardRequest(
+        ['open-ils.acq', 'open-ils.acq.distribution_formula.clone'],
+        {
+            asnyc : true,
+            params : [
+                openils.User.authtoken, 
+                formula.id(), 
+                dojo.string.substitute(localeStrings.ACQ_DISTRIB_FORMULA_NAME_CLONE, [formula.name()])
+            ],
+            oncomplete : function(r) {
+                if(r = openils.Util.readResponse(r)) {
+                    location.href = oilsBasePath + '/conify/global/acq/distribution_formula/' + r;
+                }
+            }
+        }
+    );
 }
 
+openils.Util.addOnLoad(draw);
+
 function getItemCount(rowIndex, item) {
     if(!item) return '';
     var form = formCache[this.grid.store.getValue(item, "id")];
@@ -54,3 +79,156 @@
     return count;
 }
 
+function byName(node, name) {
+    return dojo.query('[name='+name+']', node)[0];
+}
+
+function drawFormulaSummary() {
+    openils.Util.show('formula-entry-div');
+
+    var entries = pcrud.search('acqdfe', {formula: formulaId}, {order_by:{acqdfe : 'position'}});
+    formula = pcrud.retrieve('acqdf', formulaId);
+    formula.entries(entries);
+
+    dojo.byId('formula_head').innerHTML = formula.name();
+    dojo.byId('formula_head').onclick = function() {
+        var name = prompt(localeStrings.ACQ_DISTRIB_FORMULA_NAME_PROMPT, formula.name());
+        if(name && name != formula.name()) {
+            formula.name(name);
+            pcrud = new openils.PermaCrud();
+            pcrud.update(formula);
+            dojo.byId('formula_head').innerHTML = name;
+        }
+    }
+
+    dojo.forEach(entries, function(entry) { addEntry(entry); } );
+}
+
+function addEntry(entry) {
+
+    if(!entryTbody) {
+        entryTbody = dojo.byId('formula-entry-tbody');
+        entryTemplate = entryTbody.removeChild(dojo.byId('formula-entry-tempate'));
+        dndSource = new dojo.dnd.Source(entryTbody);
+        dndSource.selectAll(); 
+        dndSource.deleteSelectedNodes();
+        dndSource.clearItems();
+    }
+
+    if(!entry) {
+        entry = new fieldmapper.acqdfe();
+        entry.formula(formulaId);
+        entry.item_count(1);
+        entry.owning_lib(openils.User.user.ws_ou());
+        entry.id(virtualId--);
+        entry.isnew(true);
+        formula.entries().push(entry);
+    }
+
+    var row = entryTbody.appendChild(entryTemplate.cloneNode(true));
+    row.setAttribute('entry', entry.id());
+    dndSource.insertNodes(false, [row]);
+    byName(row, 'delete').onclick = function() {
+        entry.isdeleted(true);
+        entryTbody.removeChild(row);
+        dndSource.sync();
+    };
+
+    dojo.forEach(
+        ['owning_lib', 'location', 'item_count'],
+        function(field) {
+            new openils.widget.AutoFieldWidget({
+                forceSync : true,
+                fmField : field, 
+                fmObject : entry,
+                fmClass : 'acqdfe',
+                parentNode : byName(row, field),
+                orgDefaultsToWs : true,
+                orgLimitPerms : ['ADMIN_ACQ_DISTRIB_FORMULA'],
+                widgetClass : (field == 'item_count') ? 'dijit.form.NumberSpinner' : null,
+                dijitArgs : (field == 'item_count') ? {min:1, places:0} : null
+            }).build(
+                function(w, ww) {
+                    dojo.connect(w, 'onChange', 
+                        function(newVal) {
+                            entry[field]( newVal );
+                            entry.ischanged(true);
+                        }
+                    )
+                }
+            );
+        }
+    );
+}
+
+function saveFormula() {
+    var pos = 1;
+    var updatedEntries = [];
+    var deletedEntries = [];
+
+    // remove deleted entries from consideration for collision protection
+    for(var i = 0; i < formula.entries().length; i++) {
+        if(formula.entries()[i].isdeleted())
+            deletedEntries.push(formula.entries().splice(i--, 1)[0])
+    }
+
+    // update entry positions and create temporary collision avoidance entries
+    dojo.forEach(
+        dndSource.getAllNodes(),
+        function(node) {
+
+            var entryId = node.getAttribute('entry');
+            var entry = formula.entries().filter(function(e) {return (e.id() == entryId)})[0];
+
+            if(entry.position() != pos) {
+
+                // update the position
+                var changedEntry = entry.clone();
+                changedEntry.position(pos);
+                changedEntry.ischanged(true);
+                updatedEntries.push(changedEntry);
+
+                // clear the virtual ID
+                if(changedEntry.isnew())
+                    changedEntry.id(null); 
+
+                var oldEntry = formula.entries().filter(function(e) {return (e.position() == pos)})[0];
+
+                if(oldEntry) {
+                    // move the entry currently in that spot temporarily into negative territory
+                    var moveMe = oldEntry.clone();
+                    moveMe.ischanged(true);
+                    moveMe.position(moveMe.position() * -1); 
+                    updatedEntries.unshift(moveMe);
+                }
+            }
+            pos++;
+        }
+    );
+
+    // finally, for every entry that changed w/o changing position
+    // throw it on the list for update
+    dojo.forEach(
+        formula.entries(),
+        function(entry) {
+            if(entry.ischanged() && !entry.isdeleted() && !entry.isnew()) {
+                if(updatedEntries.filter(function(e) { return (e.id() == entry.id()) }).length == 0)
+                    updatedEntries.push(entry);
+            }
+        }
+    );
+
+    updatedEntries = deletedEntries.concat(updatedEntries);
+    if(updatedEntries.length) {
+        pcrud = new openils.PermaCrud();
+        try { 
+            pcrud.apply(updatedEntries);
+        } catch(E) {
+            alert('error updating: ' + E);
+            return;
+        }
+        location.href = location.href;
+    }
+}
+
+

Modified: branches/rel_2_0/Open-ILS/web/templates/default/conify/global/acq/distribution_formula.tt2
===================================================================
--- branches/rel_2_0/Open-ILS/web/templates/default/conify/global/acq/distribution_formula.tt2	2010-09-02 21:08:33 UTC (rev 17458)
+++ branches/rel_2_0/Open-ILS/web/templates/default/conify/global/acq/distribution_formula.tt2	2010-09-02 21:10:04 UTC (rev 17459)
@@ -1,22 +1,23 @@
 [% WRAPPER default/base.tt2 %]
 [% ctx.page_title = 'Distribution Formulas' %]
 <script type="text/javascript" src='[% ctx.media_prefix %]/js/ui/default/conify/global/acq/distribution_formula.js'></script>
-<script type="text/javascript"> var formulaId = '[% ctx.page_args.0 %]';
 
-function getFormulaName(rowIndex, item) {
-    if(!item) return '';
-    var name = this.grid.store.getValue(item, 'name');
-    var id = this.grid.store.getValue(item, 'id');
-    return id + ':' + name;
-}
+<script type="text/javascript"> 
+    var formulaId = '[% ctx.page_args.0 %]';
 
-function formatName(value) {
-    if(value) {
-        var vals = value.split(/:/);
-        return '<a href="'+location.href+ '/'+vals[0]+'">'+vals[1]+'</a>';
+    function getFormulaName(rowIndex, item) {
+        if(!item) return '';
+        var name = this.grid.store.getValue(item, 'name');
+        var id = this.grid.store.getValue(item, 'id');
+        return id + ':' + name;
     }
-}
 
+    function formatName(value) {
+        if(value) {
+            var vals = value.split(/:/);
+            return '<a href="'+location.href+ '/'+vals[0]+'">'+vals[1]+'</a>';
+        }
+    }
 </script>
 
 
@@ -27,6 +28,7 @@
             <div>
                 <button dojoType='dijit.form.Button' onClick='fListGrid.showCreateDialog()'>New Formula</button>
                 <button dojoType='dijit.form.Button' onClick='fListGrid.deleteSelected()'>Delete Selected</button>
+                <button dojoType='dijit.form.Button' onClick='cloneSelectedFormula()'>Clone Selected</button>
             </div>
         </div>
         <table  jsId="fListGrid"
@@ -49,34 +51,49 @@
 
 
 <div id='formula-entry-div'>
-    <div dojoType="dijit.layout.ContentPane" layoutAlign="client">
-        <div id='formula-summary-pane'/>
-    </div>
-        <div dojoType="dijit.layout.ContentPane" layoutAlign="client" class='oils-header-panel'>
-            <div id="formula_head"></div>
-            <div>
-                <button dojoType='dijit.form.Button' onClick='dfeListGrid.showCreateDialog()'>New Formula Entry</button>
-                <button dojoType='dijit.form.Button' onClick='dfeListGrid.deleteSelected()'>Delete Selected</button>
-            </div>
+    <div dojoType="dijit.layout.ContentPane" layoutAlign="client" class='oils-header-panel'>
+        <div><a href='javascript:void(0);' id="formula_head"></a></div>
+        <div>
         </div>
-        <div dojoType="dijit.layout.ContentPane" layoutAlign="client">
-            <table  jsId="dfeListGrid"
-                    autoHeight='true'
-                    dojoType="openils.widget.AutoGrid"
-                    fieldOrder="['id','formula', 'owning_lib', 'location', 'item_count', 'position']"
-                    suppressFields="['formula']"
-                    query="{id: '*'}"
-                    defaultCellWidth='12'
-                    fmClass='acqdfe'
-                    editOnEnter='true'>
-                <thead>
-                    <tr>
-                        <th field='formula' get='getFormulaId' formatter='formatName'/>
-                    </tr>
-                </thead>
-            </table>
-        </div>
     </div>
+    <br/>
+    <div>
+        <button dojoType='dijit.form.Button' onClick='addEntry()'>New Entry</button>
+        <span style='padding-right:20px;'></span>
+        <button dojoType='dijit.form.Button' onClick='saveFormula()'>Apply Changes</button>
+    </div>
+    <br/>
+    <table class='oils-generic-table'>
+        <thead>
+            <tr>
+                <th></th>
+                <th>Owning Library</th>
+                <th>Shelving Location</th>
+                <th>Item Count</th>
+                <th></th>
+            </tr>
+        </thead>
+        <tbody id='formula-entry-tbody'>
+            <tr id='formula-entry-tempate'>
+                <td><div name='delete' dojoType='dijit.form.Button' style='color:red;' scrollOnFocus='false'>X</div></td>
+                <td><div name='owning_lib'></td>
+                <td><div name='location'></td>
+                <td><div name='item_count'></td>
+                <td>
+                    <img src='[% ctx.media_prefix %]/images/dimple.png'/>
+                    <img src='[% ctx.media_prefix %]/images/dimple.png'/>
+                    <img src='[% ctx.media_prefix %]/images/dimple.png'/>
+                <td>
+            </tr>
+        </tbody>
+    </table>
+    <br/>
+    <div>
+        <button dojoType='dijit.form.Button' onClick='addEntry()'>New Entry</button>
+        <span style='padding-right:20px;'></span>
+        <button dojoType='dijit.form.Button' onClick='saveFormula()'>Apply Changes</button>
+    </div>
 </div>
+
 [% END %]
 



More information about the open-ils-commits mailing list