LP1803787 Grid toolbar actions menu component; cleanup
authorBill Erickson <berickxx@gmail.com>
Thu, 9 May 2019 15:50:19 +0000 (11:50 -0400)
committerJane Sandberg <sandbej@linnbenton.edu>
Mon, 17 Jun 2019 21:21:17 +0000 (14:21 -0700)
Moves the guts of the grid toolbar actions menu (the buttons) to a
dedicated component that can be shared by both the actions drop-down
menu and the actions popover.  This adds support for honoring
disableOnRow for the popover actions. And avoids duplication.

Adds a sandbox example of using the toolbar action click event and
divider.

Some minor code cleanup/consistency changes.

Signed-off-by: Bill Erickson <berickxx@gmail.com>
Signed-off-by: Jane Sandberg <sandbej@linnbenton.edu>

Open-ILS/src/eg2/src/app/share/grid/grid-body.component.html
Open-ILS/src/eg2/src/app/share/grid/grid-body.component.ts
Open-ILS/src/eg2/src/app/share/grid/grid-toolbar-action.component.ts
Open-ILS/src/eg2/src/app/share/grid/grid-toolbar-actions-menu.component.html [new file with mode: 0644]
Open-ILS/src/eg2/src/app/share/grid/grid-toolbar-actions-menu.component.ts [new file with mode: 0644]
Open-ILS/src/eg2/src/app/share/grid/grid-toolbar.component.html
Open-ILS/src/eg2/src/app/share/grid/grid-toolbar.component.ts
Open-ILS/src/eg2/src/app/share/grid/grid.module.ts
Open-ILS/src/eg2/src/app/share/grid/grid.ts
Open-ILS/src/eg2/src/app/staff/sandbox/sandbox.component.html
Open-ILS/src/eg2/src/app/staff/sandbox/sandbox.component.ts

index 616b6d2..b83c619 100644 (file)
@@ -1,15 +1,7 @@
 <!-- uses dropdown menu CSS for easy stying, but it's not a dropdown -->
 <ng-template #contextMenu let-gridContext="gridContext">
-  <ng-container *ngFor="let action of gridContext.toolbarActions">
-    <ng-container *ngIf="action.separator">
-      <div class="dropdown-divider"></div>
-    </ng-container>
-    <ng-container *ngIf="!action.separator">
-      <a class="dropdown-item" (click)="performAction(action)">
-        <span class="ml-2">{{action.label}}</span>
-      </a>
-    </ng-container>
-  </ng-container>
+  <eg-grid-toolbar-actions-menu [gridContext]="gridContext">
+  </eg-grid-toolbar-actions-menu>
 </ng-template>
 
 <!--
index 6a95b35..3869ea4 100644 (file)
@@ -91,9 +91,7 @@ export class GridBodyComponent implements OnInit {
         if (this.context.disableMultiSelect) {
             this.context.selectOneRow(index);
         } else if ($event.ctrlKey || $event.metaKey /* mac command */) {
-            if (this.context.toggleSelectOneRow(index)) {
-                this.context.lastSelectedIndex = index;
-            }
+            this.context.toggleSelectOneRow(index);
 
         } else if ($event.shiftKey) {
             // TODO shift range click
@@ -112,10 +110,6 @@ export class GridBodyComponent implements OnInit {
         this.grid.onRowActivate.emit(row);
     }
 
-    performAction(action: GridToolbarAction) {
-        action.action(this.context.getSelectedRows());
-    }
-
     // Apply row selection, track the new menu if needed,
     // manually close any existing open menus, open selected menu.
     onRowContextClick($event, row: any, contextMenu: NgbPopover) {
index 7901035..6982525 100644 (file)
@@ -36,7 +36,7 @@ export class GridToolbarActionComponent implements OnInit {
     @Input() disableOnRows: (rows: any[]) => boolean;
 
     // If true, render a separator bar only, no action link.
-    @Input() separator: boolean;
+    @Input() isSeparator: boolean;
 
     // get a reference to our container grid.
     constructor(@Host() private grid: GridComponent) {
@@ -60,6 +60,7 @@ export class GridToolbarActionComponent implements OnInit {
         this.toolbarAction.group = this.group;
         this.toolbarAction.action = this.action;
         this.toolbarAction.disabled = this.disabled;
+        this.toolbarAction.isSeparator = this.isSeparator;
         this.toolbarAction.disableOnRows = this.disableOnRows;
         this.grid.context.toolbarActions.push(this.toolbarAction);
     }
diff --git a/Open-ILS/src/eg2/src/app/share/grid/grid-toolbar-actions-menu.component.html b/Open-ILS/src/eg2/src/app/share/grid/grid-toolbar-actions-menu.component.html
new file mode 100644 (file)
index 0000000..cdb6dc4
--- /dev/null
@@ -0,0 +1,15 @@
+<button class="dropdown-item scrollable-menu" 
+  [disabled]="shouldDisable(action)"
+  (click)="performAction(action)"
+  *ngFor="let action of gridContext.toolbarActions">
+  <ng-container *ngIf="action.isGroup">
+    <span class="font-weight-bold font-italic">{{action.label}}</span>
+  </ng-container>
+  <ng-container *ngIf="action.isSeparator">
+    <div class="dropdown-divider"></div>
+  </ng-container>
+  <ng-container *ngIf="!action.isGroup && !action.isSeparator">
+    <!-- grouped entries are left paddded for group indentation -->        
+    <span [ngClass]="{'ml-2': action.group}">{{action.label}}</span>
+  </ng-container>
+</button>
diff --git a/Open-ILS/src/eg2/src/app/share/grid/grid-toolbar-actions-menu.component.ts b/Open-ILS/src/eg2/src/app/share/grid/grid-toolbar-actions-menu.component.ts
new file mode 100644 (file)
index 0000000..2d8cffd
--- /dev/null
@@ -0,0 +1,31 @@
+import {Component, Input, OnInit, Host} from '@angular/core';
+import {GridToolbarAction, GridContext} from '@eg/share/grid/grid';
+
+/** Models a list of toolbar action menu entries */
+
+@Component({
+  selector: 'eg-grid-toolbar-actions-menu',
+  templateUrl: 'grid-toolbar-actions-menu.component.html'
+})
+
+export class GridToolbarActionsMenuComponent {
+
+    @Input() gridContext: GridContext;
+
+    performAction(action: GridToolbarAction) {
+        if (action.isGroup || action.isSeparator) {
+            return; // These don't perform actions
+        }
+        const rows = this.gridContext.getSelectedRows();
+        action.onClick.emit(rows);
+        if (action.action) { action.action(rows); }
+    }
+
+    shouldDisable(action: GridToolbarAction): boolean {
+        if (action.disableOnRows) {
+            return action.disableOnRows(this.gridContext.getSelectedRows());
+        }
+        return false;
+    }
+}
+
index 036597d..6be9208 100644 (file)
       <span title="Actions For Selected Rows" i18n-title
         class="material-icons mat-icon-in-button">playlist_add_check</span>
     </button>
-    <div class="dropdown-menu scrollable-menu" ngbDropdownMenu>
-      <button class="dropdown-item" (click)="performAction(action)"
-        *ngFor="let action of gridContext.toolbarActions"
-        [disabled]="shouldDisableAction(action)">
-        <ng-container *ngIf="action.isGroup">
-          <span class="ml-2 font-weight-bold font-italic">{{action.label}}</span>
-        </ng-container>
-        <ng-container *ngIf="action.separator">
-          <div class="dropdown-divider"></div>
-        </ng-container>
-        <ng-container 
-          *ngIf="!action.group && !action.isGroup && !action.separator">
-          <span class="ml-2">{{action.label}}</span>
-        </ng-container>
-      </button>
+    <div class="dropdown-menu" ngbDropdownMenu>
+      <eg-grid-toolbar-actions-menu [gridContext]="gridContext">
+      </eg-grid-toolbar-actions-menu>
     </div>
   </div>
 
index a05aaa5..308fdd0 100644 (file)
@@ -77,28 +77,12 @@ export class GridToolbarComponent implements OnInit {
         );
     }
 
-    performAction(action: GridToolbarAction) {
-        if (action.isGroup || action.separator) {
-            return; // These don't perform actions
-        }
-        const rows = this.gridContext.getSelectedRows();
-        action.onClick.emit(rows);
-        if (action.action) { action.action(rows); }
-    }
-
     performButtonAction(button: GridToolbarButton) {
         const rows = this.gridContext.getSelectedRows();
         button.onClick.emit();
         if (button.action) { button.action(); }
     }
 
-    shouldDisableAction(action: GridToolbarAction) {
-        if (action.disableOnRows) {
-            return action.disableOnRows(this.gridContext.getSelectedRows());
-        }
-        return false;
-    }
-
     printHtml() {
         this.gridPrinter.printGrid();
     }
index 0773a7e..454dcfb 100644 (file)
@@ -9,6 +9,7 @@ import {GridToolbarComponent} from './grid-toolbar.component';
 import {GridToolbarButtonComponent} from './grid-toolbar-button.component';
 import {GridToolbarCheckboxComponent} from './grid-toolbar-checkbox.component';
 import {GridToolbarActionComponent} from './grid-toolbar-action.component';
+import {GridToolbarActionsMenuComponent} from './grid-toolbar-actions-menu.component';
 import {GridColumnConfigComponent} from './grid-column-config.component';
 import {GridColumnWidthComponent} from './grid-column-width.component';
 import {GridPrintComponent} from './grid-print.component';
@@ -26,6 +27,7 @@ import {GridPrintComponent} from './grid-print.component';
         GridToolbarButtonComponent,
         GridToolbarCheckboxComponent,
         GridToolbarActionComponent,
+        GridToolbarActionsMenuComponent,
         GridColumnConfigComponent,
         GridColumnWidthComponent,
         GridPrintComponent
index cfed24e..ae68169 100644 (file)
@@ -770,6 +770,7 @@ export class GridContext {
         }
 
         this.rowSelector.select(index);
+        this.lastSelectedIndex = index;
         return true;
     }
 
@@ -1035,7 +1036,7 @@ export class GridToolbarAction {
     group: string;
     disabled: boolean;
     isGroup: boolean; // used for group placeholder entries
-    separator: boolean;
+    isSeparator: boolean;
     disableOnRows: (rows: any[]) => boolean;
 }
 
index 7406c1f..720fa0f 100644 (file)
   <eg-grid-toolbar-action label="Action that needs a single row" i18n-label
     [action]="complimentEvergreen" [disableOnRows]="notOneSelectedRow">
   </eg-grid-toolbar-action>
+  <eg-grid-toolbar-action [isSeparator]="true">
+  </eg-grid-toolbar-action>
+  <eg-grid-toolbar-action label="Another Action" i18n-label
+    (actionClick)="complimentEvergreen2($event)">
+  </eg-grid-toolbar-action>
   <eg-grid-column name="test" [cellTemplate]="cellTmpl" 
     [cellContext]="btGridTestContext" [sortable]="false">
   </eg-grid-column>
index 4dd8892..6d4e2ea 100644 (file)
@@ -152,6 +152,11 @@ export class SandboxComponent implements OnInit {
         this.sbChannel.postMessage({msg : $event.target.value});
     }
 
+    // Example of click handler for row action
+    complimentEvergreen2(rows: IdlObject[]) {
+        alert('I know, right?');
+    }
+
     openEditor() {
         this.fmRecordEditor.open({size: 'lg'}).then(
             ok => { console.debug(ok); },