LP#1522638 egProgressDialog features and docs
authorBill Erickson <berickxx@gmail.com>
Fri, 3 Mar 2017 15:34:20 +0000 (10:34 -0500)
committerKathy Lussier <klussier@masslnc.org>
Mon, 6 Mar 2017 18:46:41 +0000 (13:46 -0500)
Use an HTML5 <progress/> element as the progress bar instead of the
Bootstrap progress CSS class.  The HTML5 element provides a more
accurate display.

Add support for 3 modes of operation:

* determinate - shows dialog and percentage progress
* semi-determinate - shows a value-less <progress/> but also displays
  the current value to indicate work happening.
* indeterminate - shows a value-less <progress/> with no specificat
  indication of forward momentum.

Adds a bunch of docs.

Rename egProgressModal to egProgressDialog for consistency with other
eg*Dialog's (which are also modal).

Signed-off-by: Bill Erickson <berickxx@gmail.com>
Signed-off-by: Terran McCanna <tmccanna@georgialibraries.org>
Signed-off-by: Kathy Lussier <klussier@masslnc.org>
Open-ILS/src/templates/staff/css/style.css.tt2
Open-ILS/src/templates/staff/share/t_progress_bar.tt2 [deleted file]
Open-ILS/src/templates/staff/share/t_progress_dialog.tt2 [new file with mode: 0644]
Open-ILS/web/js/ui/default/staff/services/ui.js

index f30ccaa..bdfd64d 100644 (file)
@@ -473,6 +473,11 @@ table.list tr.selected td { /* deprecated? */
     }
 }
 
+.eg-modal-progress progress {
+  width: 100%;
+  height: 25px;
+}
+
 [%# 
 vim: ft=css 
 %]
diff --git a/Open-ILS/src/templates/staff/share/t_progress_bar.tt2 b/Open-ILS/src/templates/staff/share/t_progress_bar.tt2
deleted file mode 100644 (file)
index 6e4df97..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-<!--
-  Generic progress bar.
-
--->
-<div>
-  <div class="modal-header">
-  </div>
-  <div class="modal-body">
-    <div class="progress progress-striped active">
-      <div class="progress-bar" role="progressbar" aria-valuenow="100"
-        aria-valuemin="0" aria-valuemax="100" style="width: 100%">
-      </div>
-    </div>
-  </div>
-</div>
diff --git a/Open-ILS/src/templates/staff/share/t_progress_dialog.tt2 b/Open-ILS/src/templates/staff/share/t_progress_dialog.tt2
new file mode 100644 (file)
index 0000000..2df60d2
--- /dev/null
@@ -0,0 +1,30 @@
+<!--
+  Generic progress bar wrapped in a modal dialog.
+-->
+
+<div>
+  <div class="modal-header"></div>
+  <div class="modal-body">
+    <div class="row eg-modal-progress">
+
+      <div ng-if="data.hasvalue() && data.hasmax()">
+        <!-- determinate progress bar.  shows max/value progress -->
+        <div class="col-md-10">
+          <progress max="{{data.max}}" value="{{data.value}}"></progress>
+        </div>
+        <div class="col-md-2">{{data.percent()}}%</div>
+      </div>
+
+      <div ng-if="data.hasvalue() && !data.hasmax()">
+        <!-- semi-determinate progress bar.  shows value -->
+        <div class="col-md-10"><progress max="1"></progress></div>
+        <div class="col-md-2">{{data.value}}...</div>
+      </div>
+
+      <div ng-if="!data.hasvalue()">
+        <!-- indeterminate -->
+        <div class="col-md-12"><progress max="1"></progress></div>
+      </div>
+    </div>
+  </div>
+</div>
index 19e80a3..ad4c104 100644 (file)
@@ -78,32 +78,126 @@ function($timeout , $parse) {
     };
 })
 
-
 /**
- * egProgressModal.open();
+ * Progress Dialog. 
+ *
+ * egProgressDialog.open();
+ * egProgressDialog.open({value : 0});
+ * egProgressDialog.open({value : 0, max : 123});
+ * egProgressDialog.increment();
+ * egProgressDialog.increment();
+ * egProgressDialog.close();
+ *
+ * Each dialog has 2 numbers, 'max' and 'value'.
+ * The content of these values determines how the dialog displays.  
+ *
+ * There are 3 flavors:
+ *
+ * -- value is set, max is set
+ * determinate: shows a progression with a percent complete.
+ *
+ * -- value is set, max is unset
+ * semi-determinate, with a value report.  Shows a value-less
+ * <progress/>, but shows the value as a number in the dialog.
+ *
+ * This is useful in cases where the total number of items to retrieve
+ * from the server is unknown, but we know how many items we've
+ * retrieved thus far.  It helps to reinforce that something specific
+ * is happening, but we don't know when it will end.
+ *
+ * -- value is unset
+ * indeterminate: shows a generic value-less <progress/> with no 
+ * clear indication of progress.
+ *
+ * Only 1 egProgressDialog instance will be activate at a time.
+ * Each invocation of .open() destroys any existing instance.
  */
-.factory('egProgressModal', 
 
-        ['$uibModal','$interpolate',
-function($uibModal, $interpolate){
+/* Simple storage class for egProgressDialog data maintenance.
+ * This data lives outside of egProgressDialog so it can be 
+ * directly imported into egProgressDialog's $uibModalInstance.
+ */
+.factory('egProgressData', [
+    function() {
+        var service = {}; // max/value initially unset
+
+        service.reset = function() {
+            delete service.max;
+            delete service.value;
+        }
+
+        service.hasvalue = function() {
+            return Number.isInteger(service.value);
+        }
+
+        service.hasmax = function() {
+            return Number.isInteger(service.max);
+        }
+
+        service.percent = function() {
+            if (service.hasvalue()  && 
+                service.hasmax()    && 
+                service.max > 0     &&
+                service.value <= service.max)
+                return Math.floor((service.value / service.max) * 100);
+            return 100;
+        }
+
+        return service;
+    }
+])
+
+.factory('egProgressDialog', [
+            'egProgressData','$uibModal', 
+    function(egProgressData , $uibModal) {
     var service = {};
 
-    service.open = function() {
+    service.open = function(args) {
+        service.close(); // force-kill existing instances.
+
+        // Reset to an indeterminate progress bar, 
+        // overlay with caller values.
+        egProgressData.reset();
+        service.update(angular.extend({}, args));
+
         return $uibModal.open({
-            templateUrl: './share/t_progress_bar',
-            controller: ['$scope', '$uibModalInstance',
-                function($scope, $uibModalInstance) {
+            templateUrl: './share/t_progress_dialog',
+            controller: ['$scope','$uibModalInstance','egProgressData',
+                function( $scope , $uibModalInstance , egProgressData) {
                   service.currentInstance = $uibModalInstance;
+                  $scope.data = egProgressData; // tiny service
                 }
             ]
         });
     };
+
     service.close = function() {
         if (service.currentInstance) {
             service.currentInstance.close();
             delete service.currentInstance;
         }
     }
+
+    // Set the current state of the progress bar.
+    service.update = function(args) {
+        if (args.max != undefined) 
+            egProgressData.max = args.max;
+        if (args.value != undefined) 
+            egProgressData.value = args.value;
+    }
+
+    // Increment the current value.  If no amount is specified,
+    // it increments by 1.  Calling increment() on an indetermite
+    // progress bar will force it to be a (semi-)determinate bar.
+    service.increment = function(amt) {
+        if (!Number.isInteger(amt)) amt = 1;
+
+        if (!egProgressData.hasvalue())
+            egProgressData.value = 0;
+
+        egProgressData.value += amt;
+    }
+
     return service;
 }])