- CSS classes for red, dark red, and orange eg-grid-cells.
- New parameter for eg-grid 'rowClass' to take an object with a function
to set the class of a cell, allowing such customizations as coloring based
on item fields.
- Implementation of 'rowClass' on the Patron Bills interface to display
colors indicating current Fines Stop reason, based on XUL client.
- New parameter for eg-grid 'statusCell' to take an object with a function
to programattically add status icons to a new "Status Icon" column. Said
column requires a boolean in the object in order to display.
- Implementation of 'statusCell' on the Patron Bills interface to display
glyphicons based on if the bill is for a circ that is lost, overdue, or long
overdue.
Signed-off-by: Kyle Huckins <khuckins@catalyte.io>
Changes to be committed:
modified: Open-ILS/src/templates/staff/circ/patron/t_bills_list.tt2
modified: Open-ILS/src/templates/staff/css/style.css.tt2
modified: Open-ILS/src/templates/staff/share/t_autogrid.tt2
modified: Open-ILS/web/js/ui/default/staff/circ/patron/bills.js
modified: Open-ILS/web/js/ui/default/staff/services/grid.js
Signed-off-by: Kathy Lussier <klussier@masslnc.org>
Signed-off-by: Dan Wells <dbw2@calvin.edu>
Signed-off-by: Dawn Dale <ddale@georgialibraries.org>
grid-controls="gridControls"
revision="gridRevision"
persist-key="circ.patron.bills"
- dateformat="{{$root.egDateAndTimeFormat}}">
+ dateformat="{{$root.egDateAndTimeFormat}}"
+ row-class="colorizeBillsList"
+ status-cell="statusIconColumn">
<eg-grid-menu-item label="[% l('Bill Patron') %]"
handler="showBillDialog"></eg-grid-menu-item>
<eg-grid-action label="[% l('Full Details') %]"
handler="showFullDetails"></eg-grid-action>
- <eg-grid-field label="[% l('Balance Owed') %]" path='summary.balance_owed'></eg-grid-field>
+ <eg-grid-field label="[% l('Balance Owed') %]" path='summary.balance_owed' required></eg-grid-field>
<eg-grid-field label="[% l('Bill #') %]" path='id'></eg-grid-field>
<eg-grid-field label="[% l('Start') %]" path='xact_start' datatype="timestamp"></eg-grid-field>
<eg-grid-field label="[% l('Total Billed') %]" path='summary.total_owed'></eg-grid-field>
<eg-grid-field path='circulation.circ_lib' required hidden></eg-grid-field>
<eg-grid-field path='circulation.duration' required hidden></eg-grid-field>
<eg-grid-field path='circulation.due_date' dateonlyinterval="circulation.duration" datecontext="circulation.circ_lib" required hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Stop Fines') %]" path="circulation.stop_fines" hidden required> </eg-grid-field>
+ <eg-grid-field path="circulation.checkin_time" hidden required></eg-grid-field>
<eg-grid-field path='circulation.*' hidden> </eg-grid-field>
<eg-grid-field label="[% l('Checkout / Renewal Library') %]"
path='circulation.circ_lib.shortname' required hidden> </eg-grid-field>
text-align: center;
}
-/* the conf header must be twice the stock flex */
+.eg-grid-cell-stock-status {
+ width: 4.4em;
+ text-align: center;
+}
+
+/* the conf header must be ~four times the stock flex */
.eg-grid-cell-conf-header {
width: 4.4em;
font-weight: bold;
}
+.eg-grid-cell-conf-header-status {
+ width: 8.8em;
+ font-weight: bold;
+}
+
.eg-grid-row-selected {
color: #000;
background-color: rgb(201, 221, 225);
background: rgb(201, 221, 225);
border-bottom: 1px solid #888;
}
+
+/* patron bill row-highlighting */
+.red-row-highlight {
+ color: #FFF;
+ background-color: #FF0000;
+}
+.orange-row-highlight {
+ color: #FFF;
+ background-color: #FFA500 ;
+}
+.dark-red-row-highlight {
+ color: #FFF;
+ background-color: #800000;
+}
+.eg-grid-row-selected .red-row-highlight {
+ background-color: #CF0000;
+}
+.eg-grid-row-selected .orange-row-highlight {
+ background-color: #DE9000;
+}
+.eg-grid-row-selected .dark-red-row-highlight {
+ background-color: #5C0000;
+}
+
.eg-grid-cell-content::selection {
color: #000;
background: rgb(201, 221, 225);
type='checkbox' ng-model="selectAll"/>
</div>
</div>
+ <div class="eg-grid-cell eg-grid-cell-stock-status" ng-show="statusCell.isEnabled">
+ <div title="[% l('Status Icon Column') %]">[% l('Status') %]</div>
+ </div>
<div class="eg-grid-cell"
eg-grid-column-drag-dest
ng-class="{'eg-grid-column-last-mod' : isLastModifiedColumn(col)}"
<!-- Inline grid configuration row -->
<div class="eg-grid-row eg-grid-conf-row" ng-show="showGridConf">
- <div class="eg-grid-cell eg-grid-cell-conf-header">
+ <div class="eg-grid-cell"
+ ng-class="statusicon.isEnabled ? 'eg-grid-cell-conf-header-status' : '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>
ng-show="items.length > 0"
ng-class="{'eg-grid-row-selected' : selected[indexValue(item)]}">
<div class="eg-grid-cell eg-grid-cell-stock" ng-show="showIndex"
- ng-click="handleRowClick($event, item)" title="[% l('Row Index') %]">
+ ng-click="handleRowClick($event, item)" title="[% l('Row Index') %]"
+ ng-class="rowClass.rowClass(item)">
<a href ng-show="gridControls.activateItem"
ng-click="gridControls.activateItem(item)" style="font-weight:bold">
{{$index + offset() + 1}}
</a>
<div ng-hide="gridControls.activateItem">{{$index + offset() + 1}}</div>
</div>
- <div class="eg-grid-cell eg-grid-cell-stock" ng-show="canMultiSelect">
+ <div class="eg-grid-cell eg-grid-cell-stock" ng-show="canMultiSelect"
+ ng-class="rowClass.rowClass(item)">
<!-- ng-click=handleRowClick here has unintended
consequences and is unnecessary, avoid it -->
<div>
ng-model="selected[indexValue(item)]"/>
</div>
</div>
+ <div class="eg-grid-cell eg-grid-cell-stock-status" ng-show="statusCell.isEnabled"
+ ng-class="rowClass.rowClass(item)">
+ <span ng-bind-html="statusCell.template(item)"></span>
+ </div>
<div class="eg-grid-cell eg-grid-cell-content"
ng-click="handleRowClick($event, item)"
ng-dblclick="gridControls.activateItem(item)"
ng-repeat="col in columns"
style="text-align:{{col.align}}; flex:{{col.flex}}"
- ng-show="col.visible">
+ ng-show="col.visible"
+ ng-class="rowClass.rowClass(item)">
<!-- if the cell comes with its own template,
translate that content into HTML and insert it here -->
return ['xact_start'];
}
}
+ // -------------
+ // Apply coloring to rows based on fines stop reason
+ $scope.colorizeBillsList = {
+ rowClass: function(item) {
+ if (!item['circulation.checkin_time']) {
+ if (item['circulation.stop_fines'] == 'LOST') {
+ return 'dark-red-row-highlight';
+ } else if (item['circulation.stop_fines'] == 'LONGOVERDUE') {
+ return 'red-row-highlight';
+ } else if (item['circulation.due_date'] && // Still checked out - need feedback on this approach, feel like there's a better way
+ !item['circulation.stop_fines']) {
+ return 'orange-row-highlight';
+ }
+ }
+ }
+ }
+
+ // Status Icon Column definition
+ $scope.statusIconColumn = {
+ isEnabled: true,
+ template: function(item) {
+ var template = "";
+ var icons = [];
+ var now = new Date();
+
+ if (item['circulation.due_date'] &&
+ !item['circulation.checkin_time']) {
+ var due_date = new Date(item['circulation.due_date']);
+
+ if (item['circulation.stop_fines'] &&
+ item['circulation.stop_fines'] == "LOST") {
+ icons.push('glyphicon-question-sign');
+ } else if (item['circulation.stop_fines'] &&
+ item['circulation.stop_fines'] == "LONGOVERDUE") {
+ icons.push('glyphicon-exclamation-sign');
+ } else if (now >= due_date) {
+ icons.push('glyphicon-time');
+ }
+ }
+
+ angular.forEach(icons, function(icon) {
+ template = template + "<i class='glyphicon " + icon + "'></i>"
+ });
+ return template;
+ }
+ }
billSvc.fetchSummary().then(function(s) {$scope.summary = s});
// column
features : '@',
+ // optional: object containing function to conditionally apply
+ // class to each row.
+ rowClass : '=',
+
+ // optional: object that enables status icon field and contains
+ // function to handle what status icons should exist and why.
+ statusCell : '=',
+
// optional primary grid label
mainLabel : '@',
scope.handleAutoFields();
scope.collect();
+ var statusCell = scope.statusCell;
+ var rowClass = scope.rowClass;
+
scope.grid_element = element;
$(element)
.find('.eg-grid-content-body')