[open-ils-commits] [GIT] Evergreen ILS branch rel_3_3 updated. 70ab7d828bc23138a595e68d770b722141d38b7c

Evergreen Git git at git.evergreen-ils.org
Mon Jun 17 17:51:08 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  70ab7d828bc23138a595e68d770b722141d38b7c (commit)
       via  a296fb34520fa13e71e27daa78b732fd8ec6e51d (commit)
       via  0acee59d8e4994193d99e530cc840ac795fb43b5 (commit)
       via  b3cb3f7f7b5e239e04754ae3dc2d1f35557cb70e (commit)
       via  fc641deb9ebf56314acb0b49d993011e32334e4c (commit)
       via  7ef2ae530a54482e3ebf38e2b96ddb601449e130 (commit)
       via  6136a31d4d145182bea6947315d62c6fb41c3bca (commit)
       via  110c8571bb4d70ec02e90c1486088443dee4ecbe (commit)
      from  cfb2135032aa78aad76c394e50fdcb6ed76df709 (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 70ab7d828bc23138a595e68d770b722141d38b7c
Author: Jane Sandberg <sandbej at linnbenton.edu>
Date:   Sun Jun 9 17:46:15 2019 -0700

    LP1803787 (follow-up) removing unnecessary arguments
    
    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/staff/share/admin-page/admin-page.component.html b/Open-ILS/src/eg2/src/app/staff/share/admin-page/admin-page.component.html
index 8d67f2edc1..855f196e51 100644
--- a/Open-ILS/src/eg2/src/app/staff/share/admin-page/admin-page.component.html
+++ b/Open-ILS/src/eg2/src/app/staff/share/admin-page/admin-page.component.html
@@ -51,10 +51,10 @@
 <eg-grid #grid idlClass="{{idlClass}}" [dataSource]="dataSource" 
     [sortable]="true" persistKey="{{persistKey}}" [showLinkSelectors]="true">
   <eg-grid-toolbar-button [disabled]="!canCreate" 
-    label="New {{idlClassDef.label}}" i18n-label (onClick)="createNew($event)">
+    label="New {{idlClassDef.label}}" i18n-label (onClick)="createNew()">
   </eg-grid-toolbar-button>
   <eg-grid-toolbar-button [disabled]="translatableFields.length == 0" 
-    label="Apply Translations" i18n-label (onClick)="translate($event)">
+    label="Apply Translations" i18n-label (onClick)="translate()">
   </eg-grid-toolbar-button>
   <eg-grid-toolbar-action label="Edit Selected" i18n-label (onClick)="editSelected($event)">
   </eg-grid-toolbar-action>

commit a296fb34520fa13e71e27daa78b732fd8ec6e51d
Author: Bill Erickson <berickxx at gmail.com>
Date:   Fri May 31 11:47:03 2019 -0400

    LP1803787 Migrate grid action/button click handlers; lint
    
    Migrate the basic admin page and sandbox grids to use the click handlers
    for grid toolbar buttons and actions, so the actions may be performed
    against class methods instead of anonymous functions.
    
    Minor lint repairs.
    
    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/print/hatch.service.ts b/Open-ILS/src/eg2/src/app/share/print/hatch.service.ts
index 015088765a..bd087b7747 100644
--- a/Open-ILS/src/eg2/src/app/share/print/hatch.service.ts
+++ b/Open-ILS/src/eg2/src/app/share/print/hatch.service.ts
@@ -27,7 +27,7 @@ export class HatchService {
 
     isAvailable: boolean;
     msgId: number;
-    messages: {[msgid:number]: HatchMessage};
+    messages: {[msgid: number]: HatchMessage};
 
     constructor() {
         this.isAvailable = null;
@@ -62,7 +62,7 @@ export class HatchService {
 
                 this.handleResponse(event.data);
             }
-        }); 
+        });
 
         return this.isAvailable = true;
     }
@@ -87,7 +87,7 @@ export class HatchService {
     // Handle the data sent back to the browser from Hatch.
     handleResponse(data: any) {
 
-        const msg = this.messages[data.msgid]; 
+        const msg = this.messages[data.msgid];
         if (!msg) {
             console.warn(`No Hatch request found with ID ${data.msgid}`);
             return;
diff --git a/Open-ILS/src/eg2/src/app/staff/sandbox/sandbox.component.html b/Open-ILS/src/eg2/src/app/staff/sandbox/sandbox.component.html
index 95c378a377..bed0c825fd 100644
--- a/Open-ILS/src/eg2/src/app/staff/sandbox/sandbox.component.html
+++ b/Open-ILS/src/eg2/src/app/staff/sandbox/sandbox.component.html
@@ -139,12 +139,12 @@
   [cellClassCallback]="btGridCellClassCallback"
   [sortable]="true">
   <eg-grid-toolbar-action label="Action that needs a single row" i18n-label
-    [action]="complimentEvergreen" [disableOnRows]="notOneSelectedRow">
+    (onClick)="complimentEvergreen($event)" [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)">
+    (onClick)="complimentEvergreen2($event)">
   </eg-grid-toolbar-action>
   <eg-grid-column name="test" [cellTemplate]="cellTmpl" 
     [cellContext]="btGridTestContext" [sortable]="false">
diff --git a/Open-ILS/src/eg2/src/app/staff/share/admin-page/admin-page.component.html b/Open-ILS/src/eg2/src/app/staff/share/admin-page/admin-page.component.html
index 7a47a3d424..8d67f2edc1 100644
--- a/Open-ILS/src/eg2/src/app/staff/share/admin-page/admin-page.component.html
+++ b/Open-ILS/src/eg2/src/app/staff/share/admin-page/admin-page.component.html
@@ -51,14 +51,14 @@
 <eg-grid #grid idlClass="{{idlClass}}" [dataSource]="dataSource" 
     [sortable]="true" persistKey="{{persistKey}}" [showLinkSelectors]="true">
   <eg-grid-toolbar-button [disabled]="!canCreate" 
-    label="New {{idlClassDef.label}}" i18n-label [action]="createNew">
+    label="New {{idlClassDef.label}}" i18n-label (onClick)="createNew($event)">
   </eg-grid-toolbar-button>
   <eg-grid-toolbar-button [disabled]="translatableFields.length == 0" 
-    label="Apply Translations" i18n-label [action]="translate">
+    label="Apply Translations" i18n-label (onClick)="translate($event)">
   </eg-grid-toolbar-button>
-  <eg-grid-toolbar-action label="Edit Selected" i18n-label [action]="editSelected">
+  <eg-grid-toolbar-action label="Edit Selected" i18n-label (onClick)="editSelected($event)">
   </eg-grid-toolbar-action>
-  <eg-grid-toolbar-action label="Delete Selected" i18n-label [action]="deleteSelected">
+  <eg-grid-toolbar-action label="Delete Selected" i18n-label (onClick)="deleteSelected($event)">
   </eg-grid-toolbar-action>
 </eg-grid>
 
diff --git a/Open-ILS/src/eg2/src/app/staff/share/admin-page/admin-page.component.ts b/Open-ILS/src/eg2/src/app/staff/share/admin-page/admin-page.component.ts
index 106f3640b2..509f95cce6 100644
--- a/Open-ILS/src/eg2/src/app/staff/share/admin-page/admin-page.component.ts
+++ b/Open-ILS/src/eg2/src/app/staff/share/admin-page/admin-page.component.ts
@@ -76,15 +76,11 @@ export class AdminPageComponent implements OnInit {
 
     idlClassDef: any;
     pkeyField: string;
-    createNew: () => void;
-    deleteSelected: (rows: IdlObject[]) => void;
-    editSelected: (rows: IdlObject[]) => void;
 
     // True if any columns on the object support translations
     translateRowIdx: number;
     translateFieldIdx: number;
     translatableFields: string[];
-    translate: () => void;
 
     contextOrg: IdlObject;
     orgFieldLabel: string;
@@ -175,93 +171,6 @@ export class AdminPageComponent implements OnInit {
         this.grid.onRowActivate.subscribe(
             (idlThing: IdlObject) => this.showEditDialog(idlThing)
         );
-
-        this.editSelected = (idlThings: IdlObject[]) => {
-
-            // Edit each IDL thing one at a time
-            const editOneThing = (thing: IdlObject) => {
-                if (!thing) { return; }
-
-                this.showEditDialog(thing).then(
-                    () => editOneThing(idlThings.shift()));
-            };
-
-            editOneThing(idlThings.shift());
-        };
-
-        this.createNew = () => {
-            this.editDialog.mode = 'create';
-            // We reuse the same editor for all actions.  Be sure
-            // create action does not try to modify an existing record.
-            this.editDialog.recId = null;
-            this.editDialog.record = null;
-            this.editDialog.open({size: this.dialogSize}).then(
-                ok => {
-                    this.createString.current()
-                        .then(str => this.toast.success(str));
-                    this.grid.reload();
-                },
-                rejection => {
-                    if (!rejection.dismissed) {
-                        this.createErrString.current()
-                            .then(str => this.toast.danger(str));
-                    }
-                }
-            );
-        };
-
-        this.deleteSelected = (idlThings: IdlObject[]) => {
-            idlThings.forEach(idlThing => idlThing.isdeleted(true));
-            this.pcrud.autoApply(idlThings).subscribe(
-                val => console.debug('deleted: ' + val),
-                err => {},
-                ()  => this.grid.reload()
-            );
-        };
-
-        // Open the field translation dialog.
-        // Link the next/previous actions to cycle through each translatable
-        // field on each row.
-        this.translate = () => {
-            this.translateRowIdx = 0;
-            this.translateFieldIdx = 0;
-            this.translator.fieldName = this.translatableFields[this.translateFieldIdx];
-            this.translator.idlObject = this.dataSource.data[this.translateRowIdx];
-
-            this.translator.nextString = () => {
-
-                if (this.translateFieldIdx < this.translatableFields.length - 1) {
-                    this.translateFieldIdx++;
-
-                } else if (this.translateRowIdx < this.dataSource.data.length - 1) {
-                    this.translateRowIdx++;
-                    this.translateFieldIdx = 0;
-                }
-
-                this.translator.idlObject =
-                    this.dataSource.data[this.translateRowIdx];
-                this.translator.fieldName =
-                    this.translatableFields[this.translateFieldIdx];
-            };
-
-            this.translator.prevString = () => {
-
-                if (this.translateFieldIdx > 0) {
-                    this.translateFieldIdx--;
-
-                } else if (this.translateRowIdx > 0) {
-                    this.translateRowIdx--;
-                    this.translateFieldIdx = 0;
-                }
-
-                this.translator.idlObject =
-                    this.dataSource.data[this.translateRowIdx];
-                this.translator.fieldName =
-                    this.translatableFields[this.translateFieldIdx];
-            };
-
-            this.translator.open({size: 'lg'});
-        };
     }
 
     checkCreatePerms() {
@@ -371,6 +280,91 @@ export class AdminPageComponent implements OnInit {
         );
     }
 
+    editSelected(idlThings: IdlObject[]) {
+
+        // Edit each IDL thing one at a time
+        const editOneThing = (thing: IdlObject) => {
+            if (!thing) { return; }
+
+            this.showEditDialog(thing).then(
+                () => editOneThing(idlThings.shift()));
+        };
+
+        editOneThing(idlThings.shift());
+    }
+
+    deleteSelected(idlThings: IdlObject[]) {
+        idlThings.forEach(idlThing => idlThing.isdeleted(true));
+        this.pcrud.autoApply(idlThings).subscribe(
+            val => console.debug('deleted: ' + val),
+            err => {},
+            ()  => this.grid.reload()
+        );
+    }
+
+    createNew() {
+        this.editDialog.mode = 'create';
+        // We reuse the same editor for all actions.  Be sure
+        // create action does not try to modify an existing record.
+        this.editDialog.recId = null;
+        this.editDialog.record = null;
+        this.editDialog.open({size: this.dialogSize}).then(
+            ok => {
+                this.createString.current()
+                    .then(str => this.toast.success(str));
+                this.grid.reload();
+            },
+            rejection => {
+                if (!rejection.dismissed) {
+                    this.createErrString.current()
+                        .then(str => this.toast.danger(str));
+                }
+            }
+        );
+    }
+    // Open the field translation dialog.
+    // Link the next/previous actions to cycle through each translatable
+    // field on each row.
+    translate() {
+        this.translateRowIdx = 0;
+        this.translateFieldIdx = 0;
+        this.translator.fieldName = this.translatableFields[this.translateFieldIdx];
+        this.translator.idlObject = this.dataSource.data[this.translateRowIdx];
+
+        this.translator.nextString = () => {
+
+            if (this.translateFieldIdx < this.translatableFields.length - 1) {
+                this.translateFieldIdx++;
+
+            } else if (this.translateRowIdx < this.dataSource.data.length - 1) {
+                this.translateRowIdx++;
+                this.translateFieldIdx = 0;
+            }
+
+            this.translator.idlObject =
+                this.dataSource.data[this.translateRowIdx];
+            this.translator.fieldName =
+                this.translatableFields[this.translateFieldIdx];
+        };
+
+        this.translator.prevString = () => {
+
+            if (this.translateFieldIdx > 0) {
+                this.translateFieldIdx--;
+
+            } else if (this.translateRowIdx > 0) {
+                this.translateRowIdx--;
+                this.translateFieldIdx = 0;
+            }
+
+            this.translator.idlObject =
+                this.dataSource.data[this.translateRowIdx];
+            this.translator.fieldName =
+                this.translatableFields[this.translateFieldIdx];
+        };
+
+        this.translator.open({size: 'lg'});
+    }
 }
 
 
diff --git a/Open-ILS/src/eg2/src/app/staff/staff.component.ts b/Open-ILS/src/eg2/src/app/staff/staff.component.ts
index dc58de1030..952a46852d 100644
--- a/Open-ILS/src/eg2/src/app/staff/staff.component.ts
+++ b/Open-ILS/src/eg2/src/app/staff/staff.component.ts
@@ -110,7 +110,7 @@ export class StaffComponent implements OnInit {
      * Make sure to fire the contextmenu Event on Shift+F10
      */
     fireContextMenuEvent(): void {
-        let event = new MouseEvent("contextmenu", {
+        const event = new MouseEvent('contextmenu', {
             bubbles: true,
             cancelable: false,
             view: window,
@@ -118,9 +118,7 @@ export class StaffComponent implements OnInit {
             buttons: 0,
         });
         document.activeElement.dispatchEvent(event);
-    };
-
-
+    }
 
     /*
     @ViewChild('egAccessKeyInfo')

commit 0acee59d8e4994193d99e530cc840ac795fb43b5
Author: Bill Erickson <berickxx at gmail.com>
Date:   Fri May 31 11:45:52 2019 -0400

    LP1803787 Grid actions menu tabindex
    
    Allow the browser to focus the actions menu entries on tab so 'Enter'
    action will not inadvertantly fire the row activate handler as well.
    
    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-toolbar-actions-menu.component.html b/Open-ILS/src/eg2/src/app/share/grid/grid-toolbar-actions-menu.component.html
index cdb6dc4fec..224128d310 100644
--- 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
@@ -1,7 +1,7 @@
 <button class="dropdown-item scrollable-menu" 
   [disabled]="shouldDisable(action)"
-  (click)="performAction(action)"
-  *ngFor="let action of gridContext.toolbarActions">
+  (click)="performAction(action)" tabindex="0"
+  *ngFor="let action of gridContext.toolbarActions; let idx = index">
   <ng-container *ngIf="action.isGroup">
     <span class="font-weight-bold font-italic">{{action.label}}</span>
   </ng-container>

commit b3cb3f7f7b5e239e04754ae3dc2d1f35557cb70e
Author: Jane Sandberg <sandbej at linnbenton.edu>
Date:   Fri May 17 12:31:56 2019 -0700

    LP1803787: Add keyboard support (Shift+F10)
    
    This allows a user to set focus to a row using a checkbox, then
    press the standard keyboard shortcut to open the row context menu.
    
    This commit sets the Shift+F10 keyboard combination to fire the
    contextmenu javascript event throughout the Angular staff client, so
    other interfaces that need to override the browser's context menu should
    be able to respond to Shift+F10.
    
    To test:
    
    1) Open an eg2 grid interface (Server Administration -> Authority
    Thesaurus is a good one).
    2) Use the tab key to set focus onto the checkbox for one of the rows.
    3) Note that pressing Shift + F10 opens the browser's context menu.
    4) Apply this commit
    5) Repeat steps 1+2
    6) Press Shift + F10.
    7) Note that the context menu opens, and that you can use Tab and
    Shift+Tab to move through the various actions.
    8) Note that you can press the Esc key to exit the context menu
    
    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-body.component.html b/Open-ILS/src/eg2/src/app/share/grid/grid-body.component.html
index b83c619044..9ab26cd32e 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
@@ -14,7 +14,13 @@
 
     <ng-container *ngIf="!context.disableSelect">
       <div class="eg-grid-cell eg-grid-checkbox-cell eg-grid-cell-skinny">
-        <input type='checkbox' [(ngModel)]="context.rowSelector.indexes[context.getRowIndex(row)]">
+        <input type='checkbox' [(ngModel)]="context.rowSelector.indexes[context.getRowIndex(row)]"
+          #rowContextMenu="ngbPopover"
+          popoverTitle="Actions for Selected Rows" i18n-popoverTitle
+          (contextmenu)="onRowContextClick($event, row, rowContextMenu)"
+          [ngbPopover]="contextMenu"
+          placement="right"
+          triggers="manual">
       </div>
     </ng-container>
     <div class="eg-grid-cell eg-grid-number-cell eg-grid-cell-skinny">
diff --git a/Open-ILS/src/eg2/src/app/staff/staff.component.html b/Open-ILS/src/eg2/src/app/staff/staff.component.html
index 2a2539c067..7afcc325a6 100644
--- a/Open-ILS/src/eg2/src/app/staff/staff.component.html
+++ b/Open-ILS/src/eg2/src/app/staff/staff.component.html
@@ -13,7 +13,11 @@
     keyDesc="Display AccessKey Info Dialog" i18n-keyDesc
     (click)="egAccessKeyInfo.open()">
 </a>
+<a egAccessKey keyCtx="base"
+    keySpec="shift+f10" i18n-keySpec
+    keyDesc="Display Context Menu" i18n-keyDesc
+    (click)="fireContextMenuEvent()">
+</a>
 
 <!-- global toast alerts -->
 <eg-toast></eg-toast>
-
diff --git a/Open-ILS/src/eg2/src/app/staff/staff.component.ts b/Open-ILS/src/eg2/src/app/staff/staff.component.ts
index 492b1df14d..dc58de1030 100644
--- a/Open-ILS/src/eg2/src/app/staff/staff.component.ts
+++ b/Open-ILS/src/eg2/src/app/staff/staff.component.ts
@@ -62,8 +62,6 @@ export class StaffComponent implements OnInit {
         this.route.data.subscribe((data: {staffResolver: any}) => {
             // Data fetched via StaffResolver is available here.
         });
-
-
     }
 
     /**
@@ -108,6 +106,22 @@ export class StaffComponent implements OnInit {
         this.keys.fire(evt);
     }
 
+    /**
+     * Make sure to fire the contextmenu Event on Shift+F10
+     */
+    fireContextMenuEvent(): void {
+        let event = new MouseEvent("contextmenu", {
+            bubbles: true,
+            cancelable: false,
+            view: window,
+            button: 2,
+            buttons: 0,
+        });
+        document.activeElement.dispatchEvent(event);
+    };
+
+
+
     /*
     @ViewChild('egAccessKeyInfo')
     private keyComponent: AccessKeyInfoComponent;
@@ -115,4 +129,3 @@ export class StaffComponent implements OnInit {
 
 }
 
-

commit fc641deb9ebf56314acb0b49d993011e32334e4c
Author: Bill Erickson <berickxx at gmail.com>
Date:   Thu May 9 11:50:19 2019 -0400

    LP1803787 Grid toolbar actions menu component; cleanup
    
    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 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 616b6d20e0..b83c619044 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
@@ -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>
 
 <!--
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 6a95b35d3d..3869ea4000 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
@@ -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) {
diff --git a/Open-ILS/src/eg2/src/app/share/grid/grid-toolbar-action.component.ts b/Open-ILS/src/eg2/src/app/share/grid/grid-toolbar-action.component.ts
index 7901035139..6982525527 100644
--- a/Open-ILS/src/eg2/src/app/share/grid/grid-toolbar-action.component.ts
+++ b/Open-ILS/src/eg2/src/app/share/grid/grid-toolbar-action.component.ts
@@ -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
index 0000000000..cdb6dc4fec
--- /dev/null
+++ b/Open-ILS/src/eg2/src/app/share/grid/grid-toolbar-actions-menu.component.html
@@ -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
index 0000000000..2d8cffd151
--- /dev/null
+++ b/Open-ILS/src/eg2/src/app/share/grid/grid-toolbar-actions-menu.component.ts
@@ -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 */
+
+ at 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;
+    }
+}
+
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 036597db97..6be92080a3 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
@@ -38,21 +38,9 @@
       <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>
 
diff --git a/Open-ILS/src/eg2/src/app/share/grid/grid-toolbar.component.ts b/Open-ILS/src/eg2/src/app/share/grid/grid-toolbar.component.ts
index a05aaa5ea2..308fdd012a 100644
--- a/Open-ILS/src/eg2/src/app/share/grid/grid-toolbar.component.ts
+++ b/Open-ILS/src/eg2/src/app/share/grid/grid-toolbar.component.ts
@@ -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();
     }
diff --git a/Open-ILS/src/eg2/src/app/share/grid/grid.module.ts b/Open-ILS/src/eg2/src/app/share/grid/grid.module.ts
index 0773a7e56f..454dcfb0ed 100644
--- a/Open-ILS/src/eg2/src/app/share/grid/grid.module.ts
+++ b/Open-ILS/src/eg2/src/app/share/grid/grid.module.ts
@@ -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
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 cfed24e7a0..ae681694d8 100644
--- a/Open-ILS/src/eg2/src/app/share/grid/grid.ts
+++ b/Open-ILS/src/eg2/src/app/share/grid/grid.ts
@@ -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;
 }
 
diff --git a/Open-ILS/src/eg2/src/app/staff/sandbox/sandbox.component.html b/Open-ILS/src/eg2/src/app/staff/sandbox/sandbox.component.html
index 54cd87d11e..95c378a377 100644
--- a/Open-ILS/src/eg2/src/app/staff/sandbox/sandbox.component.html
+++ b/Open-ILS/src/eg2/src/app/staff/sandbox/sandbox.component.html
@@ -141,6 +141,11 @@
   <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>
diff --git a/Open-ILS/src/eg2/src/app/staff/sandbox/sandbox.component.ts b/Open-ILS/src/eg2/src/app/staff/sandbox/sandbox.component.ts
index 543e3cb72b..f7de626f68 100644
--- a/Open-ILS/src/eg2/src/app/staff/sandbox/sandbox.component.ts
+++ b/Open-ILS/src/eg2/src/app/staff/sandbox/sandbox.component.ts
@@ -136,6 +136,11 @@ export class SandboxComponent implements OnInit {
         });
     }
 
+    // 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); },

commit 7ef2ae530a54482e3ebf38e2b96ddb601449e130
Author: Bill Erickson <berickxx at gmail.com>
Date:   Wed Mar 6 14:28:44 2019 -0500

    LP1803787 Grid context retains selection; lint
    
    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 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.ts b/Open-ILS/src/eg2/src/app/share/grid/grid-body.component.ts
index fb3cb742cc..6a95b35d3d 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
@@ -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[];
 
@@ -116,7 +116,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
@@ -126,14 +126,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());
 
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 a5aa235400..036597db97 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
@@ -48,10 +48,6 @@
         <ng-container *ngIf="action.separator">
           <div class="dropdown-divider"></div>
         </ng-container>
-        <ng-container *ngIf="action.group && !action.isGroup">
-          <!-- grouped entries are indented -->
-          <span class="ml-4">{{action.label}}</span>
-        </ng-container>
         <ng-container 
           *ngIf="!action.group && !action.isGroup && !action.separator">
           <span class="ml-2">{{action.label}}</span>
diff --git a/Open-ILS/src/eg2/src/app/share/grid/grid-toolbar.component.ts b/Open-ILS/src/eg2/src/app/share/grid/grid-toolbar.component.ts
index 82c199c36b..a05aaa5ea2 100644
--- a/Open-ILS/src/eg2/src/app/share/grid/grid-toolbar.component.ts
+++ b/Open-ILS/src/eg2/src/app/share/grid/grid-toolbar.component.ts
@@ -78,6 +78,9 @@ 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); }
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 ae611875c3..cfed24e7a0 100644
--- a/Open-ILS/src/eg2/src/app/share/grid/grid.ts
+++ b/Open-ILS/src/eg2/src/app/share/grid/grid.ts
@@ -651,6 +651,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;
 

commit 6136a31d4d145182bea6947315d62c6fb41c3bca
Author: Bill Erickson <berickxx at gmail.com>
Date:   Mon Nov 26 18:21:36 2018 +0000

    LP1803787 Grid actions context menu
    
    Display a context menu including the grid actions for selected rows
    links when right-clicking on a grid item.
    
    Note the popover displays oriented to the bottom of the item instead of
    the mouse click, which is not supported at time of dev.
    
    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 a9f35aaaa5..616b6d20e0 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
@@ -1,3 +1,17 @@
+<!-- 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>
+</ng-template>
+
 <!--
   tabindex=1 so the grid body can capture keyboard events.
 -->
@@ -27,11 +41,20 @@
         </ng-container>
       </ng-container>
     </div>
+    <!-- contextMenu applied to cells instead of rows so the position
+         of the popover is close to the mouse.  As of writing, no way
+         to position the popover at the mouse -->
     <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)"
+      #rowContextMenu="ngbPopover"
+      popoverTitle="Actions for Selected Rows" i18n-popoverTitle
+      (contextmenu)="onRowContextClick($event, row, rowContextMenu)"
+      [ngbPopover]="contextMenu"
+      placement="bottom"
+      triggers="manual"
       *ngFor="let col of context.columnSet.displayColumns()">
 
       <eg-grid-body-cell [context]="context" [row]="row" [column]="col">
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 9c9b19041c..fb3cb742cc 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
@@ -1,7 +1,8 @@
 import {Component, Input, OnInit, Host} from '@angular/core';
 import {GridContext, GridColumn, GridRowSelector,
-    GridColumnSet, GridDataSource} from './grid';
+    GridToolbarAction, GridColumnSet, GridDataSource} from './grid';
 import {GridComponent} from './grid.component';
+import {NgbPopover} from '@ng-bootstrap/ng-bootstrap';
 
 @Component({
   selector: 'eg-grid-body',
@@ -12,7 +13,13 @@ export class GridBodyComponent implements OnInit {
 
     @Input() context: GridContext;
 
-    constructor(@Host() private grid: GridComponent) {}
+    // Track the context menus so we can manually close them 
+    // when another popover is opened.
+    contextMenus: NgbPopover[];
+
+    constructor(@Host() private grid: GridComponent) {
+        this.contextMenus = [];
+    }
 
     ngOnInit() {}
 
@@ -71,7 +78,7 @@ export class GridBodyComponent implements OnInit {
         }
     }
 
-    onRowClick($event: any, row: any, idx: number) {
+    handleRowClick($event: any, row: any) {
 
         if (this.context.disableSelect) {
             // Avoid any appearance or click behavior when row
@@ -94,7 +101,10 @@ export class GridBodyComponent implements OnInit {
         } else {
             this.context.selectOneRow(index);
         }
+    }
 
+    onRowClick($event: any, row: any, idx: number) {
+        this.handleRowClick($event, row);
         this.grid.onRowClick.emit(row);
     }
 
@@ -102,5 +112,32 @@ 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) {
+        $event.preventDefault(); // prevent browser context menu
+
+        if (this.context.toolbarActions.length === 0) {
+            // No actions to render.
+            return;
+        }
+
+        this.handleRowClick($event, 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 
+        // not naturally occur via context-click.
+        this.contextMenus.forEach(m => m.close());
+
+        contextMenu.open({gridContext: this.context});
+    }
 }
 

commit 110c8571bb4d70ec02e90c1486088443dee4ecbe
Author: Bill Erickson <berickxx at gmail.com>
Date:   Mon Nov 26 18:20:47 2018 +0000

    LP1803787 Grid toolbar action separators
    
    Add support for "separator" toolbar actions so the action menu may be
    divided into groups.
    
    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-toolbar-action.component.ts b/Open-ILS/src/eg2/src/app/share/grid/grid-toolbar-action.component.ts
index 2cab7f9a20..7901035139 100644
--- a/Open-ILS/src/eg2/src/app/share/grid/grid-toolbar-action.component.ts
+++ b/Open-ILS/src/eg2/src/app/share/grid/grid-toolbar-action.component.ts
@@ -35,6 +35,8 @@ export class GridToolbarActionComponent implements OnInit {
     // (default behavior), the action will be enabled.
     @Input() disableOnRows: (rows: any[]) => boolean;
 
+    // If true, render a separator bar only, no action link.
+    @Input() separator: boolean;
 
     // get a reference to our container grid.
     constructor(@Host() private grid: GridComponent) {
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 0de7ede362..a5aa235400 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
@@ -45,11 +45,15 @@
         <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">
           <!-- grouped entries are indented -->
           <span class="ml-4">{{action.label}}</span>
         </ng-container>
-        <ng-container *ngIf="!action.group && !action.isGroup">
+        <ng-container 
+          *ngIf="!action.group && !action.isGroup && !action.separator">
           <span class="ml-2">{{action.label}}</span>
         </ng-container>
       </button>
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 b133d1ad13..ae611875c3 100644
--- a/Open-ILS/src/eg2/src/app/share/grid/grid.ts
+++ b/Open-ILS/src/eg2/src/app/share/grid/grid.ts
@@ -1028,6 +1028,7 @@ export class GridToolbarAction {
     group: string;
     disabled: boolean;
     isGroup: boolean; // used for group placeholder entries
+    separator: boolean;
     disableOnRows: (rows: any[]) => boolean;
 }
 

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

Summary of changes:
 .../src/app/share/grid/grid-body.component.html    |  23 ++-
 .../eg2/src/app/share/grid/grid-body.component.ts  |  47 +++++-
 .../share/grid/grid-toolbar-action.component.ts    |   3 +
 .../grid/grid-toolbar-actions-menu.component.html  |  15 ++
 .../grid/grid-toolbar-actions-menu.component.ts    |  31 ++++
 .../src/app/share/grid/grid-toolbar.component.html |  18 +--
 .../src/app/share/grid/grid-toolbar.component.ts   |  13 --
 Open-ILS/src/eg2/src/app/share/grid/grid.module.ts |   2 +
 Open-ILS/src/eg2/src/app/share/grid/grid.ts        |   9 ++
 .../src/eg2/src/app/share/print/hatch.service.ts   |   6 +-
 .../src/app/staff/sandbox/sandbox.component.html   |   7 +-
 .../eg2/src/app/staff/sandbox/sandbox.component.ts |   5 +
 .../share/admin-page/admin-page.component.html     |   8 +-
 .../staff/share/admin-page/admin-page.component.ts | 176 ++++++++++-----------
 .../src/eg2/src/app/staff/staff.component.html     |   6 +-
 Open-ILS/src/eg2/src/app/staff/staff.component.ts  |  17 +-
 16 files changed, 248 insertions(+), 138 deletions(-)
 create mode 100644 Open-ILS/src/eg2/src/app/share/grid/grid-toolbar-actions-menu.component.html
 create mode 100644 Open-ILS/src/eg2/src/app/share/grid/grid-toolbar-actions-menu.component.ts


hooks/post-receive
-- 
Evergreen ILS




More information about the open-ils-commits mailing list