[open-ils-commits] [GIT] Evergreen ILS branch rel_3_0 updated. 4eb23600cf3fb1fef7384d628a0c18702d238c47

Evergreen Git git at git.evergreen-ils.org
Mon Oct 16 15:35:39 EDT 2017


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Evergreen ILS".

The branch, rel_3_0 has been updated
       via  4eb23600cf3fb1fef7384d628a0c18702d238c47 (commit)
      from  085472193502d22ff4529940bd3bfafb677aab8d (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 4eb23600cf3fb1fef7384d628a0c18702d238c47
Author: Bill Erickson <berickxx at gmail.com>
Date:   Mon Sep 25 10:35:07 2017 -0400

    LP#1717010 Webstaff print/export full grid
    
    1. Adds a new 'Print Full Grid' action which generates printer-friendly
    HTML output of all grid rows.  The print content matches the display
    grid structure, uses the same field filters (e.g. for formatting dates)
    and is retrieved using the same query and sort parameters as the display
    grid.
    
    To render the grid as HTML, a new print HTML template is included at
    print_templates/t_grid_html.tt2.
    
    2. Modifies the 'Export CSV' action to export all grid rows instead of
    only the visible rows.  The link label is modified to 'Export Full CSV'
    to better indicate its intent.
    
    Signed-off-by: Bill Erickson <berickxx at gmail.com>
    Signed-off-by: Mike Rylander <mrylander at gmail.com>

diff --git a/Open-ILS/src/templates/staff/share/print_templates/t_grid_html.tt2 b/Open-ILS/src/templates/staff/share/print_templates/t_grid_html.tt2
new file mode 100644
index 0000000..f3037ce
--- /dev/null
+++ b/Open-ILS/src/templates/staff/share/print_templates/t_grid_html.tt2
@@ -0,0 +1,26 @@
+<!--
+  Autogrid HTML print template.
+-->
+<div>
+  <style>
+    .grid-table {
+      border-collapse: collapse;
+      margin: 1px;
+    }
+    .grid-table td {
+      padding: 2px;
+      border: 1px solid #aaa;
+    }
+  </style>
+  <table class="grid-table">
+    <thead>
+      <tr><th ng-repeat="col in columns">{{col.label}}</th></tr>
+    </thead>
+    <tbody>
+      <tr ng-repeat="item in items track by $index">
+        <td ng-repeat="col in columns"><span>{{item[col.name]}}</span></td>
+      </tr>
+    </tbody>
+  </table>
+</div>
+
diff --git a/Open-ILS/src/templates/staff/share/t_autogrid.tt2 b/Open-ILS/src/templates/staff/share/t_autogrid.tt2
index 1f5500d..e8f94d7 100644
--- a/Open-ILS/src/templates/staff/share/t_autogrid.tt2
+++ b/Open-ILS/src/templates/staff/share/t_autogrid.tt2
@@ -180,14 +180,14 @@
           <span class="glyphicon glyphicon-refresh"></span>
           [% l('Reset Columns') %]
         </a></li>
-        <li><a ng-click="generateCSVExportURL()" 
+        <li><a ng-click="generateCSVExportURL($event)" 
           download="{{csvExportFileName}}.csv" ng-href="{{csvExportURL}}">
           <span class="glyphicon glyphicon-download"></span>
-          [% l('Download CSV') %]
+          [% l('Download Full CSV') %]
         </a></li>
-        <li><a href ng-click="printCSV()">
+        <li><a href ng-click="printHTML()">
           <span class="glyphicon glyphicon-print"></span>
-          [% l('Print CSV') %]
+          [% l('Print Full Grid') %]
         </a></li>
         <li role="presentation" class="divider"></li>
         <li ng-repeat="col in columns">
diff --git a/Open-ILS/web/js/ui/default/staff/services/grid.js b/Open-ILS/web/js/ui/default/staff/services/grid.js
index 1811941..fab8679 100644
--- a/Open-ILS/web/js/ui/default/staff/services/grid.js
+++ b/Open-ILS/web/js/ui/default/staff/services/grid.js
@@ -119,8 +119,10 @@ angular.module('egGridMod',
         controller : [
                     '$scope','$q','egCore','egGridFlatDataProvider','$location',
                     'egGridColumnsProvider','$filter','$window','$sce','$timeout',
+                    'egProgressDialog',
             function($scope,  $q , egCore,  egGridFlatDataProvider , $location,
-                     egGridColumnsProvider , $filter , $window , $sce , $timeout) {
+                     egGridColumnsProvider , $filter , $window , $sce , $timeout,
+                     egProgressDialog) {
 
             var grid = this;
 
@@ -945,9 +947,35 @@ angular.module('egGridMod',
                 return str;
             }
 
-            // sets the download file name and inserts the current CSV
-            // into a Blob URL for browser download.
-            $scope.generateCSVExportURL = function() {
+            /** Export the full data set as CSV.
+             *  Flow of events:
+             *  1. User clicks the 'download csv' link
+             *  2. All grid data is retrieved asychronously
+             *  3. Once all data is all present and CSV-ized, the download 
+             *     attributes are linked to the href.
+             *  4. The href .click() action is prgrammatically fired again,
+             *     telling the browser to download the data, now that the
+             *     data is available for download.
+             *  5 Once downloaded, the href attributes are reset.
+             */
+            grid.csvExportInProgress = false;
+            $scope.generateCSVExportURL = function($event) {
+
+                if (grid.csvExportInProgress) {
+                    // This is secondary href click handler.  Give the
+                    // browser a moment to start the download, then reset
+                    // the CSV download attributes / state.
+                    $timeout(
+                        function() {
+                            $scope.csvExportURL = '';
+                            $scope.csvExportFileName = ''; 
+                            grid.csvExportInProgress = false;
+                        }, 500
+                    );
+                    return;
+                } 
+
+                grid.csvExportInProgress = true;
                 $scope.gridColumnPickerIsOpen = false;
 
                 // let the file name describe the grid
@@ -956,12 +984,21 @@ angular.module('egGridMod',
                     .replace(/\s+/g, '_') + '_' + $scope.page();
 
                 // toss the CSV into a Blob and update the export URL
-                var csv = grid.generateCSV();
-                var blob = new Blob([csv], {type : 'text/plain'});
-                $scope.csvExportURL = 
-                    ($window.URL || $window.webkitURL).createObjectURL(blob);
+                grid.generateCSV().then(function(csv) {
+                    var blob = new Blob([csv], {type : 'text/plain'});
+                    $scope.csvExportURL = 
+                        ($window.URL || $window.webkitURL).createObjectURL(blob);
+
+                    // Fire the 2nd click event now that the browser has
+                    // information on how to download the CSV file.
+                    $timeout(function() {$event.target.click()});
+                });
             }
 
+            /*
+             * TODO: does this serve any purpose given we can 
+             * print formatted HTML?  If so, generateCSV() now
+             * returns a promise, needs light refactoring...
             $scope.printCSV = function() {
                 $scope.gridColumnPickerIsOpen = false;
                 egCore.print.print({
@@ -970,40 +1007,102 @@ angular.module('egGridMod',
                     content_type : 'text/plain'
                 });
             }
+            */
+
+            // Given a row item and column definition, extract the
+            // text content for printing.  Templated columns must be
+            // processed and parsed as HTML, then boiled down to their 
+            // text content.
+            grid.getItemTextContent = function(item, col) {
+                var val;
+                if (col.template) {
+                    val = $scope.translateCellTemplate(col, item);
+                    if (val) {
+                        var node = new DOMParser()
+                            .parseFromString(val, 'text/html');
+                        val = $(node).text();
+                    }
+                } else {
+                    val = grid.dataProvider.itemFieldValue(item, col);
+                    val = $filter('egGridValueFilter')(val, col, item);
+                }
+                return val;
+            }
+
+            /**
+             * Fetches all grid data and transates each item into a simple
+             * key-value pair of column name => text-value.
+             * Included in the response for convenience is the list of 
+             * currently visible column definitions.
+             * TODO: currently fetches a maximum of 10k rows.  Does this
+             * need to be configurable?
+             */
+            grid.getAllItemsAsText = function() {
+                var text_items = [];
+
+                // we don't know the total number of rows we're about
+                // to retrieve, but we can indicate the number retrieved
+                // so far as each item arrives.
+                egProgressDialog.open({value : 0});
+
+                var visible_cols = grid.columnsProvider.columns.filter(
+                    function(c) { return c.visible });
+
+                return grid.dataProvider.get(0, 10000).then(
+                    function() { 
+                        return {items : text_items, columns : visible_cols};
+                    }, 
+                    null,
+                    function(item) { 
+                        egProgressDialog.increment();
+                        var text_item = {};
+                        angular.forEach(visible_cols, function(col) {
+                            text_item[col.name] = 
+                                grid.getItemTextContent(item, col);
+                        });
+                        text_items.push(text_item);
+                    }
+                ).finally(egProgressDialog.close);
+            }
+
+            // Fetch "all" of the grid data, translate it into print-friendly 
+            // text, and send it to the printer service.
+            $scope.printHTML = function() {
+                $scope.gridColumnPickerIsOpen = false;
+                return grid.getAllItemsAsText().then(function(text_items) {
+                    return egCore.print.print({
+                        template : 'grid_html',
+                        scope : text_items
+                    });
+                });
+            }
 
             // generates CSV for the currently visible grid contents
             grid.generateCSV = function() {
-                var csvStr = '';
-                var colCount = grid.columnsProvider.columns.length;
+                return grid.getAllItemsAsText().then(function(text_items) {
+                    var columns = text_items.columns;
+                    var items = text_items.items;
+                    var csvStr = '';
 
-                // columns
-                angular.forEach(grid.columnsProvider.columns,
-                    function(col) {
-                        if (!col.visible) return;
+                    // column headers
+                    angular.forEach(columns, function(col) {
                         csvStr += grid.csvDatum(col.label);
                         csvStr += ',';
-                    }
-                );
+                    });
 
-                csvStr = csvStr.replace(/,$/,'\n');
+                    csvStr = csvStr.replace(/,$/,'\n');
 
-                // items
-                angular.forEach($scope.items, function(item) {
-                    angular.forEach(grid.columnsProvider.columns, 
-                        function(col) {
-                            if (!col.visible) return;
-                            // bare value
-                            var val = grid.dataProvider.itemFieldValue(item, col);
-                            // filtered value (dates, etc.)
-                            val = $filter('egGridValueFilter')(val, col, item);
-                            csvStr += grid.csvDatum(val);
+                    // items
+                    angular.forEach(items, function(item) {
+                        angular.forEach(columns, function(col) {
+                            csvStr += grid.csvDatum(item[col.name]);
                             csvStr += ',';
-                        }
-                    );
-                    csvStr = csvStr.replace(/,$/,'\n');
-                });
+                        });
+                        csvStr = csvStr.replace(/,$/,'\n');
+                    });
 
-                return csvStr;
+                    return csvStr;
+                });
             }
 
             // Interpolate the value for column.linkpath within the context

-----------------------------------------------------------------------

Summary of changes:
 .../staff/share/print_templates/t_grid_html.tt2    |   26 +++
 Open-ILS/src/templates/staff/share/t_autogrid.tt2  |    8 +-
 Open-ILS/web/js/ui/default/staff/services/grid.js  |  163 ++++++++++++++++----
 3 files changed, 161 insertions(+), 36 deletions(-)
 create mode 100644 Open-ILS/src/templates/staff/share/print_templates/t_grid_html.tt2


hooks/post-receive
-- 
Evergreen ILS


More information about the open-ils-commits mailing list