Skip to content

Commit 385e860

Browse files
[ACS-8694] Cleanup of visibility rules for extensions in ACA (#4140)
1 parent de9b746 commit 385e860

16 files changed

+910
-1124
lines changed

docs/extending/legacy-rules.md

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
----
2+
Title: Legacy Rules for ACA
3+
----
4+
5+
# Legacy rules
6+
7+
Below is a list of all unused rules that were removed with ACA 5.1.1. You may use them as a reference in case your application/extension is still dependent on them,
8+
however we do advise that you revisit those implementations and substitute them with a different approach, since these rules will no longer be supported.
9+
10+
```typescript
11+
/**
12+
* app.selection.file.canLock
13+
* Checks if user can lock selected file.
14+
*/
15+
export const canLockFile = (context: RuleContext): boolean => !isWriteLocked(context) && canUpdateSelectedNode(context);
16+
17+
/**
18+
* app.selection.file.canUnlock
19+
* Checks if user can unlock selected file.
20+
*/
21+
export function canUnlockFile(context: RuleContext): boolean {
22+
const { file } = context.selection;
23+
return isWriteLocked(context) && (context.permissions.check(file?.entry, ['delete']) || isUserWriteLockOwner(context));
24+
}
25+
26+
/**
27+
* app.selection.file.isLockOwner
28+
* Checks if the selected file has **write** or **read-only** locks specified,
29+
* and that current user is the owner of the lock.
30+
*/
31+
export const isUserWriteLockOwner = (context: RuleContext): boolean =>
32+
isWriteLocked(context) &&
33+
context.selection.file?.entry.properties['cm:lockOwner'] &&
34+
context.selection.file?.entry.properties['cm:lockOwner'].id === context.profile.id;
35+
36+
/**
37+
* app.selection.file.canShare
38+
* Checks if user can share selected file.
39+
*/
40+
export const canShareFile = (context: RuleContext): boolean =>
41+
[context.selection.file, navigation.isNotTrashcan(context), repository.hasQuickShareEnabled(context), !isShared(context)].every(Boolean);
42+
43+
/**
44+
* app.selection.canUnshare
45+
* Checks if user can un-share selected nodes.
46+
*/
47+
export function canUnshareNodes(context: RuleContext): boolean {
48+
if (hasSelection(context)) {
49+
return context.permissions.check(context.selection.nodes, ['delete'], {
50+
target: 'allowableOperationsOnTarget'
51+
});
52+
}
53+
return false;
54+
}
55+
56+
/**
57+
* app.selection.file.isShared
58+
* Checks if the selected file is already shared.
59+
*/
60+
export function isShared(context: RuleContext): boolean {
61+
if (navigation.isSharedFiles(context) && context.selection.file) {
62+
return true;
63+
}
64+
65+
if (navigation.isNotTrashcan(context) && hasSelection(context) && context.selection.file) {
66+
return !!context.selection.file.entry?.properties?.['qshare:sharedId'];
67+
}
68+
69+
return false;
70+
}
71+
72+
/**
73+
* app.selection.isPrivateLibrary
74+
* Checks if user has selected a **private** library (site)
75+
*/
76+
export function isPrivateLibrary(context: RuleContext): boolean {
77+
return context.selection.library?.entry?.visibility === 'PRIVATE';
78+
}
79+
80+
/**
81+
* app.selection.hasNoLibraryRole
82+
* Checks if the selected library has no **role** property defined.
83+
*/
84+
export const hasNoLibraryRole = (context: RuleContext): boolean => !hasLibraryRole(context);
85+
86+
/**
87+
* app.navigation.isLibraryFiles
88+
* Checks if a **Library Files** route is activated.
89+
*/
90+
export function isLibraryFiles(context: RuleContext): boolean {
91+
const { url } = context.navigation;
92+
return url?.startsWith('/libraries');
93+
}
94+
95+
/**
96+
* app.navigation.isPersonalFiles
97+
* Checks if a **Personal Files** route is activated.
98+
*/
99+
export function isPersonalFiles(context: RuleContext): boolean {
100+
const { url } = context.navigation;
101+
return url?.startsWith('/personal-files');
102+
}
103+
104+
/**
105+
* app.navigation.isSharedPreview
106+
* Checks if a **Shared Preview** route is activated.
107+
*/
108+
export function isSharedPreview(context: RuleContext): boolean {
109+
const { url } = context.navigation;
110+
return url?.startsWith('/shared/preview/') || (url?.startsWith('/shared') && url?.includes('viewer:view'));
111+
}
112+
113+
/**
114+
* app.navigation.isFavoritesPreview
115+
* Checks if a **Favorites Preview** route is activated.
116+
*/
117+
export function isFavoritesPreview(context: RuleContext): boolean {
118+
const { url } = context.navigation;
119+
return url?.startsWith('/favorites/preview/') || (url?.startsWith('/favorites') && url?.includes('viewer:view'));
120+
}
121+
122+
/**
123+
* app.navigation.isSharedFileViewer
124+
* Checks if a **Shared File Preview** route is activated.
125+
*/
126+
export function isSharedFileViewer(context: RuleContext): boolean {
127+
const { url } = context.navigation;
128+
return url?.startsWith('/preview/s/');
129+
}
130+
131+
/**
132+
* repository.isQuickShareEnabled
133+
* Checks if the quick share repository option is enabled or not.
134+
*/
135+
export const hasQuickShareEnabled = (context: RuleContext): boolean => context.repository.status.isQuickShareEnabled;
136+
137+
/**
138+
* user.isAdmin
139+
* Checks if user is admin.
140+
*/
141+
export const isAdmin = (context: RuleContext): boolean => context.profile.isAdmin;
142+
```
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
---
2+
Title: Rule Migration Guide
3+
---
4+
5+
# Migrating rules to be ACA 5.1.1 compatible
6+
7+
As part of cleanup of the evaluators section in ACA 5.1.1, several rules from the application were removed and
8+
replaced with their alternatives. The biggest change involves the preference to use array based visibility rules
9+
instead of string based. What this means is that developers will now be able to provide a set of smaller visibility
10+
rules via array, instead of having to provide one single rule, which would internally call multiple smaller rules
11+
via code.
12+
13+
For e.g., for a rule `app.canManageFileVersions`, which was basically a combination of `hasFileSelection(app.selection.file)`,
14+
`isNotTrashcan (app.navigation.isNotTrashcan)`, and `isNotLocked(app.selection.file.isNotLocked)`, earlier, the code
15+
used to look something like -
16+
17+
app.extensions.json
18+
19+
```json
20+
{
21+
"rules": {
22+
"visible": "canManageFileVersions"
23+
}
24+
}
25+
```
26+
27+
aca-content.module.ts -
28+
29+
```ts
30+
extensions.setEvaluators({
31+
'app.canManageFileVersions': rules.canManageFileVersions,
32+
'app.selection.file': rules.hasFileSelection,
33+
'app.navigation.isNotTrashcan': rules.isNotTrashcan,
34+
'app.navigation.isTrashcan': rules.isTrashcan,
35+
'app.selection.file.isNotLocked': rules.isNotLocked
36+
})
37+
38+
```
39+
40+
app.rules.ts -
41+
42+
```ts
43+
import { isTrashcan } from './navigation.rules';
44+
45+
export const rules = {
46+
canManageFileVersions: () => hasFileSelection() && isNotTrashcan() && isNotLocked(),
47+
hasFileSelection: (context) => !!context?.selection?.file,
48+
isTrashcan: (context) => context.navigation.startsWith('/trashcan'),
49+
isNotTrashcan: (context) => !isTrashcan(context),
50+
isNotLocked: (context) => context.selection.file.entry.isLocked || context.selection.file.entry.properties?.['cm:lockType'] === 'READ_ONLY_LOCK'
51+
}
52+
53+
54+
```
55+
56+
Now, the visibility of this extension unit can be controlled in more compact way -
57+
58+
```json
59+
{
60+
"rules": {
61+
"visible": [
62+
"app.selection.file",
63+
"!app.navigation.isTrashcan",
64+
"!app.selection.file.isLocked"
65+
]
66+
}
67+
}
68+
```
69+
70+
No further changes in aca-content.module.ts, or app.rules.ts is required, apart from removing the unused rules and functions
71+
72+
**NOTE**: Notice the use of the rule negation `!` in the app.navigation.isTrashcan rule above, thereby removing another unneeded rule.
73+
74+
Below is a full list of rules that would need to be migrated, along with the corresponding set of rules that can be used in their place. Do note that the default OOTB ACA already has the migrations applied on extensions.json, and the changes would
75+
only need to be done on any extensions configuration that is custom to you. All old migrated rules have been removed from the code base, so performing this migration is necessary in order to ensure a stable Alfresco Content Application experience
76+
77+
| Old rule | New Rule |
78+
|--------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
79+
| app.navigation.isNotTrashcan | !app.navigation.isTrashcan |
80+
| app.navigation.isNotFavorites | !app.navigation.isFavorites |
81+
| app.navigation.isNotSharedFiles | !app.navigation.isSharedFiles |
82+
| app.navigation.isNotLibraries | !app.navigation.isLibraries |
83+
| app.navigation.isNotRecentFiles | !app.navigation.isRecentFiles |
84+
| app.navigation.isNotSearchResults | !app.navigation.isSearchResults |
85+
| canViewFile | app.selection.file<br/>!app.navigation.isTrashcan |
86+
| app.canCreateLibrary | app.isContentServiceEnabled<br/>app.navigation.isLibraries |
87+
| app.selection.canDownload | app.selection.notEmpty<br/>!app.navigation.isTrashcan<br/>app.selection.canDownload |
88+
| isTrashcanItemSelected | app.navigation.isTrashcan<br/>app.selection.notEmpty |
89+
| canLeaveLibrary | app.selection.library<br/>app.selection.hasLibraryRole |
90+
| canShowInfoDrawer | app.selection.notEmpty<br/>!app.navigation.isLibraries<br/>!app.navigation.isTrashcan |
91+
| app.toolbar.favorite.canEditMetadata | app.selection.library<br/>isLibraryManager |
92+
| canToggleEditOffline | app.selection.file<br/>!app.navigation.isTrashcan<br/>canToggleFileLock |
93+
| canEditFolder | app.selection.folder.canUpdate<br/>!app.navigation.isTrashcan |
94+
| app.toolbar.favorite.canAdd | app.selection.notEmpty<br/>app.selection.canAddFavorite<br/>!app.navigation.isTrashcan<br/>!app.navigation.isRecentFiles<br/>!app.navigation.isSharedFiles<br/>!app.navigation.isSearchResults<br/>!app.navigation.isFavorites |
95+
| app.toolbar.favorite.canRemove | app.selection.notEmpty<br/>app.selection.canRemoveFavorite<br/>!app.navigation.isTrashcan<br/>!app.navigation.isRecentFiles<br/>!app.navigation.isSharedFiles<br/>!app.navigation.isSearchResults<br/>!app.navigation.isFavorites |
96+
| canCopyNode | app.selection.notEmpty<br/>!app.navigation.isTrashcan<br/>!app.navigation.isLibraries |
97+
| canManageFileVersions | app.selection.file<br/>!app.navigation.isTrashcan<br/>!app.selection.file.isLocked |
98+
| canManagePermissions | app.selection.first.canUpdate<br/>!app.navigation.isTrashcan<br/>!isSmartFolder<br/>!isMultiSelection |
99+
| rules.canManageFolderRules | rules.isFolderRulesEnabled<br/>app.selection.folder.canUpdate<br/>!app.navigation.isTrashcan<br/>app.selection.folder<br/>!app.navigation.isFavorites<br/>!isSmartFolder |
100+
| app.navigation.folder.canCreate | app.isContentServiceEnabled<br/>app.navigation.folder.canCreate |
101+
| app.navigation.folder.canUpload | app.isContentServiceEnabled<br/>app.navigation.folder.canCreate |
102+
| app.isUploadSupported | app.isContentServiceEnabled<br/>app.navigation.folder.canCreate |
103+
| canToggleSharedLink | app.selection.file<br/>canToggleSharedLink |
104+
| canToggleJoinLibrary | app.selection.library<br/>!app.selection.hasLibraryRole<br/>canToggleJoinLibrary |
105+
| canShowExpand | !app.navigation.isLibraries<br/>!app.navigation.isDetails |
106+
| canInfoPreview | app.navigation.isSearchResults<br/>!isMultiSelection<br/>!app.selection.folder<br/>!app.navigation.isPreview |
107+
| app.selection.canDelete | !app.navigation.isTrashcan<br/>!app.navigation.isLibraries<br/>app.selection.notEmpty<br/>app.selection.canDelete |
108+
109+
In addition to the above-mentioned migrations, the following set of rules were removed from the ACA codebase, since they were not being used by the application. If you still need access to these rules however, the original implementation
110+
can be found in [legacy-rules.md](./legacy-rules.md). However, do note that since these rules have been removed from the ACA codebase, no support will be provided for them in the future. We advise that you should only use the provided rules as reference,
111+
and migrate your current implementation to use a different approach instead.
112+
113+
| Rule |
114+
|-----------------------------------|
115+
| app.selection.file.canLock |
116+
| app.selection.file.canUnlock |
117+
| app.selection.file.isLockOwner |
118+
| app.selection.file.canShare |
119+
| app.selection.file.isShared |
120+
| app.selection.canUnshare |
121+
| app.selection.isPrivateLibrary |
122+
| app.selection.hasNoLibraryRole |
123+
| app.navigation.isLibraryFiles |
124+
| app.navigation.isPersonalFiles |
125+
| app.navigation.isSharedPreview |
126+
| app.navigation.isFavoritesPreview |
127+
| app.navigation.isSharedFileViewer |
128+
| repository.isQuickShareEnabled |
129+
| user.isAdmin |

0 commit comments

Comments
 (0)