Skip to content

Commit cc8d216

Browse files
committed
Permissions UI: Misc improvements and bugs #8760
1 parent 32b29a1 commit cc8d216

File tree

8 files changed

+86
-41
lines changed

8 files changed

+86
-41
lines changed

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

+40-19
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ export class EditPermissionsDialog
5050

5151
private originalValues: AccessControlEntry[];
5252

53+
private totalChildren: number;
54+
5355
constructor() {
5456
super({
5557
steps: [new MainAccessStep(), new ApplyAccessToStep(), new StrategyStep(), new SummaryStep()],
@@ -102,7 +104,7 @@ export class EditPermissionsDialog
102104
});
103105

104106
this.secondaryAction.onExecuted(() => {
105-
this.submit();
107+
this.showStep(this.summaryStep);
106108
});
107109

108110
this.mainStep.onDataChanged(() => {
@@ -114,6 +116,7 @@ export class EditPermissionsDialog
114116

115117
this.applyToStep.onDataChanged(() => {
116118
this.strategyStep.setApplyTo(this.applyToStep.getData().applyTo);
119+
this.secondaryAction.setLabel(i18n('dialog.permissions.step.action.submitNow', this.getTotalItemsToApplyTo()));
117120
});
118121
}
119122

@@ -134,7 +137,7 @@ export class EditPermissionsDialog
134137

135138
req.sendAndParse().then((taskId) => {
136139
this.pollTask(taskId);
137-
}).done();
140+
}).catch(DefaultErrorHandler.handle).done();
138141
}
139142

140143
private collectData(): PermissionsData {
@@ -149,9 +152,10 @@ export class EditPermissionsDialog
149152
this.contentId = event.getContentId();
150153

151154
new GetDescendantsOfContentsRequest(event.getContentPath()).sendAndParse().then((ids) => {
152-
this.applyToStep.setup(ids.length);
153-
this.strategyStep.setApplyTo(ids.length === 0 ? 'single' : 'tree');
154-
this.secondaryAction.setLabel(i18n('dialog.permissions.step.action.submitNow', ids.length + 1));
155+
this.totalChildren = ids.length;
156+
this.applyToStep.setup(this.totalChildren);
157+
this.strategyStep.setApplyTo(this.totalChildren === 0 ? 'single' : 'tree');
158+
this.secondaryAction.setLabel(i18n('dialog.permissions.step.action.submitNow', this.totalChildren + 1));
155159
}).catch(DefaultErrorHandler.handle);
156160

157161
AccessControlHelper.getParentPermissions(event.getContentPath().getParentPath()).then((parentPermissions: AccessControlList) => {
@@ -172,22 +176,23 @@ export class EditPermissionsDialog
172176
protected showStep(step: DialogStep): void {
173177
super.showStep(step);
174178

175-
const isLastStep = this.isLastStep();
176-
177-
if (isLastStep) {
178-
this.summaryStep.setCurrentData(this.collectData());
179-
}
180-
181-
this.getButtonRow().toggleClass('last-step', isLastStep);
182-
183-
if (step === this.strategyStep) {
184-
this.strategyStep.setCurrentlySelectedItems(this.collectData().permissions);
185-
}
186-
187179
if (this.isFirstStep()) {
188180
this.backActionMirror.setLabel(i18n('dialog.permissions.step.action.reset'));
189181
this.backActionMirror.setEnabled(this.mainStep.isAnyPermissionChanged());
182+
this.getButtonRow().removeClass('last-step');
190183
} else {
184+
const isLastStep = this.isLastStep();
185+
186+
if (isLastStep) {
187+
this.summaryStep.setCurrentData(this.collectData());
188+
}
189+
190+
this.getButtonRow().toggleClass('last-step', isLastStep);
191+
192+
if (step === this.strategyStep) {
193+
this.strategyStep.setCurrentlySelectedItems(this.collectData().permissions);
194+
}
195+
191196
this.backActionMirror.setEnabled(true).setLabel(i18n('dialog.multistep.previous'));
192197
}
193198
}
@@ -200,8 +205,6 @@ export class EditPermissionsDialog
200205
super.handleHidden();
201206

202207
this.reset();
203-
204-
this.secondaryAction.setLabel(i18n('dialog.permissions.step.action.submitNow', '?'));
205208
}
206209

207210
protected reset(): void {
@@ -228,6 +231,24 @@ export class EditPermissionsDialog
228231
return this.getButtonRow().getActions()[1];
229232
}
230233

234+
private getTotalItemsToApplyTo(): number {
235+
const applyTo = this.applyToStep.getData().applyTo;
236+
237+
if (applyTo === 'single') {
238+
return 1;
239+
}
240+
241+
if (applyTo === 'subtree') {
242+
return this.totalChildren;
243+
}
244+
245+
return this.totalChildren + 1;
246+
}
247+
248+
protected getSubmitActionLabel(): string {
249+
return i18n('dialog.permissions.step.action.submitNow', this.getTotalItemsToApplyTo());
250+
}
251+
231252
isDirty(): boolean {
232253
return this.mainStep.isAnyPermissionChanged();
233254
}

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

+11-4
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,18 @@ export class ApplyAccessToStep
4141
}
4242

4343
setup(totalChildren: number): void {
44-
this.applyToRadioGroup.setValue(totalChildren > 0 ? 'tree' : 'single', true);
44+
const hasChildren = totalChildren > 0;
45+
46+
this.applyToRadioGroup.setValue(hasChildren ? 'tree' : 'single', true);
4547
this.itemAndChildrenRadioButton.setLabel(`${i18n('dialog.permissions.step.apply.to.all')} (${totalChildren + 1})`);
46-
this.childrenOnlyRadioButton.setLabel(`${i18n('dialog.permissions.step.apply.to.children')} (${totalChildren})`);
47-
this.itemAndChildrenRadioButton.setEnabled(totalChildren > 0);
48-
this.childrenOnlyRadioButton.setEnabled(totalChildren > 0);
48+
this.childrenOnlyRadioButton.setLabel(
49+
i18n('dialog.permissions.step.apply.to.children') + (hasChildren ? ` (${totalChildren})` : ''));
50+
this.itemAndChildrenRadioButton.setEnabled(hasChildren);
51+
this.childrenOnlyRadioButton.setEnabled(hasChildren);
52+
53+
const noChildrenTitle = i18n('dialog.permissions.step.apply.tooltip.nochildren');
54+
this.itemAndChildrenRadioButton.setTitle(hasChildren ? '' : noChildrenTitle);
55+
this.childrenOnlyRadioButton.setTitle(hasChildren ? '' : noChildrenTitle);
4956
}
5057

5158
reset(): void {

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

+1
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ export class StrategyStep extends DialogStep {
6868
this.applyTo = val;
6969
this.strategyRadioGroup.setValue(val === 'single' ? 'reset' : 'merge', true);
7070
this.mergeRadioButton.setEnabled(val !== 'single');
71+
this.mergeRadioButton.setTitle(val === 'single' ? i18n('dialog.permissions.step.strategy.tooltip.single') : '');
7172
}
7273

7374
setCurrentlySelectedItems(items: AccessControlEntry[]): void {

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

+12-4
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export class SummaryStep
1313

1414
private readonly container: Element;
1515

16+
private readonly principalsLineLabel: Element;
1617
private readonly principalsLine: Element;
1718
private readonly accessModeLine: Element;
1819
private readonly applyToLine: Element;
@@ -24,6 +25,7 @@ export class SummaryStep
2425
super();
2526

2627
this.container = new SectionEl('summary-step');
28+
this.principalsLineLabel = new DdDtEl('dt');
2729
this.principalsLine = new DdDtEl('dd');
2830
this.accessModeLine = new DdDtEl('dd');
2931
this.applyToLine = new DdDtEl('dd');
@@ -49,15 +51,17 @@ export class SummaryStep
4951
}
5052

5153
setCurrentData(data: PermissionsData): void {
52-
this.principalsLine.setHtml(this.makePrincipalsLine(data.permissions));
54+
const changedEntries = this.getChangedEntries(data.permissions);
55+
this.principalsLineLabel.setHtml(i18n('dialog.permissions.step.summary.permissions.label', changedEntries.length));
56+
this.principalsLine.setHtml(this.makePrincipalsLine(changedEntries));
5357
this.accessModeLine.setHtml(data.permissions.some(p => p.getPrincipalKey().equals(RoleKeys.EVERYONE)) ? i18n(
5458
'dialog.permissions.step.main.access.public') : i18n('dialog.permissions.step.main.access.restricted'));
5559
this.applyToLine.setHtml(this.getApplyToLine(data));
5660
this.strategyLine.setHtml(
5761
data.strategy === 'merge' ? i18n('dialog.permissions.step.strategy.merge') : i18n('dialog.permissions.step.strategy.reset'));
5862
}
5963

60-
private makePrincipalsLine(current: AccessControlEntry[]): string {
64+
private getChangedEntries(current: AccessControlEntry[]): AccessControlEntry[] {
6165
const diff = new Map<string, AccessControlEntry>();
6266

6367
this.originalPermissions.forEach(p => {
@@ -76,7 +80,11 @@ export class SummaryStep
7680
}
7781
});
7882

79-
return Array.from(diff.values()).filter(p => !p.getPrincipalKey().equals(RoleKeys.EVERYONE)).map(
83+
return Array.from(diff.values()).filter(p => !p.getPrincipalKey().equals(RoleKeys.EVERYONE));
84+
}
85+
86+
private makePrincipalsLine(changedEntries: AccessControlEntry[]): string {
87+
return changedEntries.filter(p => !p.getPrincipalKey().equals(RoleKeys.EVERYONE)).map(
8088
p => p.getPrincipalDisplayName()).join(', ') || '<None>';
8189
}
8290

@@ -99,7 +107,7 @@ export class SummaryStep
99107
const strategyLineLabel = new DdDtEl('dt').setHtml(i18n('dialog.permissions.step.summary.strategy.label'));
100108

101109
const dl = new DlEl('summary-data-list');
102-
dl.appendChildren(principalsLineLabel, this.principalsLine, accessModeLineLabel, this.accessModeLine, applyToLineLabel,
110+
dl.appendChildren(this.principalsLineLabel, this.principalsLine, accessModeLineLabel, this.accessModeLine, applyToLineLabel,
103111
this.applyToLine, strategyLineLabel, this.strategyLine);
104112

105113
this.container.appendChild(dl);

modules/lib/src/main/resources/assets/styles/wizard/edit-permissions-dialog.less

+10-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
.dialog-content {
1717
margin-top: 32px;
18-
margin-bottom: 32px;
18+
margin-bottom: 16px;
1919

2020
.steps-container {
2121
.main-access-step {
@@ -62,6 +62,14 @@
6262
}
6363
}
6464

65+
.apply-to-access-step {
66+
.apply-to-container {
67+
.radio-button.disabled {
68+
opacity: 0.5;
69+
}
70+
}
71+
}
72+
6573
.summary-step {
6674
.summary-data-list {
6775
display: grid;
@@ -85,7 +93,7 @@
8593
.strategy-step {
8694
.strategy-step-container {
8795
.radio-button.disabled {
88-
opacity: 0.75;
96+
opacity: 0.5;
8997
}
9098
}
9199

modules/lib/src/main/resources/i18n/dialogs.properties

+5-3
Original file line numberDiff line numberDiff line change
@@ -76,16 +76,17 @@ dialog.permissions.inherit=Inherit permissions
7676
dialog.permissions.overwrite=Overwrite child permissions
7777
dialog.permissions.applying=Applying permissions to content items
7878
dialog.permissions.step.title=Manage access
79-
dialog.permissions.step.action.submitNow=Apply changes ({0})
79+
dialog.permissions.step.action.submitNow=Apply ({0})
8080
dialog.permissions.step.action.reset=Reset
8181
dialog.permissions.step.main.description=General access
8282
dialog.permissions.step.main.access.public=Public
8383
dialog.permissions.step.main.access.restricted=Restricted
8484
dialog.permissions.step.main.permissions.label=Permissions
85-
dialog.permissions.step.main.permissions.copy=Copy from parent
85+
dialog.permissions.step.main.permissions.copy=Set from parent
8686
dialog.permissions.step.main.access.label=Access mode
8787
dialog.permissions.step.apply.description=Select items to affect
8888
dialog.permissions.step.apply.label=Apply to
89+
dialog.permissions.step.apply.tooltip.nochildren=This item doesn't have children
8990
dialog.permissions.step.apply.to.all=This item and all children
9091
dialog.permissions.step.apply.to.children=Children only
9192
dialog.permissions.step.apply.to.item=This item
@@ -95,8 +96,9 @@ dialog.permissions.step.strategy.merge=Merge
9596
dialog.permissions.step.strategy.reset=Reset
9697
dialog.permissions.step.strategy.item.removed=Removed
9798
dialog.permissions.step.strategy.item.added=Added
99+
dialog.permissions.step.strategy.tooltip.single=Applying changes to a single item overwrites item's permissions
98100
dialog.permissions.step.summary.description=Summary
99-
dialog.permissions.step.summary.permissions.label=Changed
101+
dialog.permissions.step.summary.permissions.label=Changed ({0})
100102
dialog.permissions.step.summary.access.label=Access mode
101103
dialog.permissions.step.summary.apply.label=Apply to
102104
dialog.permissions.step.summary.strategy.label=Strategy

modules/rest/src/main/java/com/enonic/xp/app/contentstudio/rest/resource/content/Access.java

+6-8
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,11 @@
1313

1414
public enum Access
1515
{
16-
READ( Permission.READ ), WRITE( Permission.READ, Permission.CREATE, Permission.MODIFY, Permission.DELETE ), PUBLISH( Permission.READ,
17-
Permission.CREATE,
18-
Permission.MODIFY,
19-
Permission.DELETE,
20-
Permission.PUBLISH ), FULL(
21-
Permission.READ, Permission.CREATE, Permission.MODIFY, Permission.DELETE, Permission.PUBLISH, Permission.READ_PERMISSIONS,
22-
Permission.WRITE_PERMISSIONS ), CUSTOM();
16+
READ( Permission.READ ), WRITE( Permission.READ, Permission.CREATE, Permission.MODIFY, Permission.DELETE ), FULL( Permission.READ,
17+
Permission.CREATE,
18+
Permission.MODIFY,
19+
Permission.DELETE,
20+
Permission.PUBLISH ), CUSTOM();
2321

2422
private final EnumSet<Permission> permissions;
2523

@@ -31,7 +29,7 @@ public enum Access
3129
public static Access fromPermissions( final Iterable<Permission> permissions )
3230
{
3331
final ImmutableSet<Permission> perms = Sets.immutableEnumSet( permissions );
34-
return Stream.of( READ, WRITE, PUBLISH, FULL ).
32+
return Stream.of( READ, WRITE, FULL ).
3533
filter( a -> a.hasPermissions( perms ) ).
3634
findFirst().
3735
orElse( CUSTOM );

modules/rest/src/test/java/com/enonic/xp/app/contentstudio/rest/resource/content/AccessTest.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public void testFromPermissions()
2121
{
2222
assertEquals( Access.READ, Access.fromPermissions( asList( READ ) ) );
2323
assertEquals( Access.WRITE, Access.fromPermissions( asList( READ, CREATE, MODIFY, DELETE ) ) );
24-
assertEquals( Access.PUBLISH, Access.fromPermissions( asList( READ, MODIFY, DELETE, CREATE, PUBLISH ) ) );
24+
assertEquals( Access.FULL, Access.fromPermissions( asList( READ, MODIFY, DELETE, CREATE, PUBLISH ) ) );
2525
assertEquals( Access.FULL,
2626
Access.fromPermissions( asList( READ, MODIFY, DELETE, CREATE, PUBLISH, READ_PERMISSIONS, WRITE_PERMISSIONS ) ) );
2727
assertEquals( Access.CUSTOM, Access.fromPermissions( asList( READ, CREATE ) ) );

0 commit comments

Comments
 (0)