LP1803787 Grid context retains selection; lint user/berick/lp1803787-ang-grid-context-menu-3.2
authorBill Erickson <berickxx@gmail.com>
Wed, 6 Mar 2019 19:28:44 +0000 (14:28 -0500)
committerBill Erickson <berickxx@gmail.com>
Wed, 6 Mar 2019 20:41:45 +0000 (15:41 -0500)
During right-click (context-menu click) if the currently focused row is
already selected, avoid modifying the selection.  If it's not, then
select the focused row only.

Minor lint, etc. repairs.

Signed-off-by: Bill Erickson <berickxx@gmail.com>
Open-ILS/src/eg2/src/app/share/grid/grid-body.component.ts
Open-ILS/src/eg2/src/app/share/grid/grid-toolbar.component.html
Open-ILS/src/eg2/src/app/share/grid/grid.ts

index 0486b88..a43b358 100644 (file)
@@ -13,7 +13,7 @@ export class GridBodyComponent implements OnInit {
 
     @Input() context: GridContext;
 
-    // Track the context menus so we can manually close them 
+    // Track the context menus so we can manually close them
     // when another popover is opened.
     contextMenus: NgbPopover[];
 
@@ -57,13 +57,6 @@ export class GridBodyComponent implements OnInit {
     }
 
     handleRowClick($event: any, row: any) {
-
-        if (this.context.disableSelect) {
-            // Avoid any appearance or click behavior when row
-            // selection is disabled.
-            return;
-        }
-
         const index = this.context.getRowIndex(row);
 
         if (this.context.disableMultiSelect) {
@@ -94,7 +87,7 @@ export class GridBodyComponent implements OnInit {
         action.action(this.context.getSelectedRows());
     }
 
-    // Apply row selection, track the new menu if needed, 
+    // Apply row selection, track the new menu if needed,
     // manually close any existing open menus, open selected menu.
     onRowContextClick($event, row: any, contextMenu: NgbPopover) {
         $event.preventDefault(); // prevent browser context menu
@@ -104,14 +97,18 @@ export class GridBodyComponent implements OnInit {
             return;
         }
 
-        this.handleRowClick($event, row);
+        if (!this.context.rowIsSelected(row)) {
+            // If the focused row is not selected, select it.
+            // Otherwise, avoid modifying the row selection.
+            this.context.selectOneRow(this.context.getRowIndex(row));
+        }
 
         const existing = this.contextMenus.filter(m => m === contextMenu)[0];
         if (!existing) {
             this.contextMenus.push(contextMenu);
         }
 
-        // Force any previously opened menus to close, which does 
+        // Force any previously opened menus to close, which does
         // not naturally occur via context-click.
         this.contextMenus.forEach(m => m.close());
 
index 11a4c87..9d61b2a 100644 (file)
@@ -5,7 +5,7 @@
 
     <!-- buttons -->
     <div class="btn-grp" *ngIf="gridContext.toolbarButtons.length">
-      <button *ngFor="let btn of gridContext.toolbarButtons" 
+      <button *ngFor="let btn of gridContext.toolbarButtons"
         [disabled]="btn.disabled"
         class="btn btn-outline-dark mr-1" (click)="btn.action()">
         {{btn.label}}
     </div>
 
     <!-- checkboxes -->
-    <div class="form-check form-check-inline" 
+    <div class="form-check form-check-inline"
       *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"
             (click)="cb.onChange($event.target.checked)"/>
             {{cb.label}}
         </label>
@@ -31,7 +31,7 @@
   <div ngbDropdown class="mr-1" placement="bottom-right">
     <button ngbDropdownToggle [disabled]="!gridContext.toolbarActions.length"
         class="btn btn-outline-dark no-dropdown-caret">
-      <span title="Actions For Selected Rows" i18n-title 
+      <span title="Actions For Selected Rows" i18n-title
         class="material-icons mat-icon-in-button">playlist_add_check</span>
     </button>
     <div class="dropdown-menu" ngbDropdownMenu>
           <div class="dropdown-divider"></div>
         </ng-container>
         <ng-container *ngIf="!action.separator">
-          <a class="dropdown-item" (click)="performAction(action)"
+          <button class="dropdown-item" (click)="performAction(action)"
             [disabled]="shouldDisableAction(action)">
             <span class="ml-2">{{action.label}}</span>
-          </a>
+          </button>
         </ng-container>
       </ng-container>
     </div>
   </div>
 
-  <button [disabled]="gridContext.pager.isFirstPage()" type="button" 
+  <button [disabled]="gridContext.pager.isFirstPage()" type="button"
     class="btn btn-outline-dark mr-1" (click)="gridContext.pager.toFirst()">
-    <span title="First Page" i18n-title 
+    <span title="First Page" i18n-title
         class="material-icons mat-icon-in-button">first_page</span>
   </button>
-  <button [disabled]="gridContext.pager.isFirstPage()" type="button" 
+  <button [disabled]="gridContext.pager.isFirstPage()" type="button"
     class="btn btn-outline-dark mr-1" (click)="gridContext.pager.decrement()">
-    <span title="Previous Page" i18n-title 
+    <span title="Previous Page" i18n-title
         class="material-icons mat-icon-in-button">keyboard_arrow_left</span>
   </button>
-  <button [disabled]="gridContext.pager.isLastPage()" type="button" 
+  <button [disabled]="gridContext.pager.isLastPage()" type="button"
     class="btn btn-outline-dark mr-1" (click)="gridContext.pager.increment()">
-    <span title="Next Page" i18n-title 
+    <span title="Next Page" i18n-title
         class="material-icons mat-icon-in-button">keyboard_arrow_right</span>
   </button>
 
   <!--
   Hiding jump-to-last since there's no analog in the angularjs grid and
   it has limited value since the size of the data set is often unknown.
-  <button [disabled]="!gridContext.pager.resultCount || gridContext.pager.isLastPage()" 
+  <button [disabled]="!gridContext.pager.resultCount || gridContext.pager.isLastPage()"
     type="button" class="btn btn-outline-dark mr-1" (click)="gridContext.pager.toLast()">
-    <span title="First Page" i18n-title 
+    <span title="First Page" i18n-title
         class="material-icons mat-icon-in-button">last_page</span>
   </button>
   -->
@@ -82,7 +82,7 @@
       </span>
     </button>
     <div class="dropdown-menu" ngbDropdownMenu>
-      <a class="dropdown-item" 
+      <a class="dropdown-item"
         *ngFor="let count of [5, 10, 25, 50, 100]"
         (click)="gridContext.pager.setLimit(count)">
         <span class="ml-2">{{count}}</span>
     </div>
   </div>
 
-  <button type="button" 
-    class="btn btn-outline-dark mr-1" 
+  <button type="button"
+    class="btn btn-outline-dark mr-1"
     (click)="gridContext.overflowCells=!gridContext.overflowCells">
     <span *ngIf="!gridContext.overflowCells"
-      title="Expand Cells Vertically" i18n-title 
+      title="Expand Cells Vertically" i18n-title
       class="material-icons mat-icon-in-button">expand_more</span>
     <span *ngIf="gridContext.overflowCells"
-      title="Collaps Cells Vertically" i18n-title 
+      title="Collaps Cells Vertically" i18n-title
       class="material-icons mat-icon-in-button">expand_less</span>
   </button>
 
   </eg-grid-column-config>
   <div ngbDropdown placement="bottom-right">
     <button ngbDropdownToggle class="btn btn-outline-dark no-dropdown-caret">
-      <span title="Show Grid Options" i18n-title 
+      <span title="Show Grid Options" i18n-title
         class="material-icons mat-icon-in-button">settings</span>
     </button>
     <div class="dropdown-menu" ngbDropdownMenu>
-      <a class="dropdown-item label-with-material-icon" 
+      <a class="dropdown-item label-with-material-icon"
         (click)="columnConfDialog.open({size:'lg'})">
         <span class="material-icons">build</span>
         <span class="ml-2" i18n>Manage Columns</span>
       </a>
-      <a class="dropdown-item label-with-material-icon" 
+      <a class="dropdown-item label-with-material-icon"
         (click)="colWidthConfig.isVisible = !colWidthConfig.isVisible">
         <span class="material-icons">compare_arrows</span>
         <span class="ml-2" i18n>Manage Column Widths</span>
       </a>
-      <a class="dropdown-item label-with-material-icon" 
+      <a class="dropdown-item label-with-material-icon"
         (click)="saveGridConfig()">
         <span class="material-icons">save</span>
         <span class="ml-2" i18n>Save Grid Settings</span>
       </a>
-      <a class="dropdown-item label-with-material-icon" 
+      <a class="dropdown-item label-with-material-icon"
         (click)="gridContext.columnSet.reset()">
         <span class="material-icons">restore</span>
         <span class="ml-2" i18n>Reset Columns</span>
       </a>
-      <a class="dropdown-item label-with-material-icon" 
+      <a class="dropdown-item label-with-material-icon"
         (click)="generateCsvExportUrl($event)"
         [download]="csvExportFileName"
         [href]="csvExportUrl">
 
       <div class="dropdown-divider"></div>
 
-      <a class="dropdown-item label-with-material-icon" 
+      <a class="dropdown-item label-with-material-icon"
         (click)="col.visible=!col.visible" *ngFor="let col of gridContext.columnSet.columns">
         <span *ngIf="col.visible" class="badge badge-success">&#x2713;</span>
         <span *ngIf="!col.visible" class="badge badge-warning">&#x2717;</span>
index 1c575be..387dd2d 100644 (file)
@@ -620,6 +620,13 @@ export class GridContext {
         return selected;
     }
 
+    rowIsSelected(row: any): boolean {
+        const index = this.getRowIndex(row);
+        return this.rowSelector.selected().filter(
+            idx => idx === index
+        ).length > 0;
+    }
+
     getRowColumnValue(row: any, col: GridColumn): string {
         let val;
         if (col.name in row) {