LPXXX Angular Permission group tree admin UI
authorBill Erickson <berickxx@gmail.com>
Mon, 8 Apr 2019 20:51:06 +0000 (16:51 -0400)
committerBill Erickson <berickxx@gmail.com>
Mon, 8 Apr 2019 20:51:17 +0000 (16:51 -0400)
Signed-off-by: Bill Erickson <berickxx@gmail.com>
Open-ILS/src/eg2/src/app/staff/admin/server/perm-group-map-dialog.component.html [new file with mode: 0644]
Open-ILS/src/eg2/src/app/staff/admin/server/perm-group-map-dialog.component.ts [new file with mode: 0644]
Open-ILS/src/eg2/src/app/staff/admin/server/perm-group-tree.component.html

diff --git a/Open-ILS/src/eg2/src/app/staff/admin/server/perm-group-map-dialog.component.html b/Open-ILS/src/eg2/src/app/staff/admin/server/perm-group-map-dialog.component.html
new file mode 100644 (file)
index 0000000..fe1c26b
--- /dev/null
@@ -0,0 +1,44 @@
+<ng-template #dialogContent>
+  <div class="modal-header bg-info">
+    <h4 class="modal-title" i18n>Add New Permission Group Mapping</h4>
+    <button type="button" class="close" 
+      i18n-aria-label aria-label="Close" 
+      (click)="dismiss('cross_click')">
+      <span aria-hidden="true">&times;</span>
+    </button>
+  </div>
+  <div class="modal-body">
+    <div class="row">
+      <div class="col-lg-5" i18n>Permission Group</div>
+      <div class="col-lg-7">{{permGroup.name()}}</div>
+    </div>
+    <div class="row mt-1 pt-1">
+      <div class="col-lg-5" i18n>New Permission</div>
+      <div class="col-lg-7">
+        <eg-combobox [asyncDataSource]="permEntries"
+          (onChange)="perm = $event ? $event.id : null">
+        </eg-combobox>
+      </div>
+    </div>
+    <div class="row mt-1 pt-1">
+      <div class="col-lg-5" i18n>Depth</div>
+      <div class="col-lg-7">
+        <eg-combobox [entries]="orgDepths" [startId]="0"
+          (onChange)="depth = $event ? $event.id : null">
+        </eg-combobox>
+      </div>
+    </div>
+    <div class="row mt-1 pt-1">
+      <div class="col-lg-5" i18n>Grantable</div>
+      <div class="col-lg-7">
+        <input type="checkbox" [(ngModel)]="grantable"/>
+      </div>
+    </div>
+  </div>
+  <div class="modal-footer">
+    <button type="button" class="btn btn-success" 
+      (click)="create()" i18n>Create</button>
+    <button type="button" class="btn btn-warning" 
+      (click)="close()" i18n>Cancel</button>
+  </div>
+</ng-template>
diff --git a/Open-ILS/src/eg2/src/app/staff/admin/server/perm-group-map-dialog.component.ts b/Open-ILS/src/eg2/src/app/staff/admin/server/perm-group-map-dialog.component.ts
new file mode 100644 (file)
index 0000000..a1f8f95
--- /dev/null
@@ -0,0 +1,108 @@
+import {Component, Input, ViewChild, TemplateRef} from '@angular/core';
+import {Observable, from, empty} from 'rxjs';
+import {DialogComponent} from '@eg/share/dialog/dialog.component';
+import {IdlService, IdlObject} from '@eg/core/idl.service';
+import {PcrudService} from '@eg/core/pcrud.service';
+import {NgbModal} from '@ng-bootstrap/ng-bootstrap';
+import {ComboboxEntry} from '@eg/share/combobox/combobox.component';
+
+@Component({
+  selector: 'eg-perm-group-map-dialog',
+  templateUrl: './perm-group-map-dialog.component.html'
+})
+
+/**
+ * Ask the user which part is the lead part then merge others parts in.
+ */
+export class PermGroupMapDialogComponent extends DialogComponent {
+
+    @Input() permGroup: IdlObject;
+
+    @Input() permissions: IdlObject[];
+
+    // List of grp-perm-map objects that relate to the selected permission
+    // group or are linked to a parent group.
+    @Input() permMaps: IdlObject[];
+
+    @Input() orgDepths: ComboboxEntry[];
+
+    // Note we have all of the permissions on hand, but rendering the
+    // full list of permissions can caus sluggishness.  Render async instead.
+    permEntries: (term: string) => Observable<ComboboxEntry>;
+
+    // Permissions the user may apply to the current group.
+    trimmedPerms: IdlObject[];
+
+    depth: number;
+    grantable: boolean;
+    perm: number;
+
+    constructor(
+        private idl: IdlService,
+        private pcrud: PcrudService,
+        private modal: NgbModal) {
+        super(modal);
+    }
+
+    ngOnInit() {
+        this.depth = 0;
+        this.grantable = false;
+
+        this.permissions = this.permissions
+            .sort((a, b) => a.code() < b.code() ? -1 : 1);
+
+        this.onOpen$.subscribe(() => this.trimPermissions());
+
+
+        this.permEntries = (term: string) => {
+            if (term === null || term === undefined) { return empty(); }
+            term = ('' + term).toLowerCase();
+
+            // Find entries whose code or description match the search term
+
+            const entries: ComboboxEntry[] =  [];
+            this.trimmedPerms.forEach(p => {
+                if (p.code().toLowerCase().includes(term) ||
+                    p.description().toLowerCase().includes(term)) {
+                    entries.push({id: p.id(), label: p.code()});
+                }
+            })
+
+            return from(entries);
+        }
+    }
+
+    trimPermissions() {
+        this.trimmedPerms = [];
+
+        this.permissions.forEach(p => {
+
+            // Prevent duplicate permissions, for-loop for early exit.
+            for (let idx = 0; idx < this.permMaps.length; idx++) {
+                const map = this.permMaps[idx];
+                if (map.perm().id() === p.id() &&
+                    map.grp().id() === this.permGroup.id()) {
+                    return;
+                }
+            }
+
+            this.trimmedPerms.push(p);
+        })
+    }
+
+    create() {
+        const map = this.idl.create('pgpm');
+
+        map.grp(this.permGroup.id());
+        map.perm(this.perm);
+        map.grantable(this.grantable ? 't' : 'f');
+        map.depth(this.depth);
+
+        this.pcrud.create(map).subscribe(
+            newMap => this.close(newMap),
+            err => { throw new Error(err); }
+        );
+    }
+}
+
+
index c3c6ec8..197c59c 100644 (file)
                   </eg-combobox>
                 </div>
                 <div class="col-lg-1 d-flex flex-column justify-content-center">
-                  <div class="d-flex justify-content-center p-3 rounded bg-info">                
+                  <div class="d-flex justify-content-center p-3 rounded border border-info">                
                     <input type="checkbox" class="align-middle"
                       i18n-title title="Grantable?"
                       [ngModel]="map.grantable() == 't'"
                   </div>
                 </div>
                 <div class="col-lg-1 d-flex flex-column justify-content-center">
-                  <div class="d-flex justify-content-center p-3 rounded bg-danger">
+                  <div class="d-flex justify-content-center p-3 rounded border border-danger">
                     <input type="checkbox" class="align-middle"
                       i18n-title title="Delete Mapping"
                       [ngModel]="map.isdeleted()"