diff --git a/src/Umbraco.Web.UI.Client/src/packages/language/language-access.workspace-context.ts b/src/Umbraco.Web.UI.Client/src/packages/language/language-access.workspace-context.ts new file mode 100644 index 0000000000..caa77c98f5 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/language/language-access.workspace-context.ts @@ -0,0 +1,77 @@ +import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import { UmbContextBase } from '@umbraco-cms/backoffice/class-api'; +import type { UmbVariantDatasetWorkspaceContext } from '@umbraco-cms/backoffice/workspace'; +import { UMB_VARIANT_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/workspace'; +import { UMB_CURRENT_USER_CONTEXT } from '@umbraco-cms/backoffice/current-user'; +import type { UmbVariantOptionModel, UmbVariantModel } from '@umbraco-cms/backoffice/variant'; +import { UmbVariantId } from '@umbraco-cms/backoffice/variant'; + +export class UmbLanguageAccessWorkspaceContext extends UmbContextBase { + #workspaceContext?: UmbVariantDatasetWorkspaceContext; + #currentUserAllowedLanguages?: Array; + #currentUserHasAccessToAllLanguages?: boolean; + #variantOptions?: UmbVariantOptionModel[]; + + constructor(host: UmbControllerHost) { + super(host, 'UmbLanguageAccessWorkspaceContext'); + + this.consumeContext(UMB_VARIANT_WORKSPACE_CONTEXT, (instance) => { + this.#workspaceContext = instance; + this.observe(instance.variantOptions, (variantOptions) => { + this.#variantOptions = variantOptions; + this.#checkForLanguageAccess(); + }); + }); + + this.consumeContext(UMB_CURRENT_USER_CONTEXT, (context) => { + this.observe(context.languages, (languages) => { + this.#currentUserAllowedLanguages = languages; + this.#checkForLanguageAccess(); + }); + + this.observe(context.hasAccessToAllLanguages, (hasAccessToAllLanguages) => { + this.#currentUserHasAccessToAllLanguages = hasAccessToAllLanguages; + this.#checkForLanguageAccess(); + }); + }); + } + + async #checkForLanguageAccess() { + if (!this.#workspaceContext) return; + + // find all disallowed languages + const disallowedLanguages = this.#variantOptions?.filter((variant) => { + if (this.#currentUserHasAccessToAllLanguages) { + return false; + } + + if (!variant.culture) { + return false; + } + + return !this.#currentUserAllowedLanguages?.includes(variant.culture); + }); + + // create a list of variantIds for the disallowed languages + const variantIds = disallowedLanguages?.map((variant) => new UmbVariantId(variant.culture, variant.segment)) || []; + + // create a list of states for the disallowed languages + const identifier = 'UMB_LANGUAGE_ACCESS_'; + const readOnlyStates = variantIds.map((variantId) => { + return { + unique: identifier + variantId.culture, + variantId, + message: 'You do not have access edit to this language', + }; + }); + + // remove all previous states before adding new ones + const uniques = this.#variantOptions?.map((variant) => identifier + variant.culture) || []; + this.#workspaceContext.readOnlyState?.removeStates(uniques); + + // add new states + this.#workspaceContext.readOnlyState?.addStates(readOnlyStates); + } +} + +export { UmbLanguageAccessWorkspaceContext as api }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/language/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/language/manifests.ts index 704121a188..c5783e4cb2 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/language/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/language/manifests.ts @@ -17,4 +17,16 @@ export const manifests: Array = [ ...modalManifests, ...collectionManifests, ...globalContextManifests, + { + type: 'workspaceContext', + name: 'Document Language Access Workspace Context', + alias: 'Umb.WorkspaceContext.DocumentLanguageAccess', + api: () => import('./language-access.workspace-context.js'), + conditions: [ + { + alias: 'Umb.Condition.WorkspaceAlias', + match: 'Umb.Workspace.Document', + }, + ], + }, ];