<h3 i18n class="mb-3">Selected Permission Group</h3>
<ng-container *ngIf="!selected">
<div class="alert alert-info font-italic" i18n>
- Select an org unit type from the tree on the left.
+ Select a permission group from the tree on the left.
</div>
</ng-container>
<div *ngIf="selected" class="common-form striped-even">
{{selected.callerData.name()}}
</div>
</div>
+ <div class="row">
+ <div class="col-lg-4">
+ <label i18n>Description: </label>
+ </div>
+ <div class="col-lg-8 font-weight-bold">
+ {{selected.callerData.description()}}
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-lg-4">
+ <label i18n>User Expiration Interval: </label>
+ </div>
+ <div class="col-lg-8 font-weight-bold">
+ {{selected.callerData.perm_interval()}}
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-lg-4">
+ <label i18n>Application Permission: </label>
+ </div>
+ <div class="col-lg-8 font-weight-bold">
+ {{selected.callerData.application_perm()}}
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-lg-4">
+ <label i18n>Hold Priority: </label>
+ </div>
+ <div class="col-lg-8 font-weight-bold">
+ {{selected.callerData.hold_priority()}}
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-lg-4">
+ <label i18n>User Group?: </label>
+ </div>
+ <div class="col-lg-8 font-weight-bold">
+ <!-- TODO: replace with <eg-bool/> when merged -->
+ {{selected.callerData.usergroup() == 't'}}
+ </div>
+ </div>
</ng-template>
</ngb-tab>
- <ngb-tab title="Group Permission" i18n-title id="perm">
+ <ngb-tab title="Group Permissions" i18n-title id="perm">
<ng-template ngbTabContent>
+
+ <div class="row font-weight-bold">
+ <div class="col-lg-5" i18n>Permissions</div>
+ <div class="col-lg-2" i18n>Depth</div>
+ <div class="col-lg-3" i18n>Group</div>
+ <div class="col-lg-2" i18n>Grantable?</div>
+ </div>
+
+ <div class="row" *ngFor="let map of groupPermMaps()">
+ <div class="col-lg-5">{{map.perm().code()}}</div>
+ <div class="col-lg-2">{{map.depth()}}</div>
+ <div class="col-lg-3">{{map.grp().name()}}</div>
+ <div class="col-lg-2">
+ <ng-container *ngIf="permIsInherited(map); else nativeMap">
+ <!-- TODO migrate to <eg-bool/> once merged-->
+ {{map.grantable() == 't'}}
+ </ng-container>
+ <ng-template #nativeMap>
+ <input type="checkbox"
+ [ngModel]="map.grantable() == 't'"
+ (ngModelChange)="map.grantable($event ? 't' : 'f')"/>
+ </ng-template>
+ </div>
+ </div>
</ng-template>
</ngb-tab>
</ngb-tabset>
import {Component, Input, ViewChild, OnInit} from '@angular/core';
+import {Observable, from} from 'rxjs';
import {Tree, TreeNode} from '@eg/share/tree/tree';
import {IdlService, IdlObject} from '@eg/core/idl.service';
import {OrgService} from '@eg/core/org.service';
import {ConfirmDialogComponent} from '@eg/share/dialog/confirm.component';
import {FmRecordEditorComponent, FmFieldOptions} from '@eg/share/fm-editor/fm-editor.component';
import {ComboboxEntry} from '@eg/share/combobox/combobox.component';
+import {Pager} from '@eg/share/util/pager';
@Component({
templateUrl: './perm-group-tree.component.html'
tree: Tree;
selected: TreeNode;
- permissions: ComboboxEntry[];
+ permissions: IdlObject[];
+ permIdMap: {[id: number]: IdlObject};
+ permEntries: ComboboxEntry[];
+ permMaps: IdlObject[];
@ViewChild('editDialog') editDialog: FmRecordEditorComponent;
@ViewChild('editString') editString: StringComponent;
private toast: ToastService
) {
this.permissions = [];
+ this.permEntries = [];
+ this.permMaps = [];
+ this.permIdMap = {};
}
this.loadPgtTree();
}
+ groupPermMaps(): IdlObject[] {
+ let maps = this.inheritedPermissions();
+ maps = maps.concat(
+ this.permMaps.filter(m => +m.grp().id() === +this.selected.id));
+
+ return maps.sort((m1, m2) =>
+ m1.perm().code() < m2.perm().code() ? -1 : 1);
+ }
+
+
+
loadPgtTree() {
+
this.pcrud.search('pgt', {parent: null},
{flesh: -1, flesh_fields: {pgt: ['children']}}
).subscribe(pgtTree => this.ingestPgtTree(pgtTree));
// "pgt" is text instead of a link. So the value it expects
// is the code, not the ID.
this.pcrud.retrieveAll('ppl', {order_by: {ppl: ['name']}})
- .subscribe(perm =>
- this.permissions.push({id: perm.code(), label: perm.code()}));
+ .subscribe(perm => {
+ this.permissions.push(perm);
+ this.permEntries.push({id: perm.code(), label: perm.code()})
+ this.permissions.forEach(perm => this.permIdMap[+perm.id()] = perm)
+ });
+
+ // Perm-group maps
+ this.pcrud.retrieveAll('pgpm', {}, {fleshSelectors: true})
+ .subscribe(map => this.permMaps.push(map));
}
fmEditorOptions(): {[fieldName: string]: FmFieldOptions} {
return {
application_perm: {
- customValues: this.permissions
+ customValues: this.permEntries
}
};
}
// Translate the org unt type tree into a structure EgTree can use.
- ingestPgtTree(pgtTree) {
+ ingestPgtTree(pgtTree: IdlObject) {
const handleNode = (pgtNode: IdlObject): TreeNode => {
if (!pgtNode) { return; }
this.tree = new Tree(rootNode);
}
- nodeClicked($event: any) {
- this.selected = $event;
+ groupById(id: number): IdlObject {
+ return this.tree.findNode(id).callerData;
}
- postUpdate(message: StringComponent) {
- // Modifying org unit types means refetching the org unit
- // data normally fetched on page load, since it includes
- // org unit type data.
- this.org.fetchOrgs().then(
- ok => {
- message.current().then(str => this.toast.success(str));
+ permById(id: number): IdlObject {
+ return this.permIdMap[id];
+ }
+
+ // Returns true if the perm map belongs to an ancestore of the
+ // currently selected group.
+ permIsInherited(map: IdlObject): boolean {
+ let treeNode = this.tree.findNode(this.selected.callerData.parent());
+ while (treeNode) {
+ if (+map.grp().id() === +treeNode.id) {
+ return true;
}
- );
+ treeNode = this.tree.findNode(treeNode.callerData.parent());
+ }
+ return false;
+ }
+
+ // List of perm maps that owned by perm groups which are ancestors
+ // of the selected group
+ inheritedPermissions(): IdlObject[] {
+ let maps: IdlObject[] = [];
+
+ let treeNode = this.tree.findNode(this.selected.callerData.parent());
+ while (treeNode) {
+ maps = maps.concat(
+ this.permMaps.filter(map => +map.grp().id() === +treeNode.id));
+ treeNode = this.tree.findNode(treeNode.callerData.parent());
+ }
+
+ return maps;
+ }
+
+ nodeClicked($event: any) {
+ this.selected = $event;
}
edit() {
this.editDialog.open({size: 'lg'}).then(
success => {
- this.postUpdate(this.editString);
+ this.editString.current().then(str => this.toast.success(str));
},
rejected => {
if (rejected && rejected.dismissed) {
// pcrud action/transaction completed.
this.tree.removeNode(this.selected);
this.selected = null;
- this.postUpdate(this.editString);
+ this.editString.current().then(str => this.toast.success(str));
}
);
},
callerData: result
});
parentTreeNode.children.push(newNode);
- this.postUpdate(this.createString);
+ this.createString.current().then(str => this.toast.success(str));
},
rejected => {