[open-ils-commits] [GIT] Evergreen ILS branch rel_3_3 updated. 95eed52ed5605f9cce2516652352196abd1d5947
Evergreen Git
git at git.evergreen-ils.org
Fri May 24 14:01:27 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_3 has been updated
via 95eed52ed5605f9cce2516652352196abd1d5947 (commit)
from 82ebba292f3e78fa6d4cb7a82d8df096839dc5f2 (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 95eed52ed5605f9cce2516652352196abd1d5947
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 8d495aa84d..a9f35aaaa5 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">
@@ -27,7 +27,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 15aa2b7038..9c9b19041c 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 98a6fbf365..96811a32aa 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,26 +1,31 @@
-<div class="eg-grid-row eg-grid-header-row">
+<div row="row" class="eg-grid-row eg-grid-header-row">
<ng-container *ngIf="!context.disableSelect">
- <div class="eg-grid-cell eg-grid-header-cell eg-grid-checkbox-cell eg-grid-cell-skinny">
- <input type='checkbox' (click)="handleBatchSelect($event)">
+ <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>
</ng-container>
- <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 5dd307f4f9..af223fefdf 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
@@ -19,7 +19,7 @@
<label class="form-check-label">
<input class="form-check-input" type="checkbox"
[(ngModel)]="cb.isChecked"
- (click)="cb.onChange.emit($event.target.checked)"/>
+ (click)="cb.onChange($event.target.checked)"/>
{{cb.label}}
</label>
</ng-container>
@@ -29,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 7c30438ccc..fbc020895d 100644
--- a/Open-ILS/src/eg2/src/app/share/grid/grid.ts
+++ b/Open-ILS/src/eg2/src/app/share/grid/grid.ts
@@ -442,6 +442,10 @@ export class GridContext {
overflowCells: boolean;
showLinkSelectors: 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;
@@ -467,6 +471,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;
@@ -731,6 +736,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) {
@@ -770,12 +781,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 | 5 +-
.../src/eg2/src/app/share/grid/grid.component.html | 6 +-
Open-ILS/src/eg2/src/app/share/grid/grid.ts | 87 +++++++++++++++++++++-
7 files changed, 140 insertions(+), 22 deletions(-)
hooks/post-receive
--
Evergreen ILS
More information about the open-ils-commits
mailing list