LP#1775466 Apache/doc Perm check repairs for admin pages / grids
authorBill Erickson <berickxx@gmail.com>
Wed, 8 Aug 2018 18:41:15 +0000 (14:41 -0400)
committerBill Erickson <berickxx@gmail.com>
Wed, 8 Aug 2018 18:41:15 +0000 (14:41 -0400)
Signed-off-by: Bill Erickson <berickxx@gmail.com>
Open-ILS/src/eg2/src/app/share/fm-editor/fm-editor.component.ts
Open-ILS/src/eg2/src/app/share/grid/grid-toolbar-button.component.ts
Open-ILS/src/eg2/src/app/share/grid/grid-toolbar.component.html
Open-ILS/src/eg2/src/app/share/grid/grid.ts
Open-ILS/src/eg2/src/app/staff/share/admin-page/admin-page.component.html
Open-ILS/src/eg2/src/app/staff/share/admin-page/admin-page.component.ts

index ebde009..308218a 100644 (file)
@@ -153,6 +153,13 @@ export class FmRecordEditorComponent
 
     private initRecord(): Promise<any> {
 
+        const pc = this.idlDef.permacrud || {};
+        this.modePerms = {
+            view:   pc.retrieve ? pc.retrieve.perms : [],
+            create: pc.create ? pc.create.perms : [],
+            update: pc.update ? pc.update.perms : [],
+        };
+
         if (this.mode === 'update' || this.mode === 'view') {
             return this.pcrud.retrieve(this.idlClass, this.recId)
             .toPromise().then(rec => {
@@ -168,13 +175,6 @@ export class FmRecordEditorComponent
             });
         }
 
-        const pc = this.idlDef.permacrud || {};
-        this.modePerms = {
-            view:   pc.retrieve ? pc.retrieve.perms : [],
-            create: pc.create ? pc.create.perms : [],
-            update: pc.update ? pc.update.perms : [],
-        };
-
         // create a new record from scratch
         this.pkeyIsEditable = !('pkey_sequence' in this.idlDef);
         this.record = this.idl.create(this.idlClass);
index ae71b18..8287483 100644 (file)
@@ -13,8 +13,20 @@ export class GridToolbarButtonComponent implements OnInit {
     @Input() label: string;
     @Input() action: () => any;
 
+    @Input() set disabled(d: boolean) {
+        // Support asynchronous disabled values by appling directly
+        // to our button object as values arrive.
+        if (this.button) {
+            this.button.disabled = d;
+        }
+    }
+
+    button: GridToolbarButton;
+
     // get a reference to our container grid.
-    constructor(@Host() private grid: GridComponent) {}
+    constructor(@Host() private grid: GridComponent) {
+        this.button = new GridToolbarButton();
+    }
 
     ngOnInit() {
 
@@ -23,11 +35,9 @@ export class GridToolbarButtonComponent implements OnInit {
             return;
         }
 
-        const btn = new GridToolbarButton();
-        btn.label = this.label;
-        btn.action = this.action;
-
-        this.grid.context.toolbarButtons.push(btn);
+        this.button.label = this.label;
+        this.button.action = this.action;
+        this.grid.context.toolbarButtons.push(this.button);
     }
 }
 
index 48b9e39..442bab1 100644 (file)
@@ -6,6 +6,7 @@
     <!-- buttons -->
     <div class="btn-grp" *ngIf="gridContext.toolbarButtons.length">
       <button *ngFor="let btn of gridContext.toolbarButtons" 
+        [disabled]="btn.disabled"
         class="btn btn-outline-dark" (click)="btn.action()">
         {{btn.label}}
       </button>
index 0c40a76..a152fd8 100644 (file)
@@ -890,6 +890,7 @@ export class GridToolbarAction {
 export class GridToolbarButton {
     label: string;
     action: () => any;
+    disabled: boolean;
 }
 
 export class GridToolbarCheckbox {
index 9435dc2..5f0eadd 100644 (file)
@@ -40,7 +40,8 @@
 
 <eg-grid #grid idlClass="{{idlClass}}" [dataSource]="dataSource" 
     [sortable]="true" persistKey="{{persistKey}}">
-  <eg-grid-toolbar-button label="New {{idlClassDef.label}}" i18n-label [action]="createNew">
+  <eg-grid-toolbar-button [disabled]="!canCreate" 
+    label="New {{idlClassDef.label}}" i18n-label [action]="createNew">
   </eg-grid-toolbar-button>
   <eg-grid-toolbar-action label="Delete Selected" i18n-label [action]="deleteSelected">
   </eg-grid-toolbar-action>
index 29d0545..afe9e97 100644 (file)
@@ -6,6 +6,7 @@ import {ToastService} from '@eg/share/toast/toast.service';
 import {Pager} from '@eg/share/util/pager';
 import {PcrudService} from '@eg/core/pcrud.service';
 import {OrgService} from '@eg/core/org.service';
+import {PermService} from '@eg/core/perm.service';
 import {AuthService} from '@eg/core/auth.service';
 import {FmRecordEditorComponent} from '@eg/share/fm-editor/fm-editor.component';
 import {StringComponent} from '@eg/share/string/string.component';
@@ -73,12 +74,14 @@ export class AdminPageComponent implements OnInit {
     contextOrg: IdlObject;
     orgFieldLabel: string;
     viewPerms: string;
+    canCreate: boolean;
 
     constructor(
         private idl: IdlService,
         private org: OrgService,
         private auth: AuthService,
         private pcrud: PcrudService,
+        private perm: PermService,
         private toast: ToastService
     ) {}
 
@@ -124,6 +127,7 @@ export class AdminPageComponent implements OnInit {
             this.viewPerms = pc.retrieve.perms;
         }
 
+        this.checkCreatePerms();
         this.applyOrgValues();
 
         // If the caller provides not data source, create a generic one.
@@ -169,6 +173,21 @@ export class AdminPageComponent implements OnInit {
         };
     }
 
+    checkCreatePerms() {
+        this.canCreate = false;
+        const pc = this.idlClassDef.permacrud || {};
+        const perms = pc.create ? pc.create.perms : [];
+        if (perms.length === 0) { return; }
+
+        this.perm.hasWorkPermAt(perms, true).then(permMap => {
+            Object.keys(permMap).forEach(key => {
+                if (permMap[key].length > 0) {
+                    this.canCreate = true;
+                }
+            });
+        });
+    }
+
     orgOnChange(org: IdlObject) {
         this.contextOrg = org;
         this.grid.reload();