[open-ils-commits] [GIT] Evergreen ILS branch rel_3_2 updated. 02cab0796ab405d456c92d17a608958f005808f3

Evergreen Git git at git.evergreen-ils.org
Fri May 24 14:01:51 EDT 2019


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_2 has been updated
       via  02cab0796ab405d456c92d17a608958f005808f3 (commit)
       via  9f3cffd2e3bdcd96c0dd9b82c5bab02f0cfd6cb9 (commit)
      from  0a3db017e132e1736ddd0070191ce98423e8998f (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 02cab0796ab405d456c92d17a608958f005808f3
Author: Jane Sandberg <sandbej at linnbenton.edu>
Date:   Fri May 24 10:10:07 2019 -0700

    LP1816480 follow-up: add dependency missing from 3.2 branch
    
    Signed-off-by: Jane Sandberg <sandbej at linnbenton.edu>
    Signed-off-by: Bill Erickson <berickxx at gmail.com>

diff --git a/Open-ILS/src/eg2/src/app/share/grid/grid.ts b/Open-ILS/src/eg2/src/app/share/grid/grid.ts
index f96a4e3162..c783e0afba 100644
--- a/Open-ILS/src/eg2/src/app/share/grid/grid.ts
+++ b/Open-ILS/src/eg2/src/app/share/grid/grid.ts
@@ -1,7 +1,7 @@
 /**
  * Collection of grid related classses and interfaces.
  */
-import {TemplateRef} from '@angular/core';
+import {TemplateRef, EventEmitter} from '@angular/core';
 import {Observable, Subscription} from 'rxjs';
 import {IdlService, IdlObject} from '@eg/core/idl.service';
 import {OrgService} from '@eg/core/org.service';

commit 9f3cffd2e3bdcd96c0dd9b82c5bab02f0cfd6cb9
Author: Bill Erickson <berickxx at gmail.com>
Date:   Tue Mar 5 17:07:21 2019 -0500

    LP1816480 Angular grid ARIA improvements
    
    Various navigation and "role" improvements to the Angular grid:
    
    * Apply "grid", "row", "columnheader", and "gridcell" role attributes.
    * Page-Down goes to next page
    * Page-Up goes to previous page
    * Shift-UpArrow extends selection one row up (spanning pages).
    * Shift-DownArrow extends selection one row down (spanning pages).
    * Shift-Arrow controls support reverse navigation for back-tracking to
      de-select certain rows.
    ** E.g. shift-up 3 rows then shift-down 1 will leave 2 rows selected.
    * Control-A now selects all rows in the page.
    ** For consistency with the select-all checkbox, only rows in the
       current page are selected.
    ** Note we could add an option to extend the selection to all rows,
       but it would require pre-fetching all of the data, simimar to
       how grid printing pre-fetches.
    
    Signed-off-by: Bill Erickson <berickxx at gmail.com>
    Signed-off-by: Jane Sandberg <sandbej at linnbenton.edu>

diff --git a/Open-ILS/src/eg2/src/app/share/grid/grid-body.component.html b/Open-ILS/src/eg2/src/app/share/grid/grid-body.component.html
index b7284fe6f0..c38fafa4f3 100644
--- a/Open-ILS/src/eg2/src/app/share/grid/grid-body.component.html
+++ b/Open-ILS/src/eg2/src/app/share/grid/grid-body.component.html
@@ -2,7 +2,7 @@
   tabindex=1 so the grid body can capture keyboard events.
 -->
 <div class="eg-grid-body" tabindex="1" (keydown)="onGridKeyDown($event)">
-  <div class="eg-grid-row eg-grid-body-row {{context.rowClassCallback(row)}}"
+  <div role="row" class="eg-grid-row eg-grid-body-row {{context.rowClassCallback(row)}}"
     [ngClass]="{'selected': context.rowSelector.contains(context.getRowIndex(row))}"
     *ngFor="let row of context.dataSource.getPageOfRows(context.pager); let idx = index">
 
@@ -25,7 +25,8 @@
         </ng-container>
       </ng-container>
     </div>
-    <div class="eg-grid-cell eg-grid-body-cell" [ngStyle]="{flex:col.flex}"
+    <div role="gridcell" class="eg-grid-cell eg-grid-body-cell"
+      [ngStyle]="{flex:col.flex}"
       [ngClass]="{'eg-grid-cell-overflow': context.overflowCells}"
       (dblclick)="onRowDblClick(row)"
       (click)="onRowClick($event, row, idx)"
diff --git a/Open-ILS/src/eg2/src/app/share/grid/grid-body.component.ts b/Open-ILS/src/eg2/src/app/share/grid/grid-body.component.ts
index e4829cee01..48d0e4a011 100644
--- a/Open-ILS/src/eg2/src/app/share/grid/grid-body.component.ts
+++ b/Open-ILS/src/eg2/src/app/share/grid/grid-body.component.ts
@@ -20,23 +20,45 @@ export class GridBodyComponent implements OnInit {
     onGridKeyDown(evt: KeyboardEvent) {
         switch (evt.key) {
             case 'ArrowUp':
-                this.context.selectPreviousRow();
+                if (evt.shiftKey) {
+                    // Extend selection up one row
+                    this.context.selectMultiRowsPrevious();
+                } else {
+                    this.context.selectPreviousRow();
+                }
                 evt.stopPropagation();
                 break;
             case 'ArrowDown':
-                this.context.selectNextRow();
+                if (evt.shiftKey) {
+                    // Extend selection down one row
+                    this.context.selectMultiRowsNext();
+                } else {
+                    this.context.selectNextRow();
+                }
                 evt.stopPropagation();
                 break;
             case 'ArrowLeft':
+            case 'PageUp':
                 this.context.toPrevPage()
                 .then(ok => this.context.selectFirstRow(), err => {});
                 evt.stopPropagation();
                 break;
             case 'ArrowRight':
+            case 'PageDown':
                 this.context.toNextPage()
                 .then(ok => this.context.selectFirstRow(), err => {});
                 evt.stopPropagation();
                 break;
+            case 'a':
+                // control-a means select all visible rows.
+                // For consistency, select all rows in the current page only.
+                if (evt.ctrlKey) {
+                    this.context.rowSelector.clear();
+                    this.context.selectRowsInPage();
+                    evt.preventDefault();
+                }
+                break;
+
             case 'Enter':
                 if (this.context.lastSelectedIndex) {
                     this.grid.onRowActivate.emit(
diff --git a/Open-ILS/src/eg2/src/app/share/grid/grid-header.component.html b/Open-ILS/src/eg2/src/app/share/grid/grid-header.component.html
index 58e0c66774..35a09503a9 100644
--- a/Open-ILS/src/eg2/src/app/share/grid/grid-header.component.html
+++ b/Open-ILS/src/eg2/src/app/share/grid/grid-header.component.html
@@ -1,24 +1,29 @@
 
-<div class="eg-grid-row eg-grid-header-row">
-  <div class="eg-grid-cell eg-grid-header-cell eg-grid-checkbox-cell eg-grid-cell-skinny">
-    <input type='checkbox' (click)="handleBatchSelect($event)">
+<div row="row" class="eg-grid-row eg-grid-header-row">
+  <div role="columnheader"
+    class="eg-grid-cell eg-grid-header-cell eg-grid-checkbox-cell eg-grid-cell-skinny">
+    <input type='checkbox' (click)="handleBatchSelect($event)"
+      [(ngModel)]="batchRowCheckbox">
   </div>
-  <div class="eg-grid-cell eg-grid-header-cell eg-grid-number-cell eg-grid-cell-skinny">
+  <div role="columnheader"
+    class="eg-grid-cell eg-grid-header-cell eg-grid-number-cell eg-grid-cell-skinny">
     <span i18n="number|Row Number Header">#</span>
   </div>
-  <div *ngIf="context.rowFlairIsEnabled" 
+  <div *ngIf="context.rowFlairIsEnabled"
+    role="columnheader"
     class="eg-grid-cell eg-grid-header-cell eg-grid-flair-cell">
     <span class="material-icons">notifications</span>
   </div>
-  <div *ngFor="let col of context.columnSet.displayColumns()" 
-    draggable="true" 
+  <div role="columnheader"
+    *ngFor="let col of context.columnSet.displayColumns()"
+    draggable="true"
     (dragstart)="dragColumn = col"
     (drop)="onColumnDrop(col)"
     (dragover)="onColumnDragEnter($event, col)"
     (dragleave)="onColumnDragLeave($event, col)"
     [ngClass]="{'dragover' : col.isDragTarget}"
     class="eg-grid-cell eg-grid-header-cell" [ngStyle]="{flex:col.flex}">
-    <a class="sortable label-with-material-icon" *ngIf="col.isSortable" 
+    <a class="sortable label-with-material-icon" *ngIf="col.isSortable"
       (click)="sortOneColumn(col)">
       <span class="eg-grid-header-cell-sort-label">{{col.label}}</span>
       <span class="material-icons eg-grid-header-cell-sort-arrow"
diff --git a/Open-ILS/src/eg2/src/app/share/grid/grid-header.component.ts b/Open-ILS/src/eg2/src/app/share/grid/grid-header.component.ts
index 0010a45f38..591fc66c2b 100644
--- a/Open-ILS/src/eg2/src/app/share/grid/grid-header.component.ts
+++ b/Open-ILS/src/eg2/src/app/share/grid/grid-header.component.ts
@@ -13,9 +13,15 @@ export class GridHeaderComponent implements OnInit {
 
     dragColumn: GridColumn;
 
+    batchRowCheckbox: boolean;
+
     constructor() {}
 
-    ngOnInit() {}
+    ngOnInit() {
+        this.context.selectRowsInPageEmitter.subscribe(
+            () => this.batchRowCheckbox = true
+        );
+    }
 
     onColumnDragEnter($event: any, col: any) {
         if (this.dragColumn && this.dragColumn.name !== col.name) {
@@ -71,9 +77,7 @@ export class GridHeaderComponent implements OnInit {
     }
 
     selectAll() {
-        const rows = this.context.dataSource.getPageOfRows(this.context.pager);
-        const indexes = rows.map(r => this.context.getRowIndex(r));
-        this.context.rowSelector.select(indexes);
+        this.context.selectRowsInPage();
     }
 
     allRowsAreSelected(): boolean {
diff --git a/Open-ILS/src/eg2/src/app/share/grid/grid-toolbar.component.html b/Open-ILS/src/eg2/src/app/share/grid/grid-toolbar.component.html
index 5eaa81ff62..bac58abe1a 100644
--- a/Open-ILS/src/eg2/src/app/share/grid/grid-toolbar.component.html
+++ b/Open-ILS/src/eg2/src/app/share/grid/grid-toolbar.component.html
@@ -17,7 +17,8 @@
       *ngIf="gridContext.toolbarCheckboxes.length">
       <ng-container *ngFor="let cb of gridContext.toolbarCheckboxes">
         <label class="form-check-label">
-          <input class="form-check-input" type="checkbox" 
+          <input class="form-check-input" type="checkbox"
+            [(ngModel)]="cb.isChecked"
             (click)="cb.onChange($event.target.checked)"/>
             {{cb.label}}
         </label>
@@ -28,6 +29,9 @@
   <!-- push everything else to the right -->
   <div class="flex-1"></div>
 
+  <div class="font-sm font-italic d-flex flex-column-reverse mr-2">
+    {{gridContext.rowSelector.selected().length}} selected
+  </div>
   <div ngbDropdown class="mr-1" placement="bottom-right">
     <button ngbDropdownToggle [disabled]="!gridContext.toolbarActions.length"
         class="btn btn-outline-dark no-dropdown-caret">
diff --git a/Open-ILS/src/eg2/src/app/share/grid/grid.component.html b/Open-ILS/src/eg2/src/app/share/grid/grid.component.html
index a98e17afaf..77ea0e6fb1 100644
--- a/Open-ILS/src/eg2/src/app/share/grid/grid.component.html
+++ b/Open-ILS/src/eg2/src/app/share/grid/grid.component.html
@@ -1,8 +1,8 @@
 
-<div class="eg-grid">
+<div class="eg-grid" role="grid">
 
   <eg-grid-toolbar
-    [gridContext]="context" 
+    [gridContext]="context"
     [gridPrinter]="gridPrinter"
     [colWidthConfig]="colWidthConfig">
   </eg-grid-toolbar>
@@ -11,7 +11,7 @@
 
   <eg-grid-column-width #colWidthConfig [gridContext]="context">
   </eg-grid-column-width>
-  
+
   <eg-grid-print #gridPrinter [gridContext]="context">
   </eg-grid-print>
 
diff --git a/Open-ILS/src/eg2/src/app/share/grid/grid.ts b/Open-ILS/src/eg2/src/app/share/grid/grid.ts
index b591d8a7b5..f96a4e3162 100644
--- a/Open-ILS/src/eg2/src/app/share/grid/grid.ts
+++ b/Open-ILS/src/eg2/src/app/share/grid/grid.ts
@@ -436,6 +436,10 @@ export class GridContext {
     defaultHiddenFields: string[];
     overflowCells: boolean;
 
+    // Allow calling code to know when the select-all-rows-in-page
+    // action has occurred.
+    selectRowsInPageEmitter: EventEmitter<void>;
+
     // Services injected by our grid component
     idl: IdlService;
     org: OrgService;
@@ -461,6 +465,7 @@ export class GridContext {
     }
 
     init() {
+        this.selectRowsInPageEmitter = new EventEmitter<void>();
         this.columnSet = new GridColumnSet(this.idl, this.idlClass);
         this.columnSet.isSortable = this.isSortable === true;
         this.columnSet.isMultiSortable = this.isMultiSortable === true;
@@ -699,6 +704,12 @@ export class GridContext {
         this.lastSelectedIndex = index;
     }
 
+    selectMultipleRows(indexes: any[]) {
+        this.rowSelector.clear();
+        this.rowSelector.select(indexes);
+        this.lastSelectedIndex = indexes[indexes.length - 1];
+    }
+
     // selects or deselects an item, without affecting the others.
     // returns true if the item is selected; false if de-selected.
     toggleSelectOneRow(index: any) {
@@ -738,12 +749,84 @@ export class GridContext {
         }
     }
 
+    // shift-up-arrow
+    // Select the previous row in addition to any currently selected row.
+    // However, if the previous row is already selected, assume the user
+    // has reversed direction and now wants to de-select the last selected row.
+    selectMultiRowsPrevious() {
+        if (!this.lastSelectedIndex) { return; }
+        const pos = this.getRowPosition(this.lastSelectedIndex);
+        const selectedIndexes = this.rowSelector.selected();
+
+        const promise = // load the previous page of data if needed
+            (pos === this.pager.offset) ? this.toPrevPage() : Promise.resolve();
+
+        promise.then(
+            ok => {
+                const row = this.dataSource.data[pos - 1];
+                const newIndex = this.getRowIndex(row);
+                if (selectedIndexes.filter(i => i === newIndex).length > 0) {
+                    // Prev row is already selected.  User is reversing direction.
+                    this.rowSelector.deselect(this.lastSelectedIndex);
+                    this.lastSelectedIndex = newIndex;
+                } else {
+                    this.selectMultipleRows(selectedIndexes.concat(newIndex));
+                }
+            },
+            err => {}
+        );
+    }
+
+    // shift-down-arrow
+    // Select the next row in addition to any currently selected row.
+    // However, if the next row is already selected, assume the user
+    // has reversed direction and wants to de-select the last selected row.
+    selectMultiRowsNext() {
+        if (!this.lastSelectedIndex) { return; }
+        const pos = this.getRowPosition(this.lastSelectedIndex);
+        const selectedIndexes = this.rowSelector.selected();
+
+        const promise = // load the next page of data if needed
+            (pos === (this.pager.offset + this.pager.limit - 1)) ?
+            this.toNextPage() : Promise.resolve();
+
+        promise.then(
+            ok => {
+                const row = this.dataSource.data[pos + 1];
+                const newIndex = this.getRowIndex(row);
+                if (selectedIndexes.filter(i => i === newIndex).length > 0) {
+                    // Next row is already selected.  User is reversing direction.
+                    this.rowSelector.deselect(this.lastSelectedIndex);
+                    this.lastSelectedIndex = newIndex;
+                } else {
+                    this.selectMultipleRows(selectedIndexes.concat(newIndex));
+                }
+            },
+            err => {}
+        );
+    }
+
+    getFirstRowInPage(): any {
+        return this.dataSource.data[this.pager.offset];
+    }
+
+    getLastRowInPage(): any {
+        return this.dataSource.data[this.pager.offset + this.pager.limit - 1];
+    }
+
     selectFirstRow() {
-        this.selectRowByPos(this.pager.offset);
+        this.selectOneRow(this.getRowIndex(this.getFirstRowInPage()));
     }
 
     selectLastRow() {
-        this.selectRowByPos(this.pager.offset + this.pager.limit - 1);
+        this.selectOneRow(this.getRowIndex(this.getLastRowInPage()));
+    }
+
+    selectRowsInPage() {
+        const rows = this.dataSource.getPageOfRows(this.pager);
+        const indexes = rows.map(r => this.getRowIndex(r));
+        this.rowSelector.select(indexes);
+        this.selectRowsInPageEmitter.emit();
     }
 
     toPrevPage(): Promise<any> {

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

Summary of changes:
 .../src/app/share/grid/grid-body.component.html    |  5 +-
 .../eg2/src/app/share/grid/grid-body.component.ts  | 26 ++++++-
 .../src/app/share/grid/grid-header.component.html  | 21 +++--
 .../src/app/share/grid/grid-header.component.ts    | 12 ++-
 .../src/app/share/grid/grid-toolbar.component.html |  6 +-
 .../src/eg2/src/app/share/grid/grid.component.html |  6 +-
 Open-ILS/src/eg2/src/app/share/grid/grid.ts        | 89 +++++++++++++++++++++-
 7 files changed, 142 insertions(+), 23 deletions(-)


hooks/post-receive
-- 
Evergreen ILS


More information about the open-ils-commits mailing list