ACQ PO inline details view
authorBill Erickson <berick@esilibrary.com>
Wed, 16 Jan 2013 22:13:50 +0000 (17:13 -0500)
committerLebbeous Fogle-Weekley <lebbeous@esilibrary.com>
Wed, 13 Mar 2013 19:24:53 +0000 (15:24 -0400)
Adds a new 'expand' lineitem option which produces a table inline below
the lineitem title, author, etc. containing copy information.  Each copy
linked to the lineitem is represented as a row in the table with owning
lib, copy location, fund, barcode, callnumber, and notes.  An option to
expand/collapse all is also present.

Release notes included.

Signed-off-by: Bill Erickson <berick@esilibrary.com>
Signed-off-by: Lebbeous Fogle-Weekley <lebbeous@esilibrary.com>
Open-ILS/src/templates/acq/common/li_table.tt2
Open-ILS/web/css/skin/default/acq.css
Open-ILS/web/js/ui/default/acq/common/li_table.js
docs/RELEASE_NOTES_NEXT/acq_po_detail_view.txt [new file with mode: 0644]

index 718de18..914d03a 100644 (file)
                             </a>
                         </span>
                     </td>
+                    <td style='white-space:nowrap;'>
+                        <a id='acq-inline-copies-toggle' 
+                            href='javascript:;'>&#x2713</a>[% l('Expand') %]
+                    </td>
                     <td>[% l('Items') %]</td>
                     <td>[% l('Notes') %]</td>
                     <td>[% l('Actions') %]</td>
                             </tbody>
                         </table>
                     </td>
+                    <td>
+                        <a name='expand_inline_copies' 
+                            href='javascript:;'>[% l('Expand') %]</a>
+                    </td>
                     <td><a title='FOOOBAR' name='copieslink' href='javascript:void(0);'>[% l('Copies([_1])', '<span name="count">0</span>') %]</a></td>
                     <td>
                         <a name='noteslink' href='javascript:void(0);'>[% l('Notes([_1])', '<span name="notes_count">0</span>') %]</a><span name="notes_alert_flag"></span>
                     <td><span name='li_state'></span></td>
                     <td><input type='text' size='8' name='price'/></td>
                 </tr>
+                <tr id='acq-inline-copies-row' class='acq-inline-copies-row'>
+                    <td colspan='0'>
+                        <table class='acq-li-inline-copies-table'>
+                            <thead>
+                                <tr>
+                                    <th>[% l('Branch') %]</th>
+                                    <th>[% l('Barcode') %]</th>
+                                    <th>[% l('Callnumber') %]</th>
+                                    <th>[% l('Fund') %]</th>
+                                    <th>[% l('Copy Location') %]</th>
+                                    <th>[% l('Circ Modifier') %]</th>
+                                    <th>[% l('Collection Code') %]</th>
+                                    <th>[% l('Note') %]</th>
+                                </tr>
+                            </thead>
+                            <tbody name='acq-li-inline-copies-tbody'>
+                                <tr name='acq-li-inline-copies-template'>
+                                    <td><div name='owning_lib'></div></td>
+                                    <td><div name='barcode'></div></td>
+                                    <td><div name='cn_label'></div></td>
+                                    <td><div name='fund'></div></td>
+                                    <td><div name='location'></div></td>
+                                    <td><div name='circ_modifier'></div></td>
+                                    <td><div name='collection_code'></div></td>
+                                    <td><div name='note'></div></td>
+                                </tr>
+                                <tr name='acq-li-inline-copies-none'>
+                                    <td colspan='0'>[% l('No Copies') %]</td>
+                                </tr>
+                            </tbody>
+                        </table>
+                    </td>
+                </tr>
             </tbody>
         </table>
     </div>
index 07fccb8..e881e26 100644 (file)
@@ -258,3 +258,17 @@ span[name="bib_origin"] img { vertical-align: middle; }
     margin-bottom: 15px;
     padding: 4px;
 }
+
+.acq-li-inline-copies-table { 
+    border-collapse: collapse; 
+    margin-left: 10px;
+    margin-bottom: 10px;
+}
+.acq-inline-copies-row td {
+    background-color: #FEF;
+    border: 2px solid #333;
+}
+.acq-li-inline-copies-table td { 
+    border: 1px solid #464; 
+}
+
index 0114f87..d1cfe99 100644 (file)
@@ -91,6 +91,19 @@ function AcqLiTable() {
 
     this.focusLineitem = new openils.CGI().param('focus_li');
 
+    // capture the inline copy display wrapper and row template
+    this.inlineCopyContainer = 
+        this.tbody.removeChild(dojo.byId('acq-inline-copies-row'));
+    var tb = dojo.query(
+        '[name=acq-li-inline-copies-tbody]', this.inlineCopyContainer)[0];
+    this.inlineCopyTemplate = tb.removeChild(
+        dojo.query('[name=acq-li-inline-copies-template]', tb)[0]);
+    this.inlineNoCopies = tb.removeChild(
+        dojo.query('[name=acq-li-inline-copies-none]', tb)[0]);
+
+    // list of LI IDs that should be refreshed at next display time
+    this.inlineCopiesNeedingRefresh = []; 
+
     dojo.byId("acq-lit-li-actions-selector").onchange = function() { 
         self.applySelectedLiAction(this.options[this.selectedIndex].value);
         this.selectedIndex = 0;
@@ -124,6 +137,7 @@ function AcqLiTable() {
 
 
     dojo.byId('acq-lit-select-toggle').onclick = function(){self.toggleSelect()};
+    dojo.byId('acq-inline-copies-toggle').onclick = function(){self.toggleInlineCopies()};
     dojo.byId('acq-lit-info-back-button').onclick = function(){self.show('list')};
     dojo.byId('acq-lit-copies-back-button').onclick = function(){self.show('list')};
     dojo.byId('acq-lit-notes-back-button').onclick = function(){self.show('list')};
@@ -201,6 +215,7 @@ function AcqLiTable() {
             case 'list':
                 openils.Util.show('acq-lit-table-div');
                 this.focusLi();
+                this.refreshInlineCopies();
                 break;
             case 'info':
                 openils.Util.show('acq-lit-info-div');
@@ -440,6 +455,8 @@ function AcqLiTable() {
         dojo.query('[attr=title]', row)[0].onclick = function() {self.drawInfo(li.id())};
         dojo.query('[name=copieslink]', row)[0].onclick = function() {self.drawCopies(li.id())};
         dojo.query('[name=noteslink]', row)[0].onclick = function() {self.drawLiNotes(li)};
+        dojo.query('[name=expand_inline_copies]', row)[0].onclick = 
+            function() {self.drawInlineCopies(li.id())};
 
         this.drawOrderIdentSelector(li, row);
 
@@ -1219,6 +1236,139 @@ function AcqLiTable() {
         );
     };
 
+    this.toggleInlineCopies = function() {
+        // if any inline copies are not displayed, 
+        // display them all otherwise, hide them all.
+
+        var displayAll = false;
+
+        for (var liId in this.liCache) {
+            if (!this.inlineCopiesVisible(liId)) {
+                displayAll = true;
+                break;
+            }
+        }
+
+        for (var liId in this.liCache) {
+            var row = dojo.byId('acq-inline-copies-row-' + liId);
+            if (displayAll) {
+                if (!row || row._hidden) {
+                    this.drawInlineCopies(liId);
+                }
+            } else { // hide all
+                if (row) {
+                    // drawInlineCopies() on a visible row will hide it.
+                    this.drawInlineCopies(liId);
+                }
+            }
+        }
+
+    };
+
+    this.inlineCopiesVisible = function(liId) {
+        var row = dojo.byId('acq-inline-copies-row-' + liId); 
+        return (row && !row._hidden);
+    }
+
+    this.refreshInlineCopies = function(all, reFetch) {
+        var self = this;
+        var liIds = this.inlineCopiesNeedingRefresh;
+        if (all) liIds = openils.Util.objectProperties(liCache);
+        liIds.forEach(function(liId) {
+            if (self.inlineCopiesVisible(liId)) {
+                self.drawInlineCopies(liId, reFetch); // hide
+                self.drawInlineCopies(liId, reFetch); // re-draw
+            }
+        });
+    };
+
+    // draw inline copy table.  if the table is 
+    // already visible, hide the table as-is
+    // reFetch forces a retrieval of the lineitem and 
+    // copies from the server.  otherwise the locally
+    // cached version of each is used.
+    this.drawInlineCopies = function(liId, reFetch) {
+        var self = this;
+            
+        // find or create the row where the inline copies table will live
+        var containerRow = dojo.byId('acq-inline-copies-row-' + liId);
+        var liRow = dojo.query('[li=' + liId + ']')[0];
+
+        if (!containerRow) {
+
+            // build the inline copies container row and add it to 
+            // the DOM directly after the primary lineitem row
+
+            containerRow = self.inlineCopyContainer.cloneNode(true);
+            containerRow.id = 'acq-inline-copies-row-' + liId;
+
+            if (liRow.nextSibling) {
+                self.tbody.insertBefore(containerRow, liRow.nextSibling);
+            } else {
+                self.tbody.appendChild(containerRow);
+            }
+
+        } else {
+
+            // toggle the visible state
+            containerRow._hidden = !containerRow._hidden;
+            openils.Util.toggle(containerRow, 'table-row');
+
+            if (containerRow._hidden) return; // hide only
+        }
+
+        var handler = function(li) {
+
+            var tbody = dojo.query(
+                '[name=acq-li-inline-copies-tbody]', 
+                containerRow)[0];
+
+            // reset the table before adding copy rows
+            while (tbody.childNodes[0])
+                tbody.removeChild(tbody.childNodes[0]);
+
+            if(li.lineitem_details().length == 0) {
+                tbody.appendChild(
+                    self.inlineNoCopies.cloneNode(true));
+                return; // no copies to show
+            }
+
+            // add a row to the inline copy table for each copy
+            dojo.forEach(li.lineitem_details(),
+                function(copy) {
+                    var row = self.inlineCopyTemplate.cloneNode(true);
+                    tbody.appendChild(row);
+                    self.addInlineCopy(li, copy, row);
+                }
+            );
+        };
+
+        this._fetchLineitem(liId, handler, reFetch);
+    };
+
+    /** Draw read-only copy widgets for inline copies */
+    this.addInlineCopy = function(li, copy, row) {
+
+        var self = this;
+        dojo.forEach(liDetailFields,
+            function(field) {
+
+                var widget = new openils.widget.AutoFieldWidget({
+                    fmObject : copy,
+                    fmField : field,
+                    labelFormat : (field == 'fund') ? fundLabelFormat : null,
+                    searchFormat : (field == 'fund') ? fundSearchFormat : null,
+                    dijitArgs: {"labelType": (field == 'fund') ? "html" : null},
+                    fmClass : 'acqlid',
+                    parentNode : dojo.query('[name=' + field + ']', row)[0],
+                    readOnly : true,
+                });
+
+                widget.build();
+            }
+        );
+    };
+
     /* For a given list of lineitem ids, build a list of full lineitems
      * re-using the fetching logic that is otherwise typical to use in this
      * module.
@@ -2304,7 +2454,10 @@ function AcqLiTable() {
             );
             this.virtDfaCounts = {};
         }
-    }
+
+        if (this.inlineCopiesNeedingRefresh.indexOf(liId) < 0)
+            this.inlineCopiesNeedingRefresh.push(liId);
+    };
 
     this._updateCreatePoPrepayCheckbox = function(prepay) {
         var prepay = openils.Util.isTrue(prepay);
diff --git a/docs/RELEASE_NOTES_NEXT/acq_po_detail_view.txt b/docs/RELEASE_NOTES_NEXT/acq_po_detail_view.txt
new file mode 100644 (file)
index 0000000..0016794
--- /dev/null
@@ -0,0 +1,12 @@
+Acquisitions Inline Item Detail View
+====================================
+
+Acquisitions selection lists and purchase order interfaces contain a new link
+beside each lineitem which, when clicked, creates an inline grid of copies
+linked to the lineitem.  The grid contains the same information that displays
+in the full copy edit grid (from clicking on the Copies(n) link).  However,
+the inline grid is read-only, so it displays much faster and does not require
+the user to change visual contexts.  
+
+Included along the top of the lineitem table is a new '✓ Expand' link which, 
+when clicked, expands or collapses the inline grid for all visible lineitems.