From 4c7f4f2c1452d8a936446c3da3b4664932a2f04e Mon Sep 17 00:00:00 2001 From: Michal Kinas <113341662+MichalKinas@users.noreply.github.com> Date: Thu, 2 Apr 2026 15:04:21 +0200 Subject: [PATCH] [MNT-25584] Hide edit offline option when node is checked out (#5132) * [MNT-25584] Hide edit offline option when node is checked out * [MNT-25584] CR fix * [MNT-25584] Missing docs changes --- docs/extending/rules-list.md | 3 ++- .../aca-content/assets/app.extensions.json | 9 ++++++--- .../aca-content/src/lib/aca-content.module.ts | 1 + .../aca-shared/rules/src/app.rules.spec.ts | 19 +++++++++++++++++++ projects/aca-shared/rules/src/app.rules.ts | 14 ++++++++++++++ 5 files changed, 42 insertions(+), 4 deletions(-) diff --git a/docs/extending/rules-list.md b/docs/extending/rules-list.md index c3819cb18..587a31cb1 100644 --- a/docs/extending/rules-list.md +++ b/docs/extending/rules-list.md @@ -57,7 +57,8 @@ Application related evaluators which can be used to check various different aspe | 5.1.1 | canToggleFileLock | Checks whether the user can lock/unlock the selected file | | 5.1.1 | isSmartFolder | Checks if the selected folder has the 'smf:customConfigSmartFolder' or the 'smf:systemConfigSmartFolder' aspect or not | | 5.1.1 | isMultiSelection | Checks if the user has selected multiple files | -| 6.1.0 | canPrintFile | Checks if current file can be printed or not (media files such as audio/video cannot be printed). | +| 6.1.0 | canPrintFile | Checks if current file can be printed or not (media files such as audio/video cannot be printed). | +| 7.4.0 | app.selection.isCheckedOut | Checks if selected node contains `cm:checkedOut` aspect. | #### Navigation Rules/Evaluators diff --git a/projects/aca-content/assets/app.extensions.json b/projects/aca-content/assets/app.extensions.json index 86b6a4ded..da40a6e9c 100644 --- a/projects/aca-content/assets/app.extensions.json +++ b/projects/aca-content/assets/app.extensions.json @@ -535,7 +535,8 @@ "visible": [ "app.selection.file", "!app.navigation.isTrashcan", - "canToggleFileLock" + "canToggleFileLock", + "!app.selection.isCheckedOut" ] } }, @@ -873,7 +874,8 @@ "visible": [ "app.selection.file", "!app.navigation.isTrashcan", - "canToggleFileLock" + "canToggleFileLock", + "!app.selection.isCheckedOut" ] } }, @@ -1297,7 +1299,8 @@ "visible": [ "app.selection.file", "!app.navigation.isTrashcan", - "canToggleFileLock" + "canToggleFileLock", + "!app.selection.isCheckedOut" ] } }, diff --git a/projects/aca-content/src/lib/aca-content.module.ts b/projects/aca-content/src/lib/aca-content.module.ts index 3ff4569a6..7182533e6 100644 --- a/projects/aca-content/src/lib/aca-content.module.ts +++ b/projects/aca-content/src/lib/aca-content.module.ts @@ -153,6 +153,7 @@ import { IsFeatureSupportedInCurrentAcsPipe } from './pipes/is-feature-supported 'app.selection.folder': rules.hasFolderSelected, 'app.selection.folder.canUpdate': rules.canUpdateSelectedFolder, 'app.selection.displayedKnowledgeRetrievalButton': rules.canDisplayKnowledgeRetrievalButton, + 'app.selection.isCheckedOut': rules.isCheckedOut, 'app.navigation.folder.canCreate': rules.canCreateFolder, 'app.navigation.isTrashcan': rules.isTrashcan, diff --git a/projects/aca-shared/rules/src/app.rules.spec.ts b/projects/aca-shared/rules/src/app.rules.spec.ts index 8b1d2ec2c..aedd34dd0 100644 --- a/projects/aca-shared/rules/src/app.rules.spec.ts +++ b/projects/aca-shared/rules/src/app.rules.spec.ts @@ -1204,6 +1204,25 @@ describe('app.evaluators', () => { }); }); + describe('isCheckedOut', () => { + it('should return false when there is no selection', () => { + context.selection.isEmpty = true; + expect(app.isCheckedOut(context)).toBeFalse(); + }); + + it('should return false when selected node does not have checked out aspect', () => { + context.selection.isEmpty = false; + context.selection.first = { entry: { aspectNames: ['test'] } } as any; + expect(app.isCheckedOut(context)).toBeFalse(); + }); + + it('should return true when selected node contains checked out aspect', () => { + context.selection.isEmpty = false; + context.selection.first = { entry: { aspectNames: ['cm:checkedOut'] } } as any; + expect(app.isCheckedOut(context)).toBeTrue(); + }); + }); + describe('isSSOEnabled', () => { it('should return true if sso is enabled', () => { context.appConfig = { get: () => 'OAUTH' } as any; diff --git a/projects/aca-shared/rules/src/app.rules.ts b/projects/aca-shared/rules/src/app.rules.ts index 6f670686d..df81db1fd 100644 --- a/projects/aca-shared/rules/src/app.rules.ts +++ b/projects/aca-shared/rules/src/app.rules.ts @@ -563,3 +563,17 @@ export const canDisplayKnowledgeRetrievalButton = (context: AcaRuleContext): boo ((navigation.isSearchResults(context) || navigation.isLibraryContent(context)) && !navigation.isLibraries(context))); export const isSSOEnabled = (context: AcaRuleContext): boolean => context.appConfig.get('authType') === 'OAUTH'; + +/** + * Checks if node contains checked out aspect. + * JSON ref: `app.selection.isCheckedOut` + * + * @param context Rule execution context + */ +export const isCheckedOut = (context: RuleContext): boolean => { + if (!context.selection?.isEmpty) { + const nodeAspects = context.selection.first.entry?.aspectNames ?? []; + return nodeAspects.includes('cm:checkedOut'); + } + return false; +};