diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity/constants.ts index f804358649..5f9ddc3310 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity/constants.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity/constants.ts @@ -1,2 +1,4 @@ export * from './contexts/ancestors/constants.js'; export * from './contexts/parent/constants.js'; +export * from './entity-type/constants.js'; +export * from './entity-unique/constants.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-type/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-type/constants.ts new file mode 100644 index 0000000000..eb2c39863d --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-type/constants.ts @@ -0,0 +1 @@ +export const UMB_ENTITY_TYPE_CONDITION_ALIAS = 'Umb.Condition.Entity.Type'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-type/entity-type.condition.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-type/entity-type.condition.ts new file mode 100644 index 0000000000..051607765d --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-type/entity-type.condition.ts @@ -0,0 +1,35 @@ +import { UMB_ENTITY_CONTEXT } from '../entity.context-token.js'; +import type { UmbEntityTypeConditionConfig } from './types.js'; +import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import type { UmbConditionControllerArguments, UmbExtensionCondition } from '@umbraco-cms/backoffice/extension-api'; +import { UmbConditionBase } from '@umbraco-cms/backoffice/extension-registry'; + +export class UmbEntityTypeCondition + extends UmbConditionBase + implements UmbExtensionCondition +{ + constructor(host: UmbControllerHost, args: UmbConditionControllerArguments) { + super(host, args); + + this.consumeContext(UMB_ENTITY_CONTEXT, (context) => { + this.observe(context?.entityType, (entityType) => this.#check(entityType), 'umbEntityTypeObserver'); + }); + } + + #check(value: string | undefined) { + if (!value) { + this.permitted = false; + return; + } + + // if the config has a match, we only check that + if (this.config.match) { + this.permitted = value === this.config.match; + return; + } + + this.permitted = this.config.oneOf?.some((configValue) => configValue === value) ?? false; + } +} + +export { UmbEntityTypeCondition as api }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-type/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-type/manifests.ts new file mode 100644 index 0000000000..fdab02c688 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-type/manifests.ts @@ -0,0 +1,10 @@ +import { UMB_ENTITY_TYPE_CONDITION_ALIAS } from './constants.js'; + +export const manifests: Array = [ + { + type: 'condition', + name: 'Umbraco Entity Type Condition', + alias: UMB_ENTITY_TYPE_CONDITION_ALIAS, + api: () => import('./entity-type.condition.js'), + }, +]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-type/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-type/types.ts new file mode 100644 index 0000000000..d613b7e642 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-type/types.ts @@ -0,0 +1,13 @@ +import type { UMB_ENTITY_TYPE_CONDITION_ALIAS } from './constants.js'; +import type { UmbConditionConfigBase } from '@umbraco-cms/backoffice/extension-api'; + +export type UmbEntityTypeConditionConfig = UmbConditionConfigBase & { + match: string; + oneOf?: Array; +}; + +declare global { + interface UmbExtensionConditionConfigMap { + UmbEntityTypeConditionConfig: UmbEntityTypeConditionConfig; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-unique/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-unique/constants.ts new file mode 100644 index 0000000000..29a480d672 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-unique/constants.ts @@ -0,0 +1 @@ +export const UMB_ENTITY_UNIQUE_CONDITION_ALIAS = 'Umb.Condition.Entity.Unique'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-unique/entity-unique.condition.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-unique/entity-unique.condition.ts new file mode 100644 index 0000000000..6b21f64c1e --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-unique/entity-unique.condition.ts @@ -0,0 +1,36 @@ +import { UMB_ENTITY_CONTEXT } from '../entity.context-token.js'; +import type { UmbEntityUnique } from '../types.js'; +import type { UmbEntityUniqueConditionConfig } from './types.js'; +import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import type { UmbConditionControllerArguments, UmbExtensionCondition } from '@umbraco-cms/backoffice/extension-api'; +import { UmbConditionBase } from '@umbraco-cms/backoffice/extension-registry'; + +export class UmbEntityUniqueCondition + extends UmbConditionBase + implements UmbExtensionCondition +{ + constructor(host: UmbControllerHost, args: UmbConditionControllerArguments) { + super(host, args); + + this.consumeContext(UMB_ENTITY_CONTEXT, (context) => { + this.observe(context?.unique, (unique) => this.#check(unique), 'umbEntityUniqueObserver'); + }); + } + + #check(value: UmbEntityUnique | undefined) { + if (value === undefined) { + this.permitted = false; + return; + } + + // if the config has a match, we only check that + if (this.config.match !== undefined) { + this.permitted = value === this.config.match; + return; + } + + this.permitted = this.config.oneOf?.some((configValue) => configValue === value) ?? false; + } +} + +export { UmbEntityUniqueCondition as api }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-unique/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-unique/manifests.ts new file mode 100644 index 0000000000..accb4199eb --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-unique/manifests.ts @@ -0,0 +1,10 @@ +import { UMB_ENTITY_UNIQUE_CONDITION_ALIAS } from './constants.js'; + +export const manifests: Array = [ + { + type: 'condition', + name: 'Umbraco Entity Unique Condition', + alias: UMB_ENTITY_UNIQUE_CONDITION_ALIAS, + api: () => import('./entity-unique.condition.js'), + }, +]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-unique/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-unique/types.ts new file mode 100644 index 0000000000..22e442f84f --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-unique/types.ts @@ -0,0 +1,15 @@ +import type { UMB_ENTITY_UNIQUE_CONDITION_ALIAS } from './constants.js'; +import type { UmbConditionConfigBase } from '@umbraco-cms/backoffice/extension-api'; + +export type UmbEntityUnique = string | null; + +export type UmbEntityUniqueConditionConfig = UmbConditionConfigBase & { + match?: UmbEntityUnique; + oneOf?: Array; +}; + +declare global { + interface UmbExtensionConditionConfigMap { + UmbEntityUniqueConditionConfig: UmbEntityUniqueConditionConfig; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity/manifests.ts new file mode 100644 index 0000000000..d0f7437bd9 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity/manifests.ts @@ -0,0 +1,4 @@ +import { manifests as entityTypeManifests } from './entity-type/manifests.js'; +import { manifests as entityUniqueManifests } from './entity-unique/manifests.js'; + +export const manifests: Array = [...entityTypeManifests, ...entityUniqueManifests]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity/types.ts index f2fcb7dde9..51ac14114a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity/types.ts @@ -1,4 +1,4 @@ -export type UmbEntityUnique = string | null; +import type { UmbEntityUnique } from './entity-unique/types.js'; export interface UmbEntityModel { unique: UmbEntityUnique; @@ -8,3 +8,6 @@ export interface UmbEntityModel { export interface UmbNamedEntityModel extends UmbEntityModel { name: string; } + +export type * from './entity-type/types.js'; +export type * from './entity-unique/types.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/core/manifests.ts index 2d382b768a..1e046ec818 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/manifests.ts @@ -4,6 +4,7 @@ import { manifests as cultureManifests } from './culture/manifests.js'; import { manifests as debugManifests } from './debug/manifests.js'; import { manifests as entityActionManifests } from './entity-action/manifests.js'; import { manifests as entityBulkActionManifests } from './entity-bulk-action/manifests.js'; +import { manifests as entityManifests } from './entity/manifests.js'; import { manifests as extensionManifests } from './extension-registry/manifests.js'; import { manifests as iconRegistryManifests } from './icon-registry/manifests.js'; import { manifests as localizationManifests } from './localization/manifests.js'; @@ -30,6 +31,7 @@ export const manifests: Array = ...debugManifests, ...entityActionManifests, ...entityBulkActionManifests, + ...entityManifests, ...extensionManifests, ...iconRegistryManifests, ...localizationManifests,