Skip to content

Commit e749259

Browse files
committed
Permissions UI: Misc changes and improvements part 2 #8819
1 parent d32b642 commit e749259

File tree

13 files changed

+278
-233
lines changed

13 files changed

+278
-233
lines changed

modules/lib/src/main/resources/assets/js/app/dialog/permissions/AccessControlChangedItemView.ts

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,12 @@ import {Permission} from '../../access/Permission';
66
import * as Q from 'q';
77
import {PrincipalViewer} from '@enonic/lib-admin-ui/ui/security/PrincipalViewer';
88
import {SpanEl} from '@enonic/lib-admin-ui/dom/SpanEl';
9+
import {EditPermissionState} from './EditPermissionState';
10+
import {AccessHelper} from '../../security/AccessHelper';
11+
import {AccessDiffView} from './AccessDiffView';
12+
import {Access} from '../../security/Access';
913
import {PermissionsHelper} from '../../access/PermissionsHelper';
1014
import {PermissionStateView} from './PermissionStateView';
11-
import {EditPermissionState} from './EditPermissionState';
1215

1316
export class AccessControlChangedItemView
1417
extends DivEl {
@@ -17,14 +20,11 @@ export class AccessControlChangedItemView
1720

1821
private readonly applyTo: ApplyPermissionsScope;
1922

20-
private readonly resetChildPermissions: boolean;
21-
22-
constructor(item: AccessControlChangedItem, applyTo: ApplyPermissionsScope, resetChildPermissions: boolean) {
23+
constructor(item: AccessControlChangedItem, applyTo: ApplyPermissionsScope) {
2324
super('access-control-changed-item-view');
2425

2526
this.item = item;
2627
this.applyTo = applyTo;
27-
this.resetChildPermissions = resetChildPermissions;
2828
}
2929

3030
private getAccessValue(): string {
@@ -67,19 +67,25 @@ export class AccessControlChangedItemView
6767
doRender(): Q.Promise<boolean> {
6868
return super.doRender().then((rendered: boolean) => {
6969
this.addClass(this.applyTo);
70-
this.addClass(this.resetChildPermissions ? 'reset' : 'merge');
7170
this.toggleClass('removed', this.isEntryRemoved());
71+
7272
const principalViewer = new PrincipalViewer();
7373
principalViewer.setObject(this.item.getPrincipal());
7474

7575
const accessEl = new SpanEl('access-control-changed-item-access');
7676
accessEl.setHtml(this.getAccessValue());
7777

78+
const prevPermissions = this.item.getPermissions().persisted;
79+
const fromAccess = prevPermissions ? AccessHelper.getAccessValueFromPermissions(this.item.getPermissions().persisted) : null;
80+
const currentPermissions = this.item.getPermissions().updated;
81+
const toAccess = currentPermissions ? AccessHelper.getAccessValueFromPermissions(this.item.getPermissions().updated) : null;
82+
7883
const principalAndStatusEl = new DivEl('access-control-changed-item-principal-with-status');
79-
principalAndStatusEl.appendChildren(principalViewer, accessEl);
84+
principalAndStatusEl.appendChild(principalViewer);
85+
principalAndStatusEl.appendChildren(new AccessDiffView(fromAccess, toAccess));
8086
this.appendChild(principalAndStatusEl);
8187

82-
if (!this.isEntryRemoved()) {
88+
if (toAccess === Access.CUSTOM) {
8389
const permissionsEl = new DivEl('access-control-changed-item-permissions');
8490

8591
PermissionsHelper.getAllPermissions().forEach(permission => {

modules/lib/src/main/resources/assets/js/app/dialog/permissions/AccessControlChangedItemsList.ts

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ export class AccessControlChangedItemsList
1010

1111
private applyTo: ApplyPermissionsScope;
1212

13-
private resetChildPermissions: boolean;
14-
1513
private originalValues: AccessControlEntry[] = [];
1614

1715
private currentValues: AccessControlEntry[] = [];
@@ -21,7 +19,7 @@ export class AccessControlChangedItemsList
2119
}
2220

2321
protected createItemView(item: AccessControlChangedItem, readOnly: boolean): AccessControlChangedItemView {
24-
return new AccessControlChangedItemView(item, this.applyTo, this.resetChildPermissions);
22+
return new AccessControlChangedItemView(item, this.applyTo);
2523
}
2624

2725
protected getItemId(item: AccessControlChangedItem): string {
@@ -32,26 +30,22 @@ export class AccessControlChangedItemsList
3230
this.applyTo = applyTo;
3331
}
3432

35-
setResetChildPermissions(resetChildPermissions: boolean): void {
36-
this.resetChildPermissions = resetChildPermissions;
37-
}
38-
3933
setOriginalValues(originalValues: AccessControlEntry[]): void {
4034
this.originalValues = originalValues;
4135
}
4236

4337
setCurrentValues(currentValues: AccessControlEntry[]): void {
4438
this.currentValues = currentValues;
45-
this.setItems(this.getChangedItems());
39+
this.setItems(this.calcChangedItems());
4640
}
4741

48-
private getChangedItems(): AccessControlChangedItem[] {
42+
private calcChangedItems(): AccessControlChangedItem[] {
4943
const result: AccessControlChangedItem[] = [];
5044

5145
this.originalValues.forEach((originalVal) => {
5246
const found = this.currentValues.find((currentVal) => originalVal.getPrincipalKey().equals(currentVal.getPrincipalKey()));
5347
if (found) { // item was present before and remains
54-
if (!originalVal.equals(found) || this.isOverwriteForChildren()) { // item's permissions were changed or children to be reset
48+
if (!originalVal.equals(found)) { // item's permissions were changed or || this.isOverwriteForChildren()
5549
result.push(new AccessControlChangedItem(originalVal.getPrincipal(),
5650
{persisted: originalVal.getAllowedPermissions(), updated: found.getAllowedPermissions()}));
5751
}
@@ -72,8 +66,4 @@ export class AccessControlChangedItemsList
7266

7367
return result;
7468
}
75-
76-
private isOverwriteForChildren(): boolean {
77-
return this.applyTo !== 'single' && this.resetChildPermissions;
78-
}
7969
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import {DivEl} from '@enonic/lib-admin-ui/dom/DivEl';
2+
import {SpanEl} from '@enonic/lib-admin-ui/dom/SpanEl';
3+
import {Access, ACCESS_OPTIONS} from '../../security/Access';
4+
import * as Q from 'q';
5+
6+
export class AccessDiffView extends DivEl {
7+
8+
private readonly before?: Access;
9+
10+
private readonly after?: Access;
11+
12+
constructor(before: Access, after: Access) {
13+
super('access-diff-view');
14+
15+
this.before = before;
16+
this.after = after;
17+
}
18+
19+
doRender(): Q.Promise<boolean> {
20+
return super.doRender().then((rendered: boolean) => {
21+
22+
this.calc();
23+
24+
return rendered;
25+
});
26+
}
27+
28+
private calc(): void {
29+
if (!this.before) { // Added
30+
this.showAddedAccess(this.after);
31+
} else if (!this.after) { // Removed
32+
this.showRemovedAccess(this.before);
33+
} else { // modified
34+
if (this.before === this.after) { // for custom access
35+
this.showAddedAccess(this.after);
36+
} else {
37+
this.showModifiedAccess(this.before, this.after);
38+
}
39+
}
40+
}
41+
42+
private showAddedAccess(access: Access): void {
43+
this.appendChild(new SpanEl('access-line added').setHtml(this.getAccessDisplayName(access)));
44+
}
45+
46+
private showRemovedAccess(access: Access): void {
47+
this.appendChild(new SpanEl('access-line removed').setHtml(this.getAccessDisplayName(access)));
48+
}
49+
50+
private showModifiedAccess(fromAccess: Access, toAccess: Access): void {
51+
this.showRemovedAccess(fromAccess);
52+
this.showAddedAccess(toAccess);
53+
}
54+
55+
private getAccessDisplayName(access: Access): string {
56+
return ACCESS_OPTIONS.find((option) => option.id === access.toString()).displayName;
57+
}
58+
59+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import {DdDtEl} from '@enonic/lib-admin-ui/dom/DdDtEl';
2+
import {SpanEl} from '@enonic/lib-admin-ui/dom/SpanEl';
3+
import {i18n} from '@enonic/lib-admin-ui/util/Messages';
4+
5+
export class AccessModeLine
6+
extends DdDtEl {
7+
8+
private hadEveryoneRole: boolean;
9+
10+
private hasEveryoneRole: boolean;
11+
12+
constructor() {
13+
super('dd', 'access-mode-line');
14+
}
15+
16+
setAccessDiff(hadEveryoneRole: boolean, hasEveryoneRole: boolean): void {
17+
this.hadEveryoneRole = hadEveryoneRole;
18+
this.hasEveryoneRole = hasEveryoneRole;
19+
20+
this.updateLine();
21+
}
22+
23+
private updateLine(): void {
24+
if (this.hadEveryoneRole === this.hasEveryoneRole) {
25+
this.setHtml(this.getLabel(this.hasEveryoneRole));
26+
} else {
27+
this.removeChildren();
28+
const oldValueSpan = new SpanEl().setHtml(this.getLabel(this.hadEveryoneRole));
29+
const newValueSpan = new SpanEl().setHtml(this.getLabel(this.hasEveryoneRole));
30+
this.appendChildren(oldValueSpan, newValueSpan);
31+
}
32+
}
33+
34+
private getLabel(hasEveryoneRole: boolean): string {
35+
return hasEveryoneRole ? i18n('dialog.permissions.step.main.access.public') : i18n(
36+
'dialog.permissions.step.main.access.restricted');
37+
}
38+
39+
}

modules/lib/src/main/resources/assets/js/app/dialog/permissions/EditPermissionsDialog.ts

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import {PermissionsData} from './PermissionsData';
2222
import {DialogStep} from '@enonic/lib-admin-ui/ui/dialog/multistep/DialogStep';
2323
import {AccessControlEntry} from '../../access/AccessControlEntry';
2424
import {AccessControlHelper} from '../../wizard/AccessControlHelper';
25+
import {ConfirmationDialog} from '@enonic/lib-admin-ui/ui/dialog/ConfirmationDialog';
2526

2627
export class EditPermissionsDialog
2728
extends MultiStepDialog
@@ -49,6 +50,8 @@ export class EditPermissionsDialog
4950

5051
private totalChildren: number;
5152

53+
private confirmOverwriteDialog: ConfirmationDialog;
54+
5255
constructor() {
5356
super({
5457
steps: [new MainAccessStep(), new StrategyStep(), new SummaryStep()],
@@ -78,7 +81,7 @@ export class EditPermissionsDialog
7881

7982
this.subTitle = new H6El('sub-title').setHtml(`${i18n('dialog.permissions.applying')}...`);
8083

81-
this.secondaryAction = new Action().setEnabled(false);
84+
this.secondaryAction = new Action(i18n('dialog.permissions.step.action.overwrite')).setEnabled(false);
8285

8386
this.menuButton = this.getButtonRow().makeActionMenu({
8487
defaultAction: this.getButtonRow().getActions()[2],
@@ -100,7 +103,13 @@ export class EditPermissionsDialog
100103
});
101104

102105
this.secondaryAction.onExecuted(() => {
103-
this.showStep(this.summaryStep);
106+
this.confirmOverwriteDialog = this.confirmOverwriteDialog ?? new ConfirmationDialog()
107+
.setQuestion(i18n('dialog.permissions.confirm.overwrite.question'))
108+
.setYesCallback(() => {
109+
this.doSubmit(true);
110+
});
111+
112+
this.confirmOverwriteDialog.open();
104113
});
105114

106115
this.mainStep.onDataChanged(() => {
@@ -109,20 +118,16 @@ export class EditPermissionsDialog
109118
this.backActionMirror.setEnabled(isChanged);
110119
this.secondaryAction.setEnabled(isChanged);
111120
});
112-
113-
this.strategyStep.onDataChanged(() => {
114-
this.secondaryAction.setLabel(i18n('dialog.permissions.step.action.submitNow', this.getTotalItemsToApplyTo()));
115-
});
116121
}
117122

118-
protected submit(): void {
123+
protected doSubmit(overwrite: boolean): void {
119124
this.subTitle.show();
120125
const data = this.collectData();
121126
const permissions = new AccessControlList(data.permissions);
122127

123128
const req = new ApplyContentPermissionsRequest().setId(this.contentId).setScope(data.applyTo);
124129

125-
if (data.reset) {
130+
if (overwrite) {
126131
req.setPermissions(permissions);
127132
} else {
128133
const {added, removed} = AccessControlHelper.calcMergePermissions(this.originalValues, data.permissions);
@@ -135,13 +140,16 @@ export class EditPermissionsDialog
135140
}).catch(DefaultErrorHandler.handle).done();
136141
}
137142

143+
protected submit(): void {
144+
this.doSubmit(false);
145+
}
146+
138147
private collectData(): PermissionsData {
139148
const strategyData = this.strategyStep.getData();
140149

141150
return {
142151
permissions: this.mainStep.getData(),
143152
applyTo: strategyData.applyTo,
144-
reset: strategyData.reset,
145153
}
146154
}
147155

@@ -151,7 +159,6 @@ export class EditPermissionsDialog
151159
new GetDescendantsOfContentsRequest(event.getContentPath()).sendAndParse().then((ids) => {
152160
this.totalChildren = ids.length;
153161
this.strategyStep.setTotalChildren(ids.length);
154-
this.secondaryAction.setLabel(i18n('dialog.permissions.step.action.submitNow', this.totalChildren + 1));
155162
}).catch(DefaultErrorHandler.handle);
156163

157164
const parentPath = event.getContentPath().getParentPath();
@@ -179,12 +186,14 @@ export class EditPermissionsDialog
179186
this.getButtonRow().removeClass('last-step');
180187
} else {
181188
const isLastStep = this.isLastStep();
189+
const data = this.collectData();
182190

183191
if (isLastStep) {
184-
this.summaryStep.setCurrentData(this.collectData());
192+
this.summaryStep.setCurrentData(data);
185193
}
186194

187195
this.getButtonRow().toggleClass('last-step', isLastStep);
196+
this.getButtonRow().toggleClass('single', data.applyTo === 'single');
188197
this.backActionMirror.setEnabled(true).setLabel(i18n('dialog.multistep.previous'));
189198
}
190199
}
@@ -233,6 +242,10 @@ export class EditPermissionsDialog
233242
return this.getButtonRow().getActions()[1];
234243
}
235244

245+
protected getSubmitActionLabel(): string {
246+
return i18n('dialog.permissions.step.action.submitNow', this.getTotalItemsToApplyTo());
247+
}
248+
236249
private getTotalItemsToApplyTo(): number {
237250
const applyTo = this.strategyStep.getData().applyTo;
238251

@@ -247,10 +260,6 @@ export class EditPermissionsDialog
247260
return this.totalChildren + 1;
248261
}
249262

250-
protected getSubmitActionLabel(): string {
251-
return i18n('dialog.permissions.step.action.submitNow', this.getTotalItemsToApplyTo());
252-
}
253-
254263
isDirty(): boolean {
255264
return this.mainStep.isAnyPermissionChanged();
256265
}

modules/lib/src/main/resources/assets/js/app/dialog/permissions/PermissionsData.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,4 @@ export type ApplyPermissionsScope = 'single' | 'tree' | 'subtree';
55
export interface PermissionsData {
66
permissions: AccessControlEntry[],
77
applyTo: ApplyPermissionsScope,
8-
reset: boolean,
98
}

0 commit comments

Comments
 (0)