web staff autogrid
authorBill Erickson <berick@esilibrary.com>
Mon, 24 Mar 2014 20:41:52 +0000 (16:41 -0400)
committerBill Erickson <berick@esilibrary.com>
Mon, 24 Mar 2014 20:41:52 +0000 (16:41 -0400)
Signed-off-by: Bill Erickson <berick@esilibrary.com>
Open-ILS/src/templates/staff/css/style.css.tt2
Open-ILS/src/templates/staff/parts/t_autogrid.tt2
Open-ILS/src/templates/staff/test/t_autogrid.tt2
Open-ILS/web/js/ui/default/staff/services/autogrid.js
Open-ILS/web/js/ui/default/staff/services/list.js

index 0a48f53..ed3eff8 100644 (file)
@@ -86,3 +86,110 @@ table.list tr.selected td {
 .pad-horiz {padding : 0px 10px 0px 10px; }
 .pad-vert {padding : 20px 0px 10px 0px;}
 
+
+/* ----------------------------------------------------------------------
+ * Grid
+ * ---------------------------------------------------------------------- */
+
+/* odd/even row styling */
+.eg-grid-content-body > div:nth-child(odd):not(.eg-grid-row-selected) {
+  background-color: rgb(248, 248, 248);
+}
+
+.eg-grid-row {
+  width: 100%;
+  display: flex;
+  border: 1px solid #ccc;
+}
+
+.eg-grid-action-row {
+  border: none;
+  justify-content:flex-end; /* i.e. float right */
+}
+
+.eg-grid-header-row { 
+  font-weight: bold; 
+}
+
+.eg-grid-header-row > .eg-grid-cell {
+  border-right: 1px solid #CCC;
+  text-align: center;
+
+  /* vertically align header cell text by treating 
+     each header cell as a vertical flex container */
+  display:flex;
+  flex-direction:column;
+  justify-content:flex-end;
+}
+
+.eg-grid-cell {
+  /* avoid text flowing into adjacent cells */
+  overflow: hidden;
+}
+
+/* in config display, make cells more obvious */
+.eg-grid-as-conf .eg-grid-row {
+  border: 1px solid #777;
+}
+.eg-grid-as-conf .eg-grid-cell {
+  border-right: 1px solid #777;
+}
+
+/* stock columns need fixed-width controls */
+.eg-grid-cell-stock {
+  flex: 1;
+  text-align: center;
+}
+
+/* the conf header must be twice the stock flex */
+.eg-grid-cell-conf-header {
+  flex: 2;
+  font-weight: bold;
+}
+
+.eg-grid-row-selected {
+  color: rgb(51, 51, 51);
+  background-color: rgb(201, 221, 225);
+  border-bottom: 1px solid #888;
+}
+
+.eg-grid-conf-cell-entry {
+  width:98%;
+  text-align:center;
+  padding: 3px;
+}
+
+.eg-grid-conf-cell-entry:not(:first-child) {
+  border-top:1px solid #ccc;
+}
+
+.eg-grid-conf-row {
+  background-color: #dff0d8;
+  border-color: #d6e9c6;
+}
+
+.eg-grid-conf-row:first-child {
+  /* alignment fix; account for one missing border */
+  padding-right: 1px;
+}
+
+/* hack to make the header columns line up with the content columns
+   when the scroll bar is visible along the right side of the content
+   columns. TODO: if this varies enough by browser, we'll need to
+   calculate the width instead. */
+.eg-grid-scroll > .eg-grid-header-row, 
+.eg-grid-scroll > .eg-grid-conf-row { 
+  padding-right: 15px;
+}
+.eg-grid-scroll > .eg-grid-content-body {
+  overflow-y:scroll; 
+  height: 600px; /* TODO: configurable */
+}
+
+/* ----------------------------------------------------------------------
+ * Grid
+ * ---------------------------------------------------------------------- */
+
+[%# 
+vim: ft=css 
+%]
index ef601a8..311236a 100644 (file)
-<style>
-  /* TODO: move me */
 
-  /* odd/even row styling */
-  .eg-grid > div:nth-child(odd):not(.eg-grid-header-row):not(.eg-grid-row-selected) {
-    background-color: rgb(248, 248, 248);
-  }
-
-  .eg-grid-row {
-    width: 100%;
-    display: flex;
-    border: 1px solid #ccc;
-  }
-
-  .eg-grid-action-row {
-    border: none;
-    justify-content:flex-end; /* i.e. float right */
-  }
-
-  .eg-grid-header-row { 
-    font-weight: bold; 
-  }
-
-  .eg-grid-header-row > .eg-grid-cell {
-    border-right: 1px solid #CCC;
-    text-align: center;
-  }
-
-  .eg-grid-cell {
-    /* avoid text flowing into adjacent cells */
-    overflow: hidden;
-  }
-
-  /* in config display, make cells more obvious */
-  .eg-grid-as-conf .eg-grid-row {
-    border: 1px solid #777;
-  }
-  .eg-grid-as-conf .eg-grid-cell {
-    border-right: 1px solid #777;
-  }
-
-  /* stock columns need fixed-width controls */
-  .eg-grid-cell-1 {flex: 1}
-  .eg-grid-cell-2 {flex: 2}
-
-  .eg-grid-row-selected {
-    color: rgb(51, 51, 51);
-    background-color: rgb(201, 221, 225);
-    border-bottom: 1px solid #888;
-  }
-
-  .eg-grid-conf-cell-entry {
-    width:95%;
-    text-align:center;
-  }
-
-  .eg-grid-conf-cell-entry:not(:first-child) {
-    border-top:1px solid #ccc;
-  }
-
-  .eg-grid-conf-row {
-    background-color: #dff0d8;
-    border-color: #d6e9c6;
-  }
-
-  .eg-grid-conf-row:first-child {
-    /* alignment fix; account for one missing border */
-    padding-right: 1px;
-  }
-
-  /* hack to make the header columns line up with the content columns
-     when the scroll bar is visible along the right side of the content
-     columns. TODO: if this varies enough by browser, we'll need to
-     calculate the width instead. */
-  .eg-grid-scroll > .eg-grid-header-row, 
-  .eg-grid-scroll > .eg-grid-conf-row { 
-    padding-right: 15px;
-  }
-  .eg-grid-scroll > .eg-grid-content-body {
-    overflow-y:scroll; 
-    height: 600px; /* TODO: configurable */
-  }
-
-</style>
+<!-- 
+  Actions row.
+  This sits right above the grid and contains the column picker, etc.
+-->
+<div class="eg-grid-row eg-grid-action-row">
+
+  <!-- column picker -->
+  <div class="btn-group column-picker">
+    <button type="button" class="btn btn-default dropdown-toggle" 
+      data-toggle="dropdown"><span class="caret"></span>
+    </button>
+    <ul class="dropdown-menu pull-right">
+      <li><a href='' ng-click="toggleGridConf()">
+        <span class="glyphicon glyphicon-wrench"></span>
+        [% l('Configure Columns') %]
+      </a></li>
+      <li><a href='' ng-click="list.showAllColumns()">
+        <span class="glyphicon glyphicon-resize-full"></span>
+        [% l('Show All Columns') %]
+      </a></li>
+      <li><a href='' ng-click="list.hideAllColumns()">
+        <span class="glyphicon glyphicon-resize-small"></span>
+        [% l('Hide All Columns') %]
+      </a></li>
+      <li role="presentation" class="divider"></li>
+      <li ng-repeat="col in list.allColumns">
+        <a href='' ng-click="list.displayColumns[col.name] = 
+            !list.displayColumns[col.name]">
+            <span ng-if="list.displayColumns[col.name]" 
+              class="label label-success">&#x2713;</span>
+            <span ng-if="!list.displayColumns[col.name]" 
+              class="label label-warning">&#x2717;</span>
+            <span>{{col.label}}</span>
+        </a>
+      </li>
+    </ul>
+  </div>
+</div>
 
+<!-- Grid -->
 <div class="eg-grid" 
   ng-class="{'eg-grid-as-conf' : showGridConf,'eg-grid-scroll' : isScroll}">
+
   <!-- import embedded eg-grid-field defs via no-op transclude -->
   <div ng-transclude></div>
 
-  <div class="eg-grid-row eg-grid-action-row">
-    [% INCLUDE 'staff/parts/column_picker.tt2' listname='list' %]
-  </div>
-
   <!-- ================== -->
-  <!-- column headers row -->
+  <!-- Column headers row -->
   <div class="eg-grid-row eg-grid-header-row">
-    <div class="eg-grid-cell eg-grid-cell-1">[% l('#') %]</div>
-    <div class="eg-grid-cell eg-grid-cell-1">
-      <input type='checkbox' ng-click="list.toggleSelectAll()"/>
+    <div class="eg-grid-cell eg-grid-cell-stock">[% l('#') %]</div>
+    <div class="eg-grid-cell eg-grid-cell-stock">
+      <div><input type='checkbox' ng-click="list.toggleSelectAll()"/></div>
     </div>
     <div class="eg-grid-cell"
         ng-repeat="column in list.allColumns"
     </div>
   </div>
 
-  <!-- ====================== -->
-  <!-- grid configuration row -->
+  <!-- ============================= -->
+  <!-- Inline grid configuration row -->
   <div class="eg-grid-row eg-grid-conf-row" ng-show="showGridConf">
-    <div class="eg-grid-cell eg-grid-cell-2">
-      <div class="eg-grid-conf-cell-entry">[% l('Wider') %]</div>
-      <div class="eg-grid-conf-cell-entry">[% l('Narrower') %]</div>
+    <div class="eg-grid-cell eg-grid-cell-conf-header">
+      <div class="eg-grid-conf-cell-entry">[% l('Expand') %]</div>
+      <div class="eg-grid-conf-cell-entry">[% l('Shrink') %]</div>
       <div class="eg-grid-conf-cell-entry">[% l('Sort') %]</div>
     </div>
     <div class="eg-grid-cell"
     </div>
   </div>
 
-  <!-- ============== -->
-  <!-- grid data rows -->
+  <!-- ================= -->
+  <!-- grid content rows -->
   <div class="eg-grid-content-body">
     <div class="eg-grid-row" 
         ng-repeat="item in list.items"
         ng-class="{'eg-grid-row-selected' : itemIsSelected(item)}">
-      <div class="eg-grid-cell eg-grid-cell-1
+      <div class="eg-grid-cell eg-grid-cell-stock
         ng-click="handleRowClick($event, item)">
         {{$index + 1 + list.pageOffset}}
       </div>
-      <div class="eg-grid-cell eg-grid-cell-1">
+      <div class="eg-grid-cell eg-grid-cell-stock">
         <!-- ng-click=handleRowClick here has unintended 
              consequences and is unnecessary, avoid it -->
-        <input type='checkbox'  
-          ng-model="list.selected[list.indexValue(item)]"/>
+        <div>
+          <input type='checkbox'  
+            ng-model="list.selected[list.indexValue(item)]"/>
+        </div>
       </div>
       <div class="eg-grid-cell"
           ng-click="handleRowClick($event, item)"
index 885c1d4..a8d201e 100644 (file)
@@ -8,7 +8,7 @@
   id-field="id">
   <!-- 
   eg-list="testEgList"
-    eg-grid-field's require closing tags; not sure why 
+    eg-grid-field's require closing tags; 
     you can also do <div eg-grid-tag attrs..></div>
   -->
   <eg-grid-field name="shortname" label="[% l('Shortname') %]"></eg-grid-field>
@@ -28,6 +28,7 @@
   <eg-grid-field name="parent_ou_shortname" path="parent_ou.shortname" label="[% l('Parent SN') %]"></eg-grid-field>
 </eg-grid>
 
+<!--
 <h1>AutoGrid w/ Auto Fields</h1>
 
 <eg-grid
@@ -37,4 +38,4 @@
   sort="testGridSort"
   query="testGridQuery"
   auto-fields="true"/>
-
+-->
index 9bc5978..e6e4784 100644 (file)
@@ -6,6 +6,7 @@ angular.module('egGridMod', ['egCoreMod', 'egListMod', 'egUiMod', 'ui.bootstrap'
         restrict : 'AE',
         transclude : true,
         scope : {
+            // IDL class hint (e.g. "aou")
             idlClass : '@',
 
             // points to a structure in the calling scope which defines
@@ -14,14 +15,14 @@ angular.module('egGridMod', ['egCoreMod', 'egListMod', 'egUiMod', 'ui.bootstrap'
 
             // if true, grid columns are derived from all non-virtual
             // fields on the base idlClass
-            autoFields : '=',
+            autoFields : '@',
 
             // grid preferences will be stored / retrieved with this key
             persistKey : '@',
 
             // if true, use the scroll CSS to force a vertical height 
             // and scroll bar
-            isScroll : '=',
+            isScroll : '@',
 
             // field whose value is unique and may be used for item
             // reference / lookup.  This will usually be someting like
@@ -29,16 +30,15 @@ angular.module('egGridMod', ['egCoreMod', 'egListMod', 'egUiMod', 'ui.bootstrap'
             // can determine the primary key directly from the IDL.
             idField : '@',
 
-            // egList is provided for us.
-            dataSource : '=',
-
+            // egList containting our tabular data is provided for us
+            // and managed externally.
             egList : '=',
             
             // if true, hide the sortPriority options in the
             // grid configuration UI.  This is primarily used by
             // UIs where the data is ephemeral and can only be
             // single-display-column sorted.
-            disableSortPriority : '='
+            disableSortPriority : '@'
         },
 
         link : function(scope, element, attrs) {     
@@ -60,6 +60,9 @@ angular.module('egGridMod', ['egCoreMod', 'egListMod', 'egUiMod', 'ui.bootstrap'
 
             $scope.list = $scope.egList || egList.create();
 
+            $scope.$watch('isScroll', function(newValue, oldValue) {
+                console.log('isScroll changed to ' + newValue) });
+
             // column-header click quick sort
             $scope.sortOn = function(col_name) {
                 if ($scope.sort && $scope.sort.length &&
@@ -222,7 +225,7 @@ angular.module('egGridMod', ['egCoreMod', 'egListMod', 'egUiMod', 'ui.bootstrap'
                     name : field.name,
                     label : field.label,
                     path : field.path || field.name,
-                    flex : field.flex || 2,
+                    flex : Number(field.flex) || 2,
                     display : (field.display === false) ? false : true
                 };
 
index 4e7d6c1..763a8ad 100644 (file)
@@ -113,9 +113,7 @@ angular.module('egListMod', ['egCoreMod'])
         }
 
         this.hideAllColumns = function() {
-            angular.forEach(this.allColumns, function(field) {
-                delete self.displayColumns[field.name]
-            });
+            self.displayColumns = {};
         }
 
         // selects one row after deselecting all of the others