--- /dev/null
+<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">×</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>
--- /dev/null
+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); }
+ );
+ }
+}
+
+
</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()"