Entity type + Entity Unique conditions (#19614)

* Add entity-type and entity-unique condition support

Introduces new condition types for entity-type and entity-unique, including their constants, types, condition implementations, and manifests. Updates exports in core entity modules to include these new features, enabling more granular extension conditions based on entity type and uniqueness.

* register conditions

* add support for oneOf

* fix self imports

* Update manifests.ts

* remove unused
This commit is contained in:
Mads Rasmussen
2025-06-30 14:51:21 +02:00
committed by GitHub
parent cfbbfa004c
commit 283e6b2ff0
12 changed files with 133 additions and 1 deletions

View File

@@ -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';

View File

@@ -0,0 +1 @@
export const UMB_ENTITY_TYPE_CONDITION_ALIAS = 'Umb.Condition.Entity.Type';

View File

@@ -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<UmbEntityTypeConditionConfig>
implements UmbExtensionCondition
{
constructor(host: UmbControllerHost, args: UmbConditionControllerArguments<UmbEntityTypeConditionConfig>) {
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 };

View File

@@ -0,0 +1,10 @@
import { UMB_ENTITY_TYPE_CONDITION_ALIAS } from './constants.js';
export const manifests: Array<UmbExtensionManifest> = [
{
type: 'condition',
name: 'Umbraco Entity Type Condition',
alias: UMB_ENTITY_TYPE_CONDITION_ALIAS,
api: () => import('./entity-type.condition.js'),
},
];

View File

@@ -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<typeof UMB_ENTITY_TYPE_CONDITION_ALIAS> & {
match: string;
oneOf?: Array<string>;
};
declare global {
interface UmbExtensionConditionConfigMap {
UmbEntityTypeConditionConfig: UmbEntityTypeConditionConfig;
}
}

View File

@@ -0,0 +1 @@
export const UMB_ENTITY_UNIQUE_CONDITION_ALIAS = 'Umb.Condition.Entity.Unique';

View File

@@ -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<UmbEntityUniqueConditionConfig>
implements UmbExtensionCondition
{
constructor(host: UmbControllerHost, args: UmbConditionControllerArguments<UmbEntityUniqueConditionConfig>) {
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 };

View File

@@ -0,0 +1,10 @@
import { UMB_ENTITY_UNIQUE_CONDITION_ALIAS } from './constants.js';
export const manifests: Array<UmbExtensionManifest> = [
{
type: 'condition',
name: 'Umbraco Entity Unique Condition',
alias: UMB_ENTITY_UNIQUE_CONDITION_ALIAS,
api: () => import('./entity-unique.condition.js'),
},
];

View File

@@ -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<typeof UMB_ENTITY_UNIQUE_CONDITION_ALIAS> & {
match?: UmbEntityUnique;
oneOf?: Array<UmbEntityUnique>;
};
declare global {
interface UmbExtensionConditionConfigMap {
UmbEntityUniqueConditionConfig: UmbEntityUniqueConditionConfig;
}
}

View File

@@ -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<UmbExtensionManifest> = [...entityTypeManifests, ...entityUniqueManifests];

View File

@@ -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';

View File

@@ -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<UmbExtensionManifest | UmbExtensionManifestKind> =
...debugManifests,
...entityActionManifests,
...entityBulkActionManifests,
...entityManifests,
...extensionManifests,
...iconRegistryManifests,
...localizationManifests,