]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/eg2/src/app/share/grid/grid-body.component.ts
LP2042879 Shelving Location Groups Admin accessibility
[working/Evergreen.git] / Open-ILS / src / eg2 / src / app / share / grid / grid-body.component.ts
1 import {Component, Input, Host} from '@angular/core';
2 import {GridContext} from './grid';
3 import {GridComponent} from './grid.component';
4 import {NgbPopover} from '@ng-bootstrap/ng-bootstrap';
5
6 @Component({
7     selector: 'eg-grid-body',
8     templateUrl: './grid-body.component.html'
9 })
10
11 export class GridBodyComponent {
12
13     @Input() context: GridContext;
14
15     // Track the context menus so we can manually close them
16     // when another popover is opened.
17     contextMenus: NgbPopover[];
18
19     constructor(@Host() private grid: GridComponent) {
20         this.contextMenus = [];
21     }
22
23     // Not using @HostListener because it only works globally.
24     onGridKeyDown(evt: KeyboardEvent) {
25         switch (evt.key) {
26             case 'ArrowUp':
27                 if (evt.shiftKey) {
28                     // Extend selection up one row
29                     this.context.selectMultiRowsPrevious();
30                 } else {
31                     this.context.selectPreviousRow();
32                 }
33                 evt.stopPropagation();
34                 break;
35             case 'ArrowDown':
36                 if (evt.shiftKey) {
37                     // Extend selection down one row
38                     this.context.selectMultiRowsNext();
39                 } else {
40                     this.context.selectNextRow();
41                 }
42                 evt.stopPropagation();
43                 break;
44             case 'ArrowLeft':
45             case 'PageUp':
46                 this.context.toPrevPage()
47                     .then(ok => this.context.selectFirstRow(), err => {});
48                 evt.stopPropagation();
49                 break;
50             case 'ArrowRight':
51             case 'PageDown':
52                 this.context.toNextPage()
53                     .then(ok => this.context.selectFirstRow(), err => {});
54                 evt.stopPropagation();
55                 break;
56             case 'a':
57                 // control-a means select all visible rows.
58                 // For consistency, select all rows in the current page only.
59                 if (evt.ctrlKey) {
60                     this.context.rowSelector.clear();
61                     this.context.selectRowsInPage();
62                     evt.preventDefault();
63                 }
64                 break;
65
66             case 'Enter':
67                 if (this.context.lastSelectedIndex) {
68                     this.grid.onRowActivate.emit(
69                         this.context.getRowByIndex(
70                             this.context.lastSelectedIndex)
71                     );
72                 }
73                 evt.stopPropagation();
74                 break;
75         }
76     }
77
78     handleRowClick($event: any, row: any) {
79
80         if (this.context.disableSelect) {
81             // Avoid any appearance or click behavior when row
82             // selection is disabled.
83             return;
84         }
85
86         const index = this.context.getRowIndex(row);
87
88         if (this.context.disableMultiSelect) {
89             this.context.selectOneRow(index);
90         } else if ($event.ctrlKey || $event.metaKey /* mac command */) {
91             this.context.toggleSelectOneRow(index);
92
93         } else if ($event.shiftKey) {
94             this.context.selectRowRange(index);
95
96         } else {
97             this.context.selectOneRow(index);
98         }
99     }
100
101     onRowClick($event: any, row: any, idx: number) {
102         this.handleRowClick($event, row);
103         this.grid.onRowClick.emit(row);
104     }
105
106     onRowDblClick(row: any) {
107         this.grid.onRowActivate.emit(row);
108     }
109
110     // Apply row selection, track the new menu if needed,
111     // manually close any existing open menus, open selected menu.
112     onRowContextClick($event, row: any, contextMenu: NgbPopover) {
113         $event.preventDefault(); // prevent browser context menu
114
115         if (!this.context.rowIsSelected(row)) {
116             // If the focused row is not selected, select it.
117             // Otherwise, avoid modifying the row selection.
118             this.context.selectOneRow(this.context.getRowIndex(row));
119         }
120
121         const existing = this.contextMenus.filter(m => m === contextMenu)[0];
122         if (!existing) {
123             this.contextMenus.push(contextMenu);
124         }
125
126         // Force any previously opened menus to close, which does
127         // not naturally occur via context-click.
128         this.contextMenus.forEach(m => m.close());
129
130         contextMenu.open({gridContext: this.context});
131     }
132 }
133