@firestitch/app-acl 14.0.0 → 16.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/app/components/acl-entries/acl-entries.component.d.ts +1 -1
  2. package/app/components/acl-entry/acl-entry.component.d.ts +1 -1
  3. package/app/components/acl-object-roles/acl-object-roles.component.d.ts +1 -1
  4. package/app/components/acl-permission-popover/acl-permission-popover.component.d.ts +1 -1
  5. package/app/components/acl-role/acl-role.component.d.ts +1 -1
  6. package/app/components/acl-role-popover/acl-role-popover.component.d.ts +1 -1
  7. package/app/components/acl-roles/acl-roles.component.d.ts +1 -1
  8. package/esm2022/app/components/acl-entries/acl-entries.component.mjs +182 -0
  9. package/esm2022/app/components/acl-entry/acl-entry.component.mjs +99 -0
  10. package/esm2022/app/components/acl-object-roles/acl-object-roles.component.mjs +50 -0
  11. package/esm2022/app/components/acl-permission-popover/acl-permission-popover.component.mjs +32 -0
  12. package/esm2022/app/components/acl-role/acl-role.component.mjs +265 -0
  13. package/esm2022/app/components/acl-role-popover/acl-role-popover.component.mjs +37 -0
  14. package/esm2022/app/components/acl-roles/acl-roles.component.mjs +181 -0
  15. package/{esm2020 → esm2022}/app/fs-app-acl.module.mjs +53 -53
  16. package/{esm2020 → esm2022}/app/pipes/acl-role-permission-available.pipe.mjs +4 -4
  17. package/{esm2020 → esm2022}/app/pipes/bulk-options-filter.pipe.mjs +4 -4
  18. package/esm2022/app/services/app-acl.service.mjs +54 -0
  19. package/{fesm2020 → fesm2022}/firestitch-app-acl.mjs +205 -164
  20. package/fesm2022/firestitch-app-acl.mjs.map +1 -0
  21. package/package.json +5 -11
  22. package/esm2020/app/components/acl-entries/acl-entries.component.mjs +0 -176
  23. package/esm2020/app/components/acl-entry/acl-entry.component.mjs +0 -93
  24. package/esm2020/app/components/acl-object-roles/acl-object-roles.component.mjs +0 -52
  25. package/esm2020/app/components/acl-permission-popover/acl-permission-popover.component.mjs +0 -29
  26. package/esm2020/app/components/acl-role/acl-role.component.mjs +0 -254
  27. package/esm2020/app/components/acl-role-popover/acl-role-popover.component.mjs +0 -34
  28. package/esm2020/app/components/acl-roles/acl-roles.component.mjs +0 -170
  29. package/esm2020/app/services/app-acl.service.mjs +0 -51
  30. package/fesm2015/firestitch-app-acl.mjs +0 -950
  31. package/fesm2015/firestitch-app-acl.mjs.map +0 -1
  32. package/fesm2020/firestitch-app-acl.mjs.map +0 -1
  33. /package/{esm2020 → esm2022}/app/consts/acl-role-accesses.mjs +0 -0
  34. /package/{esm2020 → esm2022}/app/enums/acl-role-access.mjs +0 -0
  35. /package/{esm2020 → esm2022}/app/injectors/app-acl-config.injector.mjs +0 -0
  36. /package/{esm2020 → esm2022}/app/interfaces/acl-entry-data.mjs +0 -0
  37. /package/{esm2020 → esm2022}/app/interfaces/acl-entry.mjs +0 -0
  38. /package/{esm2020 → esm2022}/app/interfaces/acl-level.mjs +0 -0
  39. /package/{esm2020 → esm2022}/app/interfaces/acl-object-entry.mjs +0 -0
  40. /package/{esm2020 → esm2022}/app/interfaces/acl-object-role.mjs +0 -0
  41. /package/{esm2020 → esm2022}/app/interfaces/acl-object.mjs +0 -0
  42. /package/{esm2020 → esm2022}/app/interfaces/acl-permission.mjs +0 -0
  43. /package/{esm2020 → esm2022}/app/interfaces/acl-role-config.mjs +0 -0
  44. /package/{esm2020 → esm2022}/app/interfaces/acl-role.mjs +0 -0
  45. /package/{esm2020 → esm2022}/app/interfaces/app-acl-config.mjs +0 -0
  46. /package/{esm2020 → esm2022}/app/interfaces/index.mjs +0 -0
  47. /package/{esm2020 → esm2022}/app/interfaces/name-value.mjs +0 -0
  48. /package/{esm2020 → esm2022}/app/interfaces/role-config.mjs +0 -0
  49. /package/{esm2020 → esm2022}/app/pipes/index.mjs +0 -0
  50. /package/{esm2020 → esm2022}/firestitch-app-acl.mjs +0 -0
  51. /package/{esm2020 → esm2022}/public_api.mjs +0 -0
@@ -0,0 +1,265 @@
1
+ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Inject, ViewChild } from '@angular/core';
2
+ import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
3
+ import { AclRoleAccesses } from './../../consts/acl-role-accesses';
4
+ import { takeUntil, tap } from 'rxjs/operators';
5
+ import { FsMessage } from '@firestitch/message';
6
+ import { list } from '@firestitch/common';
7
+ import { FsListComponent } from '@firestitch/list';
8
+ import { forkJoin, of, Subject } from 'rxjs';
9
+ import { FsAppAclService } from './../../services/app-acl.service';
10
+ import { AclRoleAccess } from '../../enums/acl-role-access';
11
+ import { MatButton } from '@angular/material/button';
12
+ import * as i0 from "@angular/core";
13
+ import * as i1 from "./../../services/app-acl.service";
14
+ import * as i2 from "@angular/material/dialog";
15
+ import * as i3 from "@firestitch/message";
16
+ import * as i4 from "@angular/common";
17
+ import * as i5 from "@angular/forms";
18
+ import * as i6 from "@angular/material/form-field";
19
+ import * as i7 from "@angular/material/checkbox";
20
+ import * as i8 from "@angular/material/select";
21
+ import * as i9 from "@angular/material/core";
22
+ import * as i10 from "@angular/material/button";
23
+ import * as i11 from "@angular/material/radio";
24
+ import * as i12 from "@angular/material/input";
25
+ import * as i13 from "@firestitch/list";
26
+ import * as i14 from "@firestitch/dialog";
27
+ import * as i15 from "@firestitch/form";
28
+ import * as i16 from "@firestitch/label";
29
+ import * as i17 from "@firestitch/radiogroup";
30
+ import * as i18 from "@firestitch/menu";
31
+ import * as i19 from "../../pipes/bulk-options-filter.pipe";
32
+ import * as i20 from "../../pipes/acl-role-permission-available.pipe";
33
+ export class FsAclRoleComponent {
34
+ _data;
35
+ _appAclService;
36
+ _dialogRef;
37
+ _message;
38
+ _cdRef;
39
+ list;
40
+ submitButton;
41
+ aclRole = null;
42
+ environment;
43
+ permissions = [];
44
+ listConfig;
45
+ levelPermissions = [];
46
+ AclRoleAccesses = AclRoleAccesses;
47
+ indexedAccesses = {};
48
+ aclLevels = [];
49
+ indexedAclLevels = {};
50
+ onlyFullAccess = false;
51
+ AclLevels = {};
52
+ roleConfigs = [];
53
+ aclRoleConfigValues = {};
54
+ aclRolePermissions = {};
55
+ loadRoleConfigs;
56
+ disabled;
57
+ _destroy$ = new Subject();
58
+ constructor(_data, _appAclService, _dialogRef, _message, _cdRef) {
59
+ this._data = _data;
60
+ this._appAclService = _appAclService;
61
+ this._dialogRef = _dialogRef;
62
+ this._message = _message;
63
+ this._cdRef = _cdRef;
64
+ }
65
+ ngOnInit() {
66
+ forkJoin(this.getRole(), this._appAclService.getPermissions())
67
+ .pipe(takeUntil(this._destroy$))
68
+ .subscribe(([aclRole, aclPermissions,]) => {
69
+ this.permissions = aclPermissions;
70
+ this.aclLevels = this._data.aclLevels;
71
+ this.disabled = this._data.disabled;
72
+ this.indexedAclLevels = list(this.aclLevels, 'name', 'value');
73
+ this.indexedAccesses = list(AclRoleAccesses, 'name', 'value');
74
+ this.aclRole = {
75
+ ...{
76
+ aclPermissions: [],
77
+ allPermissions: true,
78
+ aclRoleConfigs: [],
79
+ permissions: {},
80
+ level: this.aclLevels[0].value,
81
+ },
82
+ ...aclRole,
83
+ };
84
+ this.aclRoleConfigValues = (aclRole.aclRoleConfigs || [])
85
+ .reduce((accum, aclRoleConfig) => {
86
+ return {
87
+ ...accum,
88
+ [aclRoleConfig.name]: aclRoleConfig.value,
89
+ };
90
+ }, {});
91
+ if (this.aclRole.id) {
92
+ this.permissions.forEach((permission) => {
93
+ let access = 0;
94
+ const aclPermission = this.aclRole.aclPermissions.find((item) => {
95
+ return item.permission === permission.value;
96
+ });
97
+ if (aclPermission) {
98
+ access = aclPermission.access;
99
+ }
100
+ this.aclRolePermissions[permission.value] = access;
101
+ });
102
+ }
103
+ if (this.aclRole.allPermissions) {
104
+ this._applyMaxPermissionAccess();
105
+ }
106
+ this._updatePermissions();
107
+ this._updateRoleConfigs();
108
+ this._cdRef.markForCheck();
109
+ });
110
+ this.listConfig = {
111
+ status: false,
112
+ paging: false,
113
+ rowHoverHighlight: false,
114
+ noResults: {
115
+ message: '',
116
+ },
117
+ group: {
118
+ initialExpand: true,
119
+ groupBy: (data) => {
120
+ return data;
121
+ },
122
+ compareBy: (data) => {
123
+ return data.category || 'General';
124
+ },
125
+ },
126
+ fetch: () => {
127
+ return of({
128
+ data: this.levelPermissions.sort((a, b) => {
129
+ a = a.name.toUpperCase();
130
+ b = b.name.toUpperCase();
131
+ if (a < b) {
132
+ return -1;
133
+ }
134
+ else if (a > b) {
135
+ return 1;
136
+ }
137
+ return 0;
138
+ }),
139
+ });
140
+ },
141
+ };
142
+ }
143
+ bulkChange(value, groupChildren, group) {
144
+ groupChildren
145
+ .forEach((permission) => {
146
+ const access = permission.accesses
147
+ .find((access) => value === access);
148
+ if (access || !value) {
149
+ this.aclRolePermissions[permission.value] = value;
150
+ }
151
+ });
152
+ setTimeout(() => {
153
+ this.submitButton.disabled = false;
154
+ this.permissionChange();
155
+ });
156
+ }
157
+ permissionChange() {
158
+ this.aclRolePermissions = {
159
+ ...this.aclRolePermissions,
160
+ };
161
+ this._cdRef.markForCheck();
162
+ }
163
+ levelChange() {
164
+ this._updatePermissions();
165
+ this._updateRoleConfigs();
166
+ this.list.reload();
167
+ }
168
+ getRole() {
169
+ if (!this._data.aclRole.id) {
170
+ return of(this._data.aclRole);
171
+ }
172
+ const query = {
173
+ aclPermissions: true,
174
+ aclRoleConfigs: true,
175
+ };
176
+ if (!this.environment) {
177
+ query.environmentId = null;
178
+ }
179
+ return this._data.loadAclRole(this._data.aclRole, query);
180
+ }
181
+ save = () => {
182
+ const aclRoleConfigs = this.roleConfigs
183
+ .map((roleConfig) => {
184
+ return {
185
+ name: roleConfig.name,
186
+ value: this.aclRoleConfigValues[roleConfig.name],
187
+ };
188
+ });
189
+ const aclRole = {
190
+ ...this.aclRole,
191
+ permissions: this.levelPermissions.map((permission) => {
192
+ return {
193
+ value: permission.value,
194
+ access: this.aclRolePermissions[permission.value] || 0,
195
+ };
196
+ }),
197
+ aclRoleConfigs,
198
+ };
199
+ return this._data.saveAclRole(aclRole)
200
+ .pipe(tap((response) => {
201
+ this._message.success('Saved Changes');
202
+ this.close(response);
203
+ }));
204
+ };
205
+ close(data = null) {
206
+ this._dialogRef.close(data);
207
+ }
208
+ allPermissionsChange(all) {
209
+ this._updatePermissions();
210
+ if (all) {
211
+ this._applyMaxPermissionAccess();
212
+ }
213
+ else {
214
+ this._applyNonePermissionAccess();
215
+ }
216
+ }
217
+ ngOnDestroy() {
218
+ this._destroy$.next();
219
+ this._destroy$.complete();
220
+ }
221
+ _updatePermissions() {
222
+ this.levelPermissions = this.permissions
223
+ .filter((permission) => {
224
+ return permission.levels.some((item) => {
225
+ return item === this.aclRole.level;
226
+ });
227
+ });
228
+ }
229
+ _updateRoleConfigs() {
230
+ if (this._data.loadRoleConfigs) {
231
+ this._data.loadRoleConfigs()
232
+ .subscribe((roleConfigs) => {
233
+ this.roleConfigs = roleConfigs
234
+ .filter((roleConfig) => roleConfig.level === this.aclRole.level);
235
+ this._cdRef.markForCheck();
236
+ });
237
+ }
238
+ }
239
+ _applyMaxPermissionAccess() {
240
+ this.permissions.forEach((permission) => {
241
+ this.aclRolePermissions[permission.value] = Math.max(...permission.accesses);
242
+ });
243
+ }
244
+ _applyNonePermissionAccess() {
245
+ this.permissions.forEach((permission) => {
246
+ this.aclRolePermissions[permission.value] = AclRoleAccess.None;
247
+ });
248
+ }
249
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FsAclRoleComponent, deps: [{ token: MAT_DIALOG_DATA }, { token: i1.FsAppAclService }, { token: i2.MatDialogRef }, { token: i3.FsMessage }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
250
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: FsAclRoleComponent, selector: "ng-component", viewQueries: [{ propertyName: "list", first: true, predicate: FsListComponent, descendants: true }, { propertyName: "submitButton", first: true, predicate: ["submit"], descendants: true }], ngImport: i0, template: "<form fsForm [submit]=\"save\">\n <fs-dialog>\n <ng-container *ngIf=\"aclRole\">\n <div mat-dialog-title>\n <ng-container *ngIf=\"!disabled\">{{ aclRole.id ? 'Edit' : 'Create' }}</ng-container>\n <ng-container *ngIf=\"disabled\">View</ng-container>\n Role\n </div>\n <mat-dialog-content>\n <div class=\"fs-row.gap-large.align-start\">\n <div class=\"fs-column left-column\">\n <mat-form-field> \n <mat-label>Name</mat-label>\n <input\n matInput\n [(ngModel)]=\"aclRole.name\"\n [disabled]=\"disabled\"\n name=\"name\"\n fsFormRequired>\n </mat-form-field>\n\n <mat-form-field>\n <mat-label>Description</mat-label>\n <input\n matInput\n [(ngModel)]=\"aclRole.description\"\n [disabled]=\"disabled\"\n name=\"description\">\n </mat-form-field>\n\n <fs-label-field *ngIf=\"aclRole.id || aclLevels.length === 1; else levels\">\n <fs-label>Level</fs-label>\n {{indexedAclLevels[aclRole.level]}}\n </fs-label-field>\n\n <ng-template #levels>\n <div class=\"level\">\n <fs-radio-group\n [(ngModel)]=\"aclRole.level\"\n [disabled]=\"disabled\"\n (ngModelChange)=\"levelChange()\"\n fsFormRequired\n label=\"Level\"\n orientation=\"vertical\"\n name=\"level\">\n <mat-radio-button\n *ngFor=\"let item of aclLevels\"\n [value]=\"item.value\"\n [disabled]=\"!!aclRole.protected\">\n {{ item.name }}\n </mat-radio-button>\n </fs-radio-group>\n </div>\n </ng-template>\n\n <fs-label-field *ngIf=\"levelPermissions.length\">\n <fs-label>All Permissions</fs-label>\n <mat-checkbox\n [(ngModel)]=\"aclRole.allPermissions\"\n (ngModelChange)=\"allPermissionsChange($event)\"\n [disabled]=\"!!aclRole.protected || disabled\"\n name=\"allPermissions\">\n Enable\n </mat-checkbox>\n </fs-label-field>\n\n <div class=\"fs-column\" *ngFor=\"let roleConfig of roleConfigs\">\n <fs-label-field *ngIf=\"roleConfig.type === 'checkbox'\">\n <fs-label>{{roleConfig.label}}</fs-label>\n <mat-checkbox\n [(ngModel)]=\"aclRoleConfigValues[roleConfig.name]\"\n [disabled]=\"disabled\"\n [name]=\"roleConfig.name\">\n Enable\n </mat-checkbox>\n <fs-label-message>\n <mat-hint>{{roleConfig.description}}</mat-hint>\n </fs-label-message>\n </fs-label-field>\n\n <mat-form-field *ngIf=\"roleConfig.type === 'select'\">\n <mat-select\n [(ngModel)]=\"aclRoleConfigValues[roleConfig.name]\"\n [name]=\"roleConfig.name\"\n [required]=\"roleConfig.required\"\n [disabled]=\"disabled\"\n [placeholder]=\"roleConfig.label\">\n <mat-option\n *ngFor=\"let item of roleConfig.values\"\n [value]=\"item.value\">\n {{ item.name }}\n </mat-option>\n </mat-select>\n <mat-hint>{{roleConfig.description}}</mat-hint>\n </mat-form-field>\n </div>\n </div>\n\n <div *ngIf=\"aclRole.level\" [hidden]=\"!levelPermissions.length\" class=\"permissions fs-column\">\n <fs-list [config]=\"listConfig\">\n <fs-list-column title=\"Permissions\">\n <ng-template fs-list-group-cell let-row=\"row\" class=\"permission-group\">\n <div class=\"permission-group\">{{row.category || 'General'}}</div>\n </ng-template>\n <ng-template fs-list-cell let-row=\"row\">\n <div class=\"permission\">{{ row.name }}</div>\n <div class=\"description small\">{{ row.description }}</div>\n </ng-template>\n </fs-list-column>\n <fs-list-column title=\"Access\" width=\"1%\" class=\"access\">\n <ng-template \n fs-list-group-cell\n let-row=\"row\"\n let-group=\"group\"\n let-groupChildren=\"groupChildren\"\n class=\"permission-group\"\n align=\"right\">\n <ng-container *ngIf=\"!aclRole.allPermissions && !disabled\">\n <fs-menu>\n <ng-container *ngFor=\"let access of AclRoleAccesses | builkOptionsFilter: groupChildren\">\n <ng-template\n fs-menu-item\n (click)=\"bulkChange(access.value, groupChildren, group)\">\n {{ access.name }}\n </ng-template>\n </ng-container>\n </fs-menu>\n </ng-container>\n </ng-template>\n <ng-template fs-list-cell let-row=\"permission\" let-permission=\"row\">\n <span *ngIf=\"aclRole.allPermissions || disabled; else elseAll\">\n {{indexedAccesses[aclRolePermissions[permission.value]]}}\n </span>\n <ng-template #elseAll>\n <ng-container *ngIf=\"permission|aclRolePermissionAvailable:aclRolePermissions; else permissionRequires\">\n <mat-form-field>\n <mat-select\n [(ngModel)]=\"aclRolePermissions[permission.value]\"\n [disabled]=\"!!aclRole.protected\"\n required\n [name]=\"'access-' + permission.value\"\n (ngModelChange)=\"permissionChange()\">\n <ng-container *ngFor=\"let access of AclRoleAccesses\">\n <mat-option\n *ngIf=\"access.value === 0 || permission.accesses.indexOf(access.value) !== -1\"\n [value]=\"access.value\">\n {{access.name}}\n </mat-option>\n </ng-container>\n </mat-select>\n </mat-form-field>\n </ng-container>\n <ng-template #permissionRequires>\n Unavailable\n </ng-template>\n </ng-template>\n </ng-template>\n </fs-list-column>\n </fs-list>\n </div>\n </div>\n </mat-dialog-content>\n <mat-dialog-actions>\n <button\n *ngIf=\"!disabled\"\n #submit\n mat-button\n type=\"submit\"\n color=\"primary\">\n {{ aclRole.id ? 'Save' : 'Create' }}\n </button>\n <button mat-button [mat-dialog-close]=\"null\" type=\"button\">{{ disabled ? 'Done' : 'Cancel' }}</button>\n </mat-dialog-actions>\n </ng-container>\n </fs-dialog>\n</form>\n", styles: [".permissions{flex:1}.permissions ::ng-deep .fs-list-row-group{background-color:#e4e4e4;font-size:112%}.permissions ::ng-deep fs-list .access{white-space:nowrap}.permissions ::ng-deep .mat-form-field{width:100px}.permissions ::ng-deep .mat-form-field .mat-form-field-wrapper{padding-bottom:0}.permissions ::ng-deep .mat-form-field .mat-form-field-infix{border-top:0}.permissions ::ng-deep .mat-form-field .mat-form-field-underline{bottom:0}.permissions ::ng-deep fs-radio-group{width:100%}.permissions ::ng-deep fs-label-field{width:100%}.permissions .level{width:100%}.left-column{width:40%;max-width:400px}\n"], dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i5.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i5.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i2.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i2.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: i2.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "component", type: i7.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex"], exportAs: ["matCheckbox"] }, { kind: "component", type: i8.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex", "panelWidth", "hideSingleSelectionIndicator"], exportAs: ["matSelect"] }, { kind: "component", type: i9.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: i10.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i11.MatRadioButton, selector: "mat-radio-button", inputs: ["disableRipple", "tabIndex"], exportAs: ["matRadioButton"] }, { kind: "directive", type: i12.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i13.FsListComponent, selector: "fs-list", inputs: ["config", "loaderLines"], outputs: ["filtersReady"] }, { kind: "directive", type: i13.FsListColumnDirective, selector: "fs-list-column", inputs: ["show", "title", "name", "customize", "sortable", "sortableDefault", "sortableDirection", "direction", "align", "width", "class"] }, { kind: "directive", type: i13.FsListCellDirective, selector: "[fs-list-cell]", inputs: ["colspan", "align", "class"] }, { kind: "directive", type: i13.FsListGroupHeaderDirective, selector: "[fs-list-group-cell],[fs-list-group-header]" }, { kind: "component", type: i14.FsDialogComponent, selector: "fs-dialog", inputs: ["mobileMode", "mobileButtonPlacement", "mobileWidth", "mode", "buttonLayout", "dock", "dockable", "fullscreenPercent"] }, { kind: "directive", type: i15.FsFormDirective, selector: "[fsForm]", inputs: ["wrapperSelector", "messageSelector", "hintSelector", "labelSelector", "autocomplete", "shortcuts", "confirm", "confirmDialog", "confirmDrawer", "confirmBrowser", "confirmTabs", "dirtySubmitButton", "submit", "successDelay", "errorDelay", "tabGroup", "deactivationGuard"], outputs: ["fsForm", "invalid", "valid", "submitted", "reseted", "cleared"], exportAs: ["fsForm"] }, { kind: "directive", type: i15.FsFormRequiredDirective, selector: "[fsFormRequired],[ngModel][required]", inputs: ["fsFormRequired", "required", "fsFormRequiredMessage"] }, { kind: "directive", type: i15.FsFormNoFsValidatorsDirective, selector: "[ngModel]:not([required]):not([fsFormRequired]):not([fsFormCompare]):not([fsFormDateRange]):not([fsFormEmail]):not([fsFormEmails]):not([fsFormFunction]):not([fsFormGreater]):not([fsFormGreaterEqual]):not([fsFormInteger]):not([fsFormLesser]):not([fsFormMax]):not([fsFormMaxLength]):not([fsFormMin]):not([fsFormMinLength]):not([fsFormNumeric]):not([fsFormPattern]):not([fsFormPhone]):not([fsFormUrl]):not([validate])" }, { kind: "directive", type: i15.FsButtonDirective, selector: "[mat-raised-button]:not([fsFormButtonStandalone]),[mat-button]:not([fsFormButtonStandalone]),[mat-flat-button]:not([fsFormButtonStandalone]),[mat-stroked-button]:not([fsFormButtonStandalone])", inputs: ["name", "dirtySubmit", "form"] }, { kind: "component", type: i16.FsLabelComponent, selector: "fs-label" }, { kind: "component", type: i16.FsLabelFieldComponent, selector: "fs-label-field", inputs: ["bottomMargin", "topMargin", "labelMargin"] }, { kind: "component", type: i16.FsLabelMessageComponent, selector: "fs-label-message" }, { kind: "component", type: i17.FsRadioGroupComponent, selector: "fs-radio-group", inputs: ["orientation", "label", "name", "disabled", "radioPosition", "compareWith", "required"] }, { kind: "component", type: i18.FsMenuComponent, selector: "fs-menu", inputs: ["class", "buttonClass", "buttonType", "buttonColor"], outputs: ["opened", "closed"] }, { kind: "directive", type: i18.FsMenuItemDirective, selector: "fs-menu-group,[fs-menu-item]" }, { kind: "pipe", type: i19.BulkOptionsFilterPipe, name: "builkOptionsFilter" }, { kind: "pipe", type: i20.AclRolePermissionAvailablePipe, name: "aclRolePermissionAvailable" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
251
+ }
252
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FsAclRoleComponent, decorators: [{
253
+ type: Component,
254
+ args: [{ changeDetection: ChangeDetectionStrategy.OnPush, template: "<form fsForm [submit]=\"save\">\n <fs-dialog>\n <ng-container *ngIf=\"aclRole\">\n <div mat-dialog-title>\n <ng-container *ngIf=\"!disabled\">{{ aclRole.id ? 'Edit' : 'Create' }}</ng-container>\n <ng-container *ngIf=\"disabled\">View</ng-container>\n Role\n </div>\n <mat-dialog-content>\n <div class=\"fs-row.gap-large.align-start\">\n <div class=\"fs-column left-column\">\n <mat-form-field> \n <mat-label>Name</mat-label>\n <input\n matInput\n [(ngModel)]=\"aclRole.name\"\n [disabled]=\"disabled\"\n name=\"name\"\n fsFormRequired>\n </mat-form-field>\n\n <mat-form-field>\n <mat-label>Description</mat-label>\n <input\n matInput\n [(ngModel)]=\"aclRole.description\"\n [disabled]=\"disabled\"\n name=\"description\">\n </mat-form-field>\n\n <fs-label-field *ngIf=\"aclRole.id || aclLevels.length === 1; else levels\">\n <fs-label>Level</fs-label>\n {{indexedAclLevels[aclRole.level]}}\n </fs-label-field>\n\n <ng-template #levels>\n <div class=\"level\">\n <fs-radio-group\n [(ngModel)]=\"aclRole.level\"\n [disabled]=\"disabled\"\n (ngModelChange)=\"levelChange()\"\n fsFormRequired\n label=\"Level\"\n orientation=\"vertical\"\n name=\"level\">\n <mat-radio-button\n *ngFor=\"let item of aclLevels\"\n [value]=\"item.value\"\n [disabled]=\"!!aclRole.protected\">\n {{ item.name }}\n </mat-radio-button>\n </fs-radio-group>\n </div>\n </ng-template>\n\n <fs-label-field *ngIf=\"levelPermissions.length\">\n <fs-label>All Permissions</fs-label>\n <mat-checkbox\n [(ngModel)]=\"aclRole.allPermissions\"\n (ngModelChange)=\"allPermissionsChange($event)\"\n [disabled]=\"!!aclRole.protected || disabled\"\n name=\"allPermissions\">\n Enable\n </mat-checkbox>\n </fs-label-field>\n\n <div class=\"fs-column\" *ngFor=\"let roleConfig of roleConfigs\">\n <fs-label-field *ngIf=\"roleConfig.type === 'checkbox'\">\n <fs-label>{{roleConfig.label}}</fs-label>\n <mat-checkbox\n [(ngModel)]=\"aclRoleConfigValues[roleConfig.name]\"\n [disabled]=\"disabled\"\n [name]=\"roleConfig.name\">\n Enable\n </mat-checkbox>\n <fs-label-message>\n <mat-hint>{{roleConfig.description}}</mat-hint>\n </fs-label-message>\n </fs-label-field>\n\n <mat-form-field *ngIf=\"roleConfig.type === 'select'\">\n <mat-select\n [(ngModel)]=\"aclRoleConfigValues[roleConfig.name]\"\n [name]=\"roleConfig.name\"\n [required]=\"roleConfig.required\"\n [disabled]=\"disabled\"\n [placeholder]=\"roleConfig.label\">\n <mat-option\n *ngFor=\"let item of roleConfig.values\"\n [value]=\"item.value\">\n {{ item.name }}\n </mat-option>\n </mat-select>\n <mat-hint>{{roleConfig.description}}</mat-hint>\n </mat-form-field>\n </div>\n </div>\n\n <div *ngIf=\"aclRole.level\" [hidden]=\"!levelPermissions.length\" class=\"permissions fs-column\">\n <fs-list [config]=\"listConfig\">\n <fs-list-column title=\"Permissions\">\n <ng-template fs-list-group-cell let-row=\"row\" class=\"permission-group\">\n <div class=\"permission-group\">{{row.category || 'General'}}</div>\n </ng-template>\n <ng-template fs-list-cell let-row=\"row\">\n <div class=\"permission\">{{ row.name }}</div>\n <div class=\"description small\">{{ row.description }}</div>\n </ng-template>\n </fs-list-column>\n <fs-list-column title=\"Access\" width=\"1%\" class=\"access\">\n <ng-template \n fs-list-group-cell\n let-row=\"row\"\n let-group=\"group\"\n let-groupChildren=\"groupChildren\"\n class=\"permission-group\"\n align=\"right\">\n <ng-container *ngIf=\"!aclRole.allPermissions && !disabled\">\n <fs-menu>\n <ng-container *ngFor=\"let access of AclRoleAccesses | builkOptionsFilter: groupChildren\">\n <ng-template\n fs-menu-item\n (click)=\"bulkChange(access.value, groupChildren, group)\">\n {{ access.name }}\n </ng-template>\n </ng-container>\n </fs-menu>\n </ng-container>\n </ng-template>\n <ng-template fs-list-cell let-row=\"permission\" let-permission=\"row\">\n <span *ngIf=\"aclRole.allPermissions || disabled; else elseAll\">\n {{indexedAccesses[aclRolePermissions[permission.value]]}}\n </span>\n <ng-template #elseAll>\n <ng-container *ngIf=\"permission|aclRolePermissionAvailable:aclRolePermissions; else permissionRequires\">\n <mat-form-field>\n <mat-select\n [(ngModel)]=\"aclRolePermissions[permission.value]\"\n [disabled]=\"!!aclRole.protected\"\n required\n [name]=\"'access-' + permission.value\"\n (ngModelChange)=\"permissionChange()\">\n <ng-container *ngFor=\"let access of AclRoleAccesses\">\n <mat-option\n *ngIf=\"access.value === 0 || permission.accesses.indexOf(access.value) !== -1\"\n [value]=\"access.value\">\n {{access.name}}\n </mat-option>\n </ng-container>\n </mat-select>\n </mat-form-field>\n </ng-container>\n <ng-template #permissionRequires>\n Unavailable\n </ng-template>\n </ng-template>\n </ng-template>\n </fs-list-column>\n </fs-list>\n </div>\n </div>\n </mat-dialog-content>\n <mat-dialog-actions>\n <button\n *ngIf=\"!disabled\"\n #submit\n mat-button\n type=\"submit\"\n color=\"primary\">\n {{ aclRole.id ? 'Save' : 'Create' }}\n </button>\n <button mat-button [mat-dialog-close]=\"null\" type=\"button\">{{ disabled ? 'Done' : 'Cancel' }}</button>\n </mat-dialog-actions>\n </ng-container>\n </fs-dialog>\n</form>\n", styles: [".permissions{flex:1}.permissions ::ng-deep .fs-list-row-group{background-color:#e4e4e4;font-size:112%}.permissions ::ng-deep fs-list .access{white-space:nowrap}.permissions ::ng-deep .mat-form-field{width:100px}.permissions ::ng-deep .mat-form-field .mat-form-field-wrapper{padding-bottom:0}.permissions ::ng-deep .mat-form-field .mat-form-field-infix{border-top:0}.permissions ::ng-deep .mat-form-field .mat-form-field-underline{bottom:0}.permissions ::ng-deep fs-radio-group{width:100%}.permissions ::ng-deep fs-label-field{width:100%}.permissions .level{width:100%}.left-column{width:40%;max-width:400px}\n"] }]
255
+ }], ctorParameters: function () { return [{ type: undefined, decorators: [{
256
+ type: Inject,
257
+ args: [MAT_DIALOG_DATA]
258
+ }] }, { type: i1.FsAppAclService }, { type: i2.MatDialogRef }, { type: i3.FsMessage }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { list: [{
259
+ type: ViewChild,
260
+ args: [FsListComponent]
261
+ }], submitButton: [{
262
+ type: ViewChild,
263
+ args: ['submit', { static: false }]
264
+ }] } });
265
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWNsLXJvbGUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9jb21wb25lbnRzL2FjbC1yb2xlL2FjbC1yb2xlLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvY29tcG9uZW50cy9hY2wtcm9sZS9hY2wtcm9sZS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsTUFBTSxFQUdOLFNBQVMsRUFDVixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsZUFBZSxFQUFFLFlBQVksRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBRXpFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUVuRSxPQUFPLEVBQUUsU0FBUyxFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRWhELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNoRCxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDMUMsT0FBTyxFQUFFLGVBQWUsRUFBZ0IsTUFBTSxrQkFBa0IsQ0FBQztBQUVqRSxPQUFPLEVBQUUsUUFBUSxFQUFjLEVBQUUsRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDekQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBRW5FLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUM1RCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sMEJBQTBCLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFRckQsTUFBTSxPQUFPLGtCQUFrQjtJQTRCZTtJQUN6QjtJQUNBO0lBQ0E7SUFDVDtJQTdCSCxJQUFJLENBQWtCO0lBR3RCLFlBQVksQ0FBWTtJQUV4QixPQUFP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QUFDLFFBQVEsRUFBRSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgSW5qZWN0LFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbiAgVmlld0NoaWxkXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgTUFUX0RJQUxPR19EQVRBLCBNYXREaWFsb2dSZWYgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9kaWFsb2cnO1xuXG5pbXBvcnQgeyBBY2xSb2xlQWNjZXNzZXMgfSBmcm9tICcuLy4uLy4uL2NvbnN0cy9hY2wtcm9sZS1hY2Nlc3Nlcyc7XG5pbXBvcnQgeyBBY2xSb2xlIH0gZnJvbSAnLi8uLi8uLi9pbnRlcmZhY2VzL2FjbC1yb2xlJztcbmltcG9ydCB7IHRha2VVbnRpbCwgdGFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyBGc01lc3NhZ2UgfSBmcm9tICdAZmlyZXN0aXRjaC9tZXNzYWdlJztcbmltcG9ydCB7IGxpc3QgfSBmcm9tICdAZmlyZXN0aXRjaC9jb21tb24nO1xuaW1wb3J0IHsgRnNMaXN0Q29tcG9uZW50LCBGc0xpc3RDb25maWcgfSBmcm9tICdAZmlyZXN0aXRjaC9saXN0JztcblxuaW1wb3J0IHsgZm9ya0pvaW4sIE9ic2VydmFibGUsIG9mLCBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBGc0FwcEFjbFNlcnZpY2UgfSBmcm9tICcuLy4uLy4uL3NlcnZpY2VzL2FwcC1hY2wuc2VydmljZSc7XG5pbXBvcnQgeyBSb2xlQ29uZmlnIH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcyc7XG5pbXBvcnQgeyBBY2xSb2xlQWNjZXNzIH0gZnJvbSAnLi4vLi4vZW51bXMvYWNsLXJvbGUtYWNjZXNzJztcbmltcG9ydCB7IE1hdEJ1dHRvbiB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2J1dHRvbic7XG5cblxuQENvbXBvbmVudCh7XG4gIHRlbXBsYXRlVXJsOiAnLi9hY2wtcm9sZS5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2FjbC1yb2xlLmNvbXBvbmVudC5zY3NzJ10sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxufSlcbmV4cG9ydCBjbGFzcyBGc0FjbFJvbGVDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSB7XG5cbiAgQFZpZXdDaGlsZChGc0xpc3RDb21wb25lbnQpXG4gIHB1YmxpYyBsaXN0OiBGc0xpc3RDb21wb25lbnQ7XG5cbiAgQFZpZXdDaGlsZCgnc3VibWl0JywgeyBzdGF0aWM6IGZhbHNlIH0pXG4gIHB1YmxpYyBzdWJtaXRCdXR0b246IE1hdEJ1dHRvbjtcblxuICBwdWJsaWMgYWNsUm9sZTogQWNsUm9sZSA9IG51bGw7XG4gIHB1YmxpYyBlbnZpcm9ubWVudDtcbiAgcHVibGljIHBlcm1pc3Npb25zOiBhbnlbXSA9IFtdO1xuICBwdWJsaWMgbGlzdENvbmZpZzogRnNMaXN0Q29uZmlnO1xuICBwdWJsaWMgbGV2ZWxQZXJtaXNzaW9ucyA9IFtdO1xuICBwdWJsaWMgQWNsUm9sZUFjY2Vzc2VzID0gQWNsUm9sZUFjY2Vzc2VzO1xuICBwdWJsaWMgaW5kZXhlZEFjY2Vzc2VzID0ge307XG4gIHB1YmxpYyBhY2xMZXZlbHM6IGFueVtdID0gW107XG4gIHB1YmxpYyBpbmRleGVkQWNsTGV2ZWxzID0ge307XG4gIHB1YmxpYyBvbmx5RnVsbEFjY2VzcyA9IGZhbHNlO1xuICBwdWJsaWMgQWNsTGV2ZWxzID0ge307XG4gIHB1YmxpYyByb2xlQ29uZmlnczogUm9sZUNvbmZpZ1tdID0gW107XG4gIHB1YmxpYyBhY2xSb2xlQ29uZmlnVmFsdWVzID0ge307XG4gIHB1YmxpYyBhY2xSb2xlUGVybWlzc2lvbnMgPSB7fTtcbiAgcHVibGljIGxvYWRSb2xlQ29uZmlnczogKGFjbFJvbGU6IEFjbFJvbGUsIHF1ZXJ5KSA9PiBPYnNlcnZhYmxlPFJvbGVDb25maWdbXT47XG4gIHB1YmxpYyBkaXNhYmxlZDogYm9vbGVhbjtcblxuICBwcml2YXRlIF9kZXN0cm95JCA9IG5ldyBTdWJqZWN0KCk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgQEluamVjdChNQVRfRElBTE9HX0RBVEEpIHByaXZhdGUgcmVhZG9ubHkgX2RhdGE6IGFueSxcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9hcHBBY2xTZXJ2aWNlOiBGc0FwcEFjbFNlcnZpY2UsXG4gICAgcHJpdmF0ZSByZWFkb25seSBfZGlhbG9nUmVmOiBNYXREaWFsb2dSZWY8RnNBY2xSb2xlQ29tcG9uZW50PixcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9tZXNzYWdlOiBGc01lc3NhZ2UsXG4gICAgcHJpdmF0ZSBfY2RSZWY6IENoYW5nZURldGVjdG9yUmVmLFxuICApIHsgfVxuXG4gIHB1YmxpYyBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICBmb3JrSm9pbihcbiAgICAgIHRoaXMuZ2V0Um9sZSgpLFxuICAgICAgdGhpcy5fYXBwQWNsU2VydmljZS5nZXRQZXJtaXNzaW9ucygpLFxuICAgIClcbiAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLl9kZXN0cm95JCkpXG4gICAgICAuc3Vic2NyaWJlKChbXG4gICAgICAgIGFjbFJvbGUsXG4gICAgICAgIGFjbFBlcm1pc3Npb25zLFxuICAgICAgXSkgPT4ge1xuXG4gICAgICAgIHRoaXMucGVybWlzc2lvbnMgPSBhY2xQZXJtaXNzaW9ucztcbiAgICAgICAgdGhpcy5hY2xMZXZlbHMgPSB0aGlzLl9kYXRhLmFjbExldmVscztcbiAgICAgICAgdGhpcy5kaXNhYmxlZCA9IHRoaXMuX2RhdGEuZGlzYWJsZWQ7XG5cbiAgICAgICAgdGhpcy5pbmRleGVkQWNsTGV2ZWxzID0gbGlzdCh0aGlzLmFjbExldmVscywgJ25hbWUnLCAndmFsdWUnKTtcbiAgICAgICAgdGhpcy5pbmRleGVkQWNjZXNzZXMgPSBsaXN0KEFjbFJvbGVBY2Nlc3NlcywgJ25hbWUnLCAndmFsdWUnKTtcblxuICAgICAgICB0aGlzLmFjbFJvbGUgPSB7XG4gICAgICAgICAgLi4ue1xuICAgICAgICAgICAgYWNsUGVybWlzc2lvbnM6IFtdLFxuICAgICAgICAgICAgYWxsUGVybWlzc2lvbnM6IHRydWUsXG4gICAgICAgICAgICBhY2xSb2xlQ29uZmlnczogW10sXG4gICAgICAgICAgICBwZXJtaXNzaW9uczoge30sXG4gICAgICAgICAgICBsZXZlbDogdGhpcy5hY2xMZXZlbHNbMF0udmFsdWUsXG4gICAgICAgICAgfSxcbiAgICAgICAgICAuLi5hY2xSb2xlLFxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMuYWNsUm9sZUNvbmZpZ1ZhbHVlcyA9IChhY2xSb2xlLmFjbFJvbGVDb25maWdzIHx8IFtdKVxuICAgICAgICAgIC5yZWR1Y2UoKGFjY3VtLCBhY2xSb2xlQ29uZmlnKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAuLi5hY2N1bSxcbiAgICAgICAgICAgICAgW2FjbFJvbGVDb25maWcubmFtZV06IGFjbFJvbGVDb25maWcudmFsdWUsXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSwge30pO1xuXG4gICAgICAgIGlmICh0aGlzLmFjbFJvbGUuaWQpIHtcbiAgICAgICAgICB0aGlzLnBlcm1pc3Npb25zLmZvckVhY2goKHBlcm1pc3Npb24pID0+IHtcbiAgICAgICAgICAgIGxldCBhY2Nlc3MgPSAwO1xuXG4gICAgICAgICAgICBjb25zdCBhY2xQZXJtaXNzaW9uID0gdGhpcy5hY2xSb2xlLmFjbFBlcm1pc3Npb25zLmZpbmQoKGl0ZW0pID0+IHtcbiAgICAgICAgICAgICAgcmV0dXJuIGl0ZW0ucGVybWlzc2lvbiA9PT0gcGVybWlzc2lvbi52YWx1ZTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBpZiAoYWNsUGVybWlzc2lvbikge1xuICAgICAgICAgICAgICBhY2Nlc3MgPSBhY2xQZXJtaXNzaW9uLmFjY2VzcztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5hY2xSb2xlUGVybWlzc2lvbnNbcGVybWlzc2lvbi52YWx1ZV0gPSBhY2Nlc3M7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5hY2xSb2xlLmFsbFBlcm1pc3Npb25zKSB7XG4gICAgICAgICAgdGhpcy5fYXBwbHlNYXhQZXJtaXNzaW9uQWNjZXNzKCk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl91cGRhdGVQZXJtaXNzaW9ucygpO1xuICAgICAgICB0aGlzLl91cGRhdGVSb2xlQ29uZmlncygpO1xuXG4gICAgICAgIHRoaXMuX2NkUmVmLm1hcmtGb3JDaGVjaygpO1xuICAgICAgfSk7XG5cbiAgICB0aGlzLmxpc3RDb25maWcgPSB7XG4gICAgICBzdGF0dXM6IGZhbHNlLFxuICAgICAgcGFnaW5nOiBmYWxzZSxcbiAgICAgIHJvd0hvdmVySGlnaGxpZ2h0OiBmYWxzZSxcbiAgICAgIG5vUmVzdWx0czoge1xuICAgICAgICBtZXNzYWdlOiAnJyxcbiAgICAgIH0sXG4gICAgICBncm91cDoge1xuICAgICAgICBpbml0aWFsRXhwYW5kOiB0cnVlLFxuICAgICAgICBncm91cEJ5OiAoZGF0YSkgPT4ge1xuICAgICAgICAgIHJldHVybiBkYXRhO1xuICAgICAgICB9LFxuICAgICAgICBjb21wYXJlQnk6IChkYXRhKSA9PiB7XG4gICAgICAgICAgcmV0dXJuIGRhdGEuY2F0ZWdvcnkgfHwgJ0dlbmVyYWwnO1xuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIGZldGNoOiAoKSA9PiB7XG4gICAgICAgIHJldHVybiBvZih7XG4gICAgICAgICAgZGF0YTogdGhpcy5sZXZlbFBlcm1pc3Npb25zLnNvcnQoKGEsIGIpID0+IHtcbiAgICAgICAgICAgIGEgPSBhLm5hbWUudG9VcHBlckNhc2UoKTtcbiAgICAgICAgICAgIGIgPSBiLm5hbWUudG9VcHBlckNhc2UoKTtcbiAgICAgICAgICAgIGlmIChhIDwgYikge1xuICAgICAgICAgICAgICByZXR1cm4gLTE7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGEgPiBiKSB7XG4gICAgICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgICB9KSxcbiAgICAgICAgfSk7XG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICBwdWJsaWMgYnVsa0NoYW5nZSh2YWx1ZTogbnVtYmVyLCBncm91cENoaWxkcmVuLCBncm91cCk6IHZvaWQge1xuICAgIGdyb3VwQ2hpbGRyZW5cbiAgICAgIC5mb3JFYWNoKChwZXJtaXNzaW9uKSA9PiB7XG4gICAgICAgIGNvbnN0IGFjY2VzcyA9IHBlcm1pc3Npb24uYWNjZXNzZXNcbiAgICAgICAgICAuZmluZCgoYWNjZXNzKSA9PiB2YWx1ZSA9PT0gYWNjZXNzKTtcblxuICAgICAgICBpZihhY2Nlc3MgfHwgIXZhbHVlKSB7XG4gICAgICAgICAgdGhpcy5hY2xSb2xlUGVybWlzc2lvbnNbcGVybWlzc2lvbi52YWx1ZV0gPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMuc3VibWl0QnV0dG9uLmRpc2FibGVkID0gZmFsc2U7XG4gICAgICB0aGlzLnBlcm1pc3Npb25DaGFuZ2UoKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBwZXJtaXNzaW9uQ2hhbmdlKCk6IHZvaWQge1xuICAgIHRoaXMuYWNsUm9sZVBlcm1pc3Npb25zID0ge1xuICAgICAgLi4udGhpcy5hY2xSb2xlUGVybWlzc2lvbnMsICAgICAgICBcbiAgICB9O1xuICAgIHRoaXMuX2NkUmVmLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgcHVibGljIGxldmVsQ2hhbmdlKCk6IHZvaWQge1xuICAgIHRoaXMuX3VwZGF0ZVBlcm1pc3Npb25zKCk7XG4gICAgdGhpcy5fdXBkYXRlUm9sZUNvbmZpZ3MoKTtcbiAgICB0aGlzLmxpc3QucmVsb2FkKCk7XG4gIH1cblxuICBwdWJsaWMgZ2V0Um9sZSgpOiBPYnNlcnZhYmxlPGFueT4ge1xuICAgIGlmICghdGhpcy5fZGF0YS5hY2xSb2xlLmlkKSB7XG4gICAgICByZXR1cm4gb2YodGhpcy5fZGF0YS5hY2xSb2xlKTtcbiAgICB9XG5cbiAgICBjb25zdCBxdWVyeTogYW55ID0ge1xuICAgICAgYWNsUGVybWlzc2lvbnM6IHRydWUsXG4gICAgICBhY2xSb2xlQ29uZmlnczogdHJ1ZSxcbiAgICB9O1xuXG4gICAgaWYgKCF0aGlzLmVudmlyb25tZW50KSB7XG4gICAgICBxdWVyeS5lbnZpcm9ubWVudElkID0gbnVsbDtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5fZGF0YS5sb2FkQWNsUm9sZSh0aGlzLl9kYXRhLmFjbFJvbGUsIHF1ZXJ5KTtcbiAgfVxuXG4gIHB1YmxpYyBzYXZlID0gKCk6IE9ic2VydmFibGU8YW55PiA9PiB7XG4gICAgY29uc3QgYWNsUm9sZUNvbmZpZ3MgPSB0aGlzLnJvbGVDb25maWdzXG4gICAgICAubWFwKChyb2xlQ29uZmlnKSA9PiB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgbmFtZTogcm9sZUNvbmZpZy5uYW1lLFxuICAgICAgICAgIHZhbHVlOiB0aGlzLmFjbFJvbGVDb25maWdWYWx1ZXNbcm9sZUNvbmZpZy5uYW1lXSxcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICBjb25zdCBhY2xSb2xlID0ge1xuICAgICAgLi4udGhpcy5hY2xSb2xlLFxuICAgICAgcGVybWlzc2lvbnM6IHRoaXMubGV2ZWxQZXJtaXNzaW9ucy5tYXAoKHBlcm1pc3Npb24pID0+IHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICB2YWx1ZTogcGVybWlzc2lvbi52YWx1ZSxcbiAgICAgICAgICBhY2Nlc3M6IHRoaXMuYWNsUm9sZVBlcm1pc3Npb25zW3Blcm1pc3Npb24udmFsdWVdIHx8IDAsXG4gICAgICAgIH07XG4gICAgICB9KSxcbiAgICAgIGFjbFJvbGVDb25maWdzLFxuICAgIH07XG5cbiAgICByZXR1cm4gdGhpcy5fZGF0YS5zYXZlQWNsUm9sZShhY2xSb2xlKVxuICAgICAgLnBpcGUoXG4gICAgICAgIHRhcCgocmVzcG9uc2UpID0+IHtcbiAgICAgICAgICB0aGlzLl9tZXNzYWdlLnN1Y2Nlc3MoJ1NhdmVkIENoYW5nZXMnKTtcbiAgICAgICAgICB0aGlzLmNsb3NlKHJlc3BvbnNlKTtcbiAgICAgICAgfSksXG4gICAgICApO1xuICB9XG5cbiAgcHVibGljIGNsb3NlKGRhdGE6IGFueSA9IG51bGwpOiB2b2lkIHtcbiAgICB0aGlzLl9kaWFsb2dSZWYuY2xvc2UoZGF0YSk7XG4gIH1cblxuICBwdWJsaWMgYWxsUGVybWlzc2lvbnNDaGFuZ2UoYWxsOiBib29sZWFuKTogdm9pZCB7XG4gICAgdGhpcy5fdXBkYXRlUGVybWlzc2lvbnMoKTtcbiAgICBpZiAoYWxsKSB7XG4gICAgICB0aGlzLl9hcHBseU1heFBlcm1pc3Npb25BY2Nlc3MoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fYXBwbHlOb25lUGVybWlzc2lvbkFjY2VzcygpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLl9kZXN0cm95JC5uZXh0KCk7XG4gICAgdGhpcy5fZGVzdHJveSQuY29tcGxldGUoKTtcbiAgfVxuXG4gIHByaXZhdGUgX3VwZGF0ZVBlcm1pc3Npb25zKCk6IHZvaWQge1xuICAgIHRoaXMubGV2ZWxQZXJtaXNzaW9ucyA9IHRoaXMucGVybWlzc2lvbnNcbiAgICAuZmlsdGVyKChwZXJtaXNzaW9uKSA9PiB7XG4gICAgICByZXR1cm4gcGVybWlzc2lvbi5sZXZlbHMuc29tZSgoaXRlbSkgPT4ge1xuICAgICAgICByZXR1cm4gaXRlbSA9PT0gdGhpcy5hY2xSb2xlLmxldmVsO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIF91cGRhdGVSb2xlQ29uZmlncygpOiB2b2lkIHtcbiAgICBpZih0aGlzLl9kYXRhLmxvYWRSb2xlQ29uZmlncykge1xuICAgICAgdGhpcy5fZGF0YS5sb2FkUm9sZUNvbmZpZ3MoKVxuICAgICAgLnN1YnNjcmliZSgocm9sZUNvbmZpZ3M6IFJvbGVDb25maWdbXSkgPT4ge1xuICAgICAgICB0aGlzLnJvbGVDb25maWdzID0gcm9sZUNvbmZpZ3NcbiAgICAgICAgICAuZmlsdGVyKChyb2xlQ29uZmlnKSA9PiByb2xlQ29uZmlnLmxldmVsID09PSB0aGlzLmFjbFJvbGUubGV2ZWwpO1xuICAgICAgICB0aGlzLl9jZFJlZi5tYXJrRm9yQ2hlY2soKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX2FwcGx5TWF4UGVybWlzc2lvbkFjY2VzcygpOiB2b2lkIHtcbiAgICB0aGlzLnBlcm1pc3Npb25zLmZvckVhY2goKHBlcm1pc3Npb24pID0+IHtcbiAgICAgIHRoaXMuYWNsUm9sZVBlcm1pc3Npb25zW3Blcm1pc3Npb24udmFsdWVdID0gTWF0aC5tYXgoLi4ucGVybWlzc2lvbi5hY2Nlc3Nlcyk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIF9hcHBseU5vbmVQZXJtaXNzaW9uQWNjZXNzKCk6IHZvaWQge1xuICAgIHRoaXMucGVybWlzc2lvbnMuZm9yRWFjaCgocGVybWlzc2lvbikgPT4ge1xuICAgICAgdGhpcy5hY2xSb2xlUGVybWlzc2lvbnNbcGVybWlzc2lvbi52YWx1ZV0gPSBBY2xSb2xlQWNjZXNzLk5vbmU7XG4gICAgfSk7XG4gIH1cblxufVxuIiwiPGZvcm0gZnNGb3JtIFtzdWJtaXRdPVwic2F2ZVwiPlxuICA8ZnMtZGlhbG9nPlxuICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJhY2xSb2xlXCI+XG4gICAgICA8ZGl2IG1hdC1kaWFsb2ctdGl0bGU+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhZGlzYWJsZWRcIj57eyBhY2xSb2xlLmlkID8gJ0VkaXQnIDogJ0NyZWF0ZScgfX08L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImRpc2FibGVkXCI+VmlldzwvbmctY29udGFpbmVyPlxuICAgICAgICBSb2xlXG4gICAgICA8L2Rpdj5cbiAgICAgIDxtYXQtZGlhbG9nLWNvbnRlbnQ+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJmcy1yb3cuZ2FwLWxhcmdlLmFsaWduLXN0YXJ0XCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImZzLWNvbHVtbiBsZWZ0LWNvbHVtblwiPlxuICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkPiAgICAgICAgICAgIFxuICAgICAgICAgICAgICA8bWF0LWxhYmVsPk5hbWU8L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgbWF0SW5wdXRcbiAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cImFjbFJvbGUubmFtZVwiXG4gICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImRpc2FibGVkXCJcbiAgICAgICAgICAgICAgICBuYW1lPVwibmFtZVwiXG4gICAgICAgICAgICAgICAgZnNGb3JtUmVxdWlyZWQ+XG4gICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuXG4gICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgIDxtYXQtbGFiZWw+RGVzY3JpcHRpb248L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgbWF0SW5wdXRcbiAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cImFjbFJvbGUuZGVzY3JpcHRpb25cIlxuICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJkaXNhYmxlZFwiXG4gICAgICAgICAgICAgICAgbmFtZT1cImRlc2NyaXB0aW9uXCI+XG4gICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuXG4gICAgICAgICAgICA8ZnMtbGFiZWwtZmllbGQgKm5nSWY9XCJhY2xSb2xlLmlkIHx8IGFjbExldmVscy5sZW5ndGggPT09IDE7IGVsc2UgbGV2ZWxzXCI+XG4gICAgICAgICAgICAgIDxmcy1sYWJlbD5MZXZlbDwvZnMtbGFiZWw+XG4gICAgICAgICAgICAgIHt7aW5kZXhlZEFjbExldmVsc1thY2xSb2xlLmxldmVsXX19XG4gICAgICAgICAgICA8L2ZzLWxhYmVsLWZpZWxkPlxuXG4gICAgICAgICAgICA8bmctdGVtcGxhdGUgI2xldmVscz5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImxldmVsXCI+XG4gICAgICAgICAgICAgICAgPGZzLXJhZGlvLWdyb3VwXG4gICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwiYWNsUm9sZS5sZXZlbFwiXG4gICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJkaXNhYmxlZFwiXG4gICAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cImxldmVsQ2hhbmdlKClcIlxuICAgICAgICAgICAgICAgICAgICBmc0Zvcm1SZXF1aXJlZFxuICAgICAgICAgICAgICAgICAgICBsYWJlbD1cIkxldmVsXCJcbiAgICAgICAgICAgICAgICAgICAgb3JpZW50YXRpb249XCJ2ZXJ0aWNhbFwiXG4gICAgICAgICAgICAgICAgICAgIG5hbWU9XCJsZXZlbFwiPlxuICAgICAgICAgICAgICAgICAgPG1hdC1yYWRpby1idXR0b25cbiAgICAgICAgICAgICAgICAgICAgICAqbmdGb3I9XCJsZXQgaXRlbSBvZiBhY2xMZXZlbHNcIlxuICAgICAgICAgICAgICAgICAgICAgIFt2YWx1ZV09XCJpdGVtLnZhbHVlXCJcbiAgICAgICAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiISFhY2xSb2xlLnByb3RlY3RlZFwiPlxuICAgICAgICAgICAgICAgICAgICB7eyBpdGVtLm5hbWUgfX1cbiAgICAgICAgICAgICAgICAgIDwvbWF0LXJhZGlvLWJ1dHRvbj5cbiAgICAgICAgICAgICAgICA8L2ZzLXJhZGlvLWdyb3VwPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICAgICAgICAgIDxmcy1sYWJlbC1maWVsZCAqbmdJZj1cImxldmVsUGVybWlzc2lvbnMubGVuZ3RoXCI+XG4gICAgICAgICAgICAgIDxmcy1sYWJlbD5BbGwgUGVybWlzc2lvbnM8L2ZzLWxhYmVsPlxuICAgICAgICAgICAgICA8bWF0LWNoZWNrYm94XG4gICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cImFjbFJvbGUuYWxsUGVybWlzc2lvbnNcIlxuICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwiYWxsUGVybWlzc2lvbnNDaGFuZ2UoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiISFhY2xSb2xlLnByb3RlY3RlZCB8fCBkaXNhYmxlZFwiXG4gICAgICAgICAgICAgICAgICBuYW1lPVwiYWxsUGVybWlzc2lvbnNcIj5cbiAgICAgICAgICAgICAgICBFbmFibGVcbiAgICAgICAgICAgICAgPC9tYXQtY2hlY2tib3g+XG4gICAgICAgICAgICA8L2ZzLWxhYmVsLWZpZWxkPlxuXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZnMtY29sdW1uXCIgKm5nRm9yPVwibGV0IHJvbGVDb25maWcgb2Ygcm9sZUNvbmZpZ3NcIj5cbiAgICAgICAgICAgICAgPGZzLWxhYmVsLWZpZWxkICpuZ0lmPVwicm9sZUNvbmZpZy50eXBlID09PSAnY2hlY2tib3gnXCI+XG4gICAgICAgICAgICAgICAgPGZzLWxhYmVsPnt7cm9sZUNvbmZpZy5sYWJlbH19PC9mcy1sYWJlbD5cbiAgICAgICAgICAgICAgICA8bWF0LWNoZWNrYm94XG4gICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwiYWNsUm9sZUNvbmZpZ1ZhbHVlc1tyb2xlQ29uZmlnLm5hbWVdXCJcbiAgICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImRpc2FibGVkXCJcbiAgICAgICAgICAgICAgICAgICAgW25hbWVdPVwicm9sZUNvbmZpZy5uYW1lXCI+XG4gICAgICAgICAgICAgICAgICBFbmFibGVcbiAgICAgICAgICAgICAgICA8L21hdC1jaGVja2JveD5cbiAgICAgICAgICAgICAgICA8ZnMtbGFiZWwtbWVzc2FnZT5cbiAgICAgICAgICAgICAgICAgIDxtYXQtaGludD57e3JvbGVDb25maWcuZGVzY3JpcHRpb259fTwvbWF0LWhpbnQ+XG4gICAgICAgICAgICAgICAgPC9mcy1sYWJlbC1tZXNzYWdlPlxuICAgICAgICAgICAgICA8L2ZzLWxhYmVsLWZpZWxkPlxuXG4gICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCAqbmdJZj1cInJvbGVDb25maWcudHlwZSA9PT0gJ3NlbGVjdCdcIj5cbiAgICAgICAgICAgICAgICA8bWF0LXNlbGVjdFxuICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cImFjbFJvbGVDb25maWdWYWx1ZXNbcm9sZUNvbmZpZy5uYW1lXVwiXG4gICAgICAgICAgICAgICAgICAgIFtuYW1lXT1cInJvbGVDb25maWcubmFtZVwiXG4gICAgICAgICAgICAgICAgICAgIFtyZXF1aXJlZF09XCJyb2xlQ29uZmlnLnJlcXVpcmVkXCJcbiAgICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImRpc2FibGVkXCJcbiAgICAgICAgICAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cInJvbGVDb25maWcubGFiZWxcIj5cbiAgICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgKm5nRm9yPVwibGV0IGl0ZW0gb2Ygcm9sZUNvbmZpZy52YWx1ZXNcIlxuICAgICAgICAgICAgICAgICAgICAgIFt2YWx1ZV09XCJpdGVtLnZhbHVlXCI+XG4gICAgICAgICAgICAgICAgICAgIHt7IGl0ZW0ubmFtZSB9fVxuICAgICAgICAgICAgICAgICAgPC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICAgIDwvbWF0LXNlbGVjdD5cbiAgICAgICAgICAgICAgICA8bWF0LWhpbnQ+e3tyb2xlQ29uZmlnLmRlc2NyaXB0aW9ufX08L21hdC1oaW50PlxuICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICA8ZGl2ICpuZ0lmPVwiYWNsUm9sZS5sZXZlbFwiIFtoaWRkZW5dPVwiIWxldmVsUGVybWlzc2lvbnMubGVuZ3RoXCIgY2xhc3M9XCJwZXJtaXNzaW9ucyBmcy1jb2x1bW5cIj5cbiAgICAgICAgICAgIDxmcy1saXN0IFtjb25maWddPVwibGlzdENvbmZpZ1wiPlxuICAgICAgICAgICAgICA8ZnMtbGlzdC1jb2x1bW4gdGl0bGU9XCJQZXJtaXNzaW9uc1wiPlxuICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBmcy1saXN0LWdyb3VwLWNlbGwgbGV0LXJvdz1cInJvd1wiIGNsYXNzPVwicGVybWlzc2lvbi1ncm91cFwiPlxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInBlcm1pc3Npb24tZ3JvdXBcIj57e3Jvdy5jYXRlZ29yeSB8fCAnR2VuZXJhbCd9fTwvZGl2PlxuICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIGZzLWxpc3QtY2VsbCBsZXQtcm93PVwicm93XCI+XG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicGVybWlzc2lvblwiPnt7IHJvdy5uYW1lIH19PC9kaXY+XG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZGVzY3JpcHRpb24gc21hbGxcIj57eyByb3cuZGVzY3JpcHRpb24gfX08L2Rpdj5cbiAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICA8L2ZzLWxpc3QtY29sdW1uPlxuICAgICAgICAgICAgICA8ZnMtbGlzdC1jb2x1bW4gdGl0bGU9XCJBY2Nlc3NcIiB3aWR0aD1cIjElXCIgY2xhc3M9XCJhY2Nlc3NcIj5cbiAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgXG4gICAgICAgICAgICAgICAgICAgIGZzLWxpc3QtZ3JvdXAtY2VsbFxuICAgICAgICAgICAgICAgICAgICBsZXQtcm93PVwicm93XCJcbiAgICAgICAgICAgICAgICAgICAgbGV0LWdyb3VwPVwiZ3JvdXBcIlxuICAgICAgICAgICAgICAgICAgICBsZXQtZ3JvdXBDaGlsZHJlbj1cImdyb3VwQ2hpbGRyZW5cIlxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInBlcm1pc3Npb24tZ3JvdXBcIlxuICAgICAgICAgICAgICAgICAgICBhbGlnbj1cInJpZ2h0XCI+XG4gICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIWFjbFJvbGUuYWxsUGVybWlzc2lvbnMgJiYgIWRpc2FibGVkXCI+XG4gICAgICAgICAgICAgICAgICAgIDxmcy1tZW51PlxuICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGFjY2VzcyBvZiBBY2xSb2xlQWNjZXNzZXMgfCBidWlsa09wdGlvbnNGaWx0ZXI6IGdyb3VwQ2hpbGRyZW5cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZzLW1lbnUtaXRlbVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJidWxrQ2hhbmdlKGFjY2Vzcy52YWx1ZSwgZ3JvdXBDaGlsZHJlbiwgZ3JvdXApXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHt7IGFjY2Vzcy5uYW1lIH19XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICA8L2ZzLW1lbnU+XG4gICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBmcy1saXN0LWNlbGwgbGV0LXJvdz1cInBlcm1pc3Npb25cIiBsZXQtcGVybWlzc2lvbj1cInJvd1wiPlxuICAgICAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJhY2xSb2xlLmFsbFBlcm1pc3Npb25zIHx8IGRpc2FibGVkOyBlbHNlIGVsc2VBbGxcIj5cbiAgICAgICAgICAgICAgICAgICAge3tpbmRleGVkQWNjZXNzZXNbYWNsUm9sZVBlcm1pc3Npb25zW3Blcm1pc3Npb24udmFsdWVdXX19XG4gICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgI2Vsc2VBbGw+XG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJwZXJtaXNzaW9ufGFjbFJvbGVQZXJtaXNzaW9uQXZhaWxhYmxlOmFjbFJvbGVQZXJtaXNzaW9uczsgZWxzZSBwZXJtaXNzaW9uUmVxdWlyZXNcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LXNlbGVjdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwiYWNsUm9sZVBlcm1pc3Npb25zW3Blcm1pc3Npb24udmFsdWVdXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiISFhY2xSb2xlLnByb3RlY3RlZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWlyZWRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmFtZV09XCInYWNjZXNzLScgKyBwZXJtaXNzaW9uLnZhbHVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJwZXJtaXNzaW9uQ2hhbmdlKClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgYWNjZXNzIG9mIEFjbFJvbGVBY2Nlc3Nlc1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiYWNjZXNzLnZhbHVlID09PSAwIHx8IHBlcm1pc3Npb24uYWNjZXNzZXMuaW5kZXhPZihhY2Nlc3MudmFsdWUpICE9PSAtMVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt2YWx1ZV09XCJhY2Nlc3MudmFsdWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7YWNjZXNzLm5hbWV9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjcGVybWlzc2lvblJlcXVpcmVzPlxuICAgICAgICAgICAgICAgICAgICAgIFVuYXZhaWxhYmxlXG4gICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgIDwvZnMtbGlzdC1jb2x1bW4+XG4gICAgICAgICAgICA8L2ZzLWxpc3Q+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9tYXQtZGlhbG9nLWNvbnRlbnQ+XG4gICAgICA8bWF0LWRpYWxvZy1hY3Rpb25zPlxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAqbmdJZj1cIiFkaXNhYmxlZFwiXG4gICAgICAgICAgICAjc3VibWl0XG4gICAgICAgICAgICBtYXQtYnV0dG9uXG4gICAgICAgICAgICB0eXBlPVwic3VibWl0XCJcbiAgICAgICAgICAgIGNvbG9yPVwicHJpbWFyeVwiPlxuICAgICAgICAgIHt7IGFjbFJvbGUuaWQgPyAnU2F2ZScgOiAnQ3JlYXRlJyB9fVxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPGJ1dHRvbiBtYXQtYnV0dG9uIFttYXQtZGlhbG9nLWNsb3NlXT1cIm51bGxcIiB0eXBlPVwiYnV0dG9uXCI+e3sgZGlzYWJsZWQgPyAnRG9uZScgOiAnQ2FuY2VsJyB9fTwvYnV0dG9uPlxuICAgICAgPC9tYXQtZGlhbG9nLWFjdGlvbnM+XG4gICAgPC9uZy1jb250YWluZXI+XG4gIDwvZnMtZGlhbG9nPlxuPC9mb3JtPlxuIl19
@@ -0,0 +1,37 @@
1
+ import { Component, Input } from '@angular/core';
2
+ import { FsAppAclService } from './../../services/app-acl.service';
3
+ import * as i0 from "@angular/core";
4
+ import * as i1 from "./../../services/app-acl.service";
5
+ import * as i2 from "@angular/common";
6
+ import * as i3 from "@firestitch/popover";
7
+ export class FsAclRolePopoverComponent {
8
+ _appAclService;
9
+ aclRole;
10
+ objectName;
11
+ permissions = [];
12
+ constructor(_appAclService) {
13
+ this._appAclService = _appAclService;
14
+ }
15
+ ngOnInit() {
16
+ const aclRolePermissions = this.aclRole.permissions || [];
17
+ this._appAclService.getPermissions()
18
+ .subscribe((response) => {
19
+ this.permissions = response.filter(item => {
20
+ return aclRolePermissions.some(permission => {
21
+ return item.value === permission.value;
22
+ });
23
+ });
24
+ });
25
+ }
26
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FsAclRolePopoverComponent, deps: [{ token: i1.FsAppAclService }], target: i0.ɵɵFactoryTarget.Component });
27
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: FsAclRolePopoverComponent, selector: "fs-acl-role-popover", inputs: { aclRole: "aclRole", objectName: "objectName" }, ngImport: i0, template: "\n<fs-popover [template]=\"popover\" [maxWidth]=\"400\">\n <ng-content></ng-content>\n</fs-popover>\n\n<ng-template #popover>\n <div class=\"name small\">{{aclRole.name}}<span *ngIf=\"objectName\">: {{objectName}}</span></div>\n\n <ng-container *ngIf=\"permissions.length; else nonePermission\">\n <div *ngFor=\"let permission of permissions\" class=\"permission\">\n <div>{{permission.name}}</div>\n <div class=\"small\">{{permission.description}}</div>\n </div>\n </ng-container>\n\n <ng-template #nonePermission>\n None\n </ng-template>\n</ng-template>\n", styles: [".name{padding-bottom:10px}.permission+.permission{padding-top:5px}:host{cursor:pointer}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i3.FsPopoverComponent, selector: "fs-popover" }] });
28
+ }
29
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FsAclRolePopoverComponent, decorators: [{
30
+ type: Component,
31
+ args: [{ selector: 'fs-acl-role-popover', template: "\n<fs-popover [template]=\"popover\" [maxWidth]=\"400\">\n <ng-content></ng-content>\n</fs-popover>\n\n<ng-template #popover>\n <div class=\"name small\">{{aclRole.name}}<span *ngIf=\"objectName\">: {{objectName}}</span></div>\n\n <ng-container *ngIf=\"permissions.length; else nonePermission\">\n <div *ngFor=\"let permission of permissions\" class=\"permission\">\n <div>{{permission.name}}</div>\n <div class=\"small\">{{permission.description}}</div>\n </div>\n </ng-container>\n\n <ng-template #nonePermission>\n None\n </ng-template>\n</ng-template>\n", styles: [".name{padding-bottom:10px}.permission+.permission{padding-top:5px}:host{cursor:pointer}\n"] }]
32
+ }], ctorParameters: function () { return [{ type: i1.FsAppAclService }]; }, propDecorators: { aclRole: [{
33
+ type: Input
34
+ }], objectName: [{
35
+ type: Input
36
+ }] } });
37
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWNsLXJvbGUtcG9wb3Zlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvYXBwL2NvbXBvbmVudHMvYWNsLXJvbGUtcG9wb3Zlci9hY2wtcm9sZS1wb3BvdmVyLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvY29tcG9uZW50cy9hY2wtcm9sZS1wb3BvdmVyL2FjbC1yb2xlLXBvcG92ZXIuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBVSxLQUFLLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDekQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGtDQUFrQyxDQUFDOzs7OztBQU9uRSxNQUFNLE9BQU8seUJBQXlCO0lBUWpCO0lBTlYsT0FBTyxDQUFDO0lBQ1IsVUFBVSxDQUFDO0lBRWIsV0FBVyxHQUFHLEVBQUUsQ0FBQztJQUV4QixZQUNtQixjQUErQjtRQUEvQixtQkFBYyxHQUFkLGNBQWMsQ0FBaUI7SUFDL0MsQ0FBQztJQUVHLFFBQVE7UUFDYixNQUFNLGtCQUFrQixHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxJQUFJLEVBQUUsQ0FBQztRQUUxRCxJQUFJLENBQUMsY0FBYyxDQUFDLGNBQWMsRUFBRTthQUNqQyxTQUFTLENBQUMsQ0FBQyxRQUFRLEVBQUUsRUFBRTtZQUN0QixJQUFJLENBQUMsV0FBVyxHQUFHLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEVBQUU7Z0JBQ3hDLE9BQU8sa0JBQWtCLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxFQUFFO29CQUMxQyxPQUFPLElBQUksQ0FBQyxLQUFLLEtBQUssVUFBVSxDQUFDLEtBQUssQ0FBQztnQkFDekMsQ0FBQyxDQUFDLENBQUM7WUFDUCxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQzt3R0F0QlUseUJBQXlCOzRGQUF6Qix5QkFBeUIscUhDUnRDLHdrQkFtQkE7OzRGRFhhLHlCQUF5QjtrQkFMckMsU0FBUzsrQkFDRSxxQkFBcUI7c0dBTXRCLE9BQU87c0JBQWYsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBPbkluaXQsIElucHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBGc0FwcEFjbFNlcnZpY2UgfSBmcm9tICcuLy4uLy4uL3NlcnZpY2VzL2FwcC1hY2wuc2VydmljZSc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2ZzLWFjbC1yb2xlLXBvcG92ZXInLFxuICB0ZW1wbGF0ZVVybDogJy4vYWNsLXJvbGUtcG9wb3Zlci5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2FjbC1yb2xlLXBvcG92ZXIuY29tcG9uZW50LnNjc3MnXVxufSlcbmV4cG9ydCBjbGFzcyBGc0FjbFJvbGVQb3BvdmVyQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcblxuICBASW5wdXQoKSBhY2xSb2xlO1xuICBASW5wdXQoKSBvYmplY3ROYW1lO1xuXG4gIHB1YmxpYyBwZXJtaXNzaW9ucyA9IFtdO1xuXG4gIHB1YmxpYyBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9hcHBBY2xTZXJ2aWNlOiBGc0FwcEFjbFNlcnZpY2UsXG4gICkge31cblxuICBwdWJsaWMgbmdPbkluaXQoKSB7XG4gICAgY29uc3QgYWNsUm9sZVBlcm1pc3Npb25zID0gdGhpcy5hY2xSb2xlLnBlcm1pc3Npb25zIHx8IFtdO1xuXG4gICAgdGhpcy5fYXBwQWNsU2VydmljZS5nZXRQZXJtaXNzaW9ucygpXG4gICAgICAuc3Vic2NyaWJlKChyZXNwb25zZSkgPT4ge1xuICAgICAgICB0aGlzLnBlcm1pc3Npb25zID0gcmVzcG9uc2UuZmlsdGVyKGl0ZW0gPT4ge1xuICAgICAgICAgIHJldHVybiBhY2xSb2xlUGVybWlzc2lvbnMuc29tZShwZXJtaXNzaW9uID0+IHtcbiAgICAgICAgICAgIHJldHVybiBpdGVtLnZhbHVlID09PSBwZXJtaXNzaW9uLnZhbHVlO1xuICAgICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cbn1cbiIsIlxuPGZzLXBvcG92ZXIgW3RlbXBsYXRlXT1cInBvcG92ZXJcIiBbbWF4V2lkdGhdPVwiNDAwXCI+XG4gIDxuZy1jb250ZW50PjwvbmctY29udGVudD5cbjwvZnMtcG9wb3Zlcj5cblxuPG5nLXRlbXBsYXRlICNwb3BvdmVyPlxuICA8ZGl2IGNsYXNzPVwibmFtZSBzbWFsbFwiPnt7YWNsUm9sZS5uYW1lfX08c3BhbiAqbmdJZj1cIm9iamVjdE5hbWVcIj46IHt7b2JqZWN0TmFtZX19PC9zcGFuPjwvZGl2PlxuXG4gIDxuZy1jb250YWluZXIgKm5nSWY9XCJwZXJtaXNzaW9ucy5sZW5ndGg7IGVsc2Ugbm9uZVBlcm1pc3Npb25cIj5cbiAgICA8ZGl2ICpuZ0Zvcj1cImxldCBwZXJtaXNzaW9uIG9mIHBlcm1pc3Npb25zXCIgY2xhc3M9XCJwZXJtaXNzaW9uXCI+XG4gICAgICA8ZGl2Pnt7cGVybWlzc2lvbi5uYW1lfX08L2Rpdj5cbiAgICAgIDxkaXYgY2xhc3M9XCJzbWFsbFwiPnt7cGVybWlzc2lvbi5kZXNjcmlwdGlvbn19PC9kaXY+XG4gICAgPC9kaXY+XG4gIDwvbmctY29udGFpbmVyPlxuXG4gIDxuZy10ZW1wbGF0ZSAjbm9uZVBlcm1pc3Npb24+XG4gICAgTm9uZVxuICA8L25nLXRlbXBsYXRlPlxuPC9uZy10ZW1wbGF0ZT5cbiJdfQ==