From d709edae61a062624ee264a5ff3a9fa70339a8d0 Mon Sep 17 00:00:00 2001 From: NathanWoulfe Date: Wed, 23 Jul 2025 10:43:50 +1000 Subject: [PATCH 1/3] adds new third-party permissions section to user group workspace --- .../src/assets/lang/en.ts | 1 + ...oup-entity-user-permission-list.element.ts | 35 +----- ...group-extension-permission-list.element.ts | 108 +++++++++++++++++ ...user-group-permission-list-base.element.ts | 49 ++++++++ .../user-group-workspace-editor.element.ts | 6 + .../user/user-permission/components/index.ts | 4 + .../input-entity-user-permission.element.ts | 110 ++---------------- ...input-extension-user-permission.element.ts | 32 +++++ .../input-user-permission-base.element.ts | 107 +++++++++++++++++ .../packages/user/user-permission/types.ts | 2 + .../user-extension-permission.extension.ts | 33 ++++++ 11 files changed, 352 insertions(+), 135 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/user/user-group/workspace/user-group/components/user-group-extension-permission-list.element.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/user/user-group/workspace/user-group/components/user-group-permission-list-base.element.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/user/user-permission/components/input-extension-user-permission/input-extension-user-permission.element.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/user/user-permission/components/input-user-permission-base.element.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/user/user-permission/user-extension-permission.extension.ts diff --git a/src/Umbraco.Web.UI.Client/src/assets/lang/en.ts b/src/Umbraco.Web.UI.Client/src/assets/lang/en.ts index f538f741d576..c681b4a55644 100644 --- a/src/Umbraco.Web.UI.Client/src/assets/lang/en.ts +++ b/src/Umbraco.Web.UI.Client/src/assets/lang/en.ts @@ -2087,6 +2087,7 @@ export default { permissionsDefault: 'Default permissions', permissionsGranular: 'Granular permissions', permissionsGranularHelp: 'Set permissions for specific nodes', + permissionsExtensions: 'Third-party permissions', granularRightsLabel: 'Documents', granularRightsDescription: 'Assign permissions to specific documents', permissionsEntityGroup_document: 'Document', diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user-group/workspace/user-group/components/user-group-entity-user-permission-list.element.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user-group/workspace/user-group/components/user-group-entity-user-permission-list.element.ts index d9ecbdbf19ed..8ec36de78db7 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/user-group/workspace/user-group/components/user-group-entity-user-permission-list.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user-group/workspace/user-group/components/user-group-entity-user-permission-list.element.ts @@ -1,35 +1,16 @@ -import { UMB_USER_GROUP_WORKSPACE_CONTEXT } from '../user-group-workspace.context-token.js'; -import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { html, customElement, state } from '@umbraco-cms/backoffice/external/lit'; -import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; -import type { UmbSelectionChangeEvent } from '@umbraco-cms/backoffice/event'; import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; +import { UmbUserGroupPermissionsListBaseElement } from './user-group-permission-list-base.element.js'; @customElement('umb-user-group-entity-user-permission-list') -export class UmbUserGroupEntityUserPermissionListElement extends UmbLitElement { - @state() - private _fallBackPermissions?: Array; - +export class UmbUserGroupEntityUserPermissionListElement extends UmbUserGroupPermissionsListBaseElement { @state() private _groups: Array<{ entityType: string; headline: string }> = []; - #userGroupWorkspaceContext?: typeof UMB_USER_GROUP_WORKSPACE_CONTEXT.TYPE; - constructor() { super(); this.#observeEntityUserPermissions(); - - this.consumeContext(UMB_USER_GROUP_WORKSPACE_CONTEXT, (instance) => { - this.#userGroupWorkspaceContext = instance; - this.observe( - this.#userGroupWorkspaceContext?.fallbackPermissions, - (fallbackPermissions) => { - this._fallBackPermissions = fallbackPermissions; - }, - 'umbUserGroupEntityUserPermissionsObserver', - ); - }); } #observeEntityUserPermissions() { @@ -50,14 +31,6 @@ export class UmbUserGroupEntityUserPermissionListElement extends UmbLitElement { ); } - #onPermissionChange(event: UmbSelectionChangeEvent) { - event.stopPropagation(); - const target = event.target as any; - const verbs = target.allowedVerbs; - if (verbs === undefined || verbs === null) throw new Error('The verbs are not defined'); - this.#userGroupWorkspaceContext?.setFallbackPermissions(verbs); - } - override render() { return html` ${this._groups.map((group) => this.#renderPermissionsForEntityType(group))}`; } @@ -68,11 +41,9 @@ export class UmbUserGroupEntityUserPermissionListElement extends UmbLitElement { + @change=${this.onPermissionChange}> `; } - - static override styles = [UmbTextStyles]; } export default UmbUserGroupEntityUserPermissionListElement; diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user-group/workspace/user-group/components/user-group-extension-permission-list.element.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user-group/workspace/user-group/components/user-group-extension-permission-list.element.ts new file mode 100644 index 000000000000..2cb43c29e15e --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user-group/workspace/user-group/components/user-group-extension-permission-list.element.ts @@ -0,0 +1,108 @@ +import { customElement, html, nothing, state } from '@umbraco-cms/backoffice/external/lit'; +import type { + ManifestExtensionPermissions, + ManifestExtensionUserPermission, +} from '@umbraco-cms/backoffice/user-permission'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; +import { createExtensionElement } from '@umbraco-cms/backoffice/extension-api'; +import { UmbUserGroupPermissionsListBaseElement } from './user-group-permission-list-base.element.js'; + +@customElement('umb-user-group-extension-permission-list') +export class UmbUserGroupExtensionPermissionsListElement extends UmbUserGroupPermissionsListBaseElement { + @state() + private _manifests?: ManifestExtensionUserPermission[]; + + @state() + private _extensionElements = new Map(); + + @state() + private _extensions?: ManifestExtensionPermissions[]; + + constructor() { + super(); + + this.#observeExtensionPermissions(); + this.#observeEntityUserPermissions(); + } + + #observeExtensionPermissions() { + this.observe( + umbExtensionsRegistry.byType('extensionPermissions'), + async (manifests) => { + this._extensions = manifests; + + // Pre-create extension elements for each manifest + for (const manifest of manifests) { + if (!manifest.element && !manifest.js) continue; + const element = await createExtensionElement(manifest); + + if (element) { + this._extensionElements.set(manifest.meta.extensionAlias, element); + } + } + this.requestUpdate('_extensionElements'); + }, + 'umbExtensionPermissionsObserver', + ); + } + + #observeEntityUserPermissions() { + this.observe( + umbExtensionsRegistry.byType('extensionUserPermission'), + (manifests) => (this._manifests = manifests), + 'umbExtensionUserPermissionsObserver', + ); + } + + #groupPermissionsForExtension(manifests: ManifestExtensionUserPermission[]) { + const entityTypes = [...new Set(manifests.flatMap((manifest) => manifest.forEntityTypes))]; + + return entityTypes + .map((entityType) => ({ + entityType, + headline: this.localize.term(`user_permissionsEntityGroup_${entityType}`), + })) + .sort((a, b) => a.headline.localeCompare(b.headline)); + } + + #renderProperty(manifest: ManifestExtensionPermissions) { + const label = manifest.meta.labelKey ? this.localize.term(manifest.meta.labelKey) : manifest.meta.label; + const description = manifest.meta.descriptionKey + ? this.localize.term(manifest.meta.descriptionKey) + : manifest.meta.description; + + const permissions = this._manifests?.filter((x) => x.forExtension === manifest.meta.extensionAlias) || []; + const groupedPermissions = this.#groupPermissionsForExtension(permissions); + + return html` + +
+ ${this._extensionElements.get(manifest.meta.extensionAlias)} + ${groupedPermissions.map( + (group) => + html`

${group.headline}

+ `, + )} +
+
+ `; + } + + override render() { + if (!this._extensions) return nothing; + + return html`${this._extensions.map((extension) => this.#renderProperty(extension))}`; + } +} + +export default UmbUserGroupExtensionPermissionsListElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-user-group-extension-permission-list': UmbUserGroupExtensionPermissionsListElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user-group/workspace/user-group/components/user-group-permission-list-base.element.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user-group/workspace/user-group/components/user-group-permission-list-base.element.ts new file mode 100644 index 000000000000..fd693a0485ac --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user-group/workspace/user-group/components/user-group-permission-list-base.element.ts @@ -0,0 +1,49 @@ +import { html, state } from '@umbraco-cms/backoffice/external/lit'; +import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import { UMB_USER_GROUP_WORKSPACE_CONTEXT } from '../user-group-workspace.context-token'; +import type { UmbSelectionChangeEvent } from 'src/packages/core/event/selection-change.event'; +import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; + +export abstract class UmbUserGroupPermissionsListBaseElement extends UmbLitElement { + protected userGroupWorkspaceContext?: typeof UMB_USER_GROUP_WORKSPACE_CONTEXT.TYPE; + + @state() + protected _fallBackPermissions?: Array; + + constructor() { + super(); + + this.consumeContext(UMB_USER_GROUP_WORKSPACE_CONTEXT, (instance) => { + this.userGroupWorkspaceContext = instance; + this.observe( + this.userGroupWorkspaceContext?.fallbackPermissions, + (fallbackPermissions) => { + this._fallBackPermissions = fallbackPermissions; + }, + 'umbUserGroupFallbackPermissionsObserver', + ); + }); + } + + protected renderPermissionsForEntityType(group: { entityType: string; headline: string }) { + return html` +

${group.headline}

+ + `; + } + + protected onPermissionChange(event: UmbSelectionChangeEvent) { + event.stopPropagation(); + const target = event.target as any; + const verbs = target.allowedVerbs; + + if (verbs === undefined || verbs === null) throw new Error('The verbs are not defined'); + + this.userGroupWorkspaceContext?.setFallbackPermissions(verbs); + } + + static override styles = [UmbTextStyles]; +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user-group/workspace/user-group/user-group-workspace-editor.element.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user-group/workspace/user-group/user-group-workspace-editor.element.ts index 701ff856e9c1..f08a9c95d098 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/user-group/workspace/user-group/user-group-workspace-editor.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user-group/workspace/user-group/user-group-workspace-editor.element.ts @@ -14,6 +14,7 @@ import type { UmbInputWithAliasElement } from '@umbraco-cms/backoffice/component import './components/user-group-entity-user-permission-list.element.js'; import './components/user-group-granular-permission-list.element.js'; +import './components/user-group-extension-permission-list.element.js'; @customElement('umb-user-group-workspace-editor') export class UmbUserGroupWorkspaceEditorElement extends UmbLitElement { @@ -256,6 +257,11 @@ export class UmbUserGroupWorkspaceEditorElement extends UmbLitElement {
+ + +
+ +
`; diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/components/index.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/components/index.ts index 70730115a2d2..5d878f63f284 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/components/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/components/index.ts @@ -1,5 +1,9 @@ import './input-entity-user-permission/input-entity-user-permission.element.js'; import './input-user-permission-verb/input-user-permission-verb.element.js'; +import './input-extension-user-permission/input-extension-user-permission.element.js'; +import './input-user-permission-base.element.js' export * from './input-entity-user-permission/input-entity-user-permission.element.js'; export * from './input-user-permission-verb/input-user-permission-verb.element.js'; +export * from './input-extension-user-permission/input-extension-user-permission.element.js'; +export * from './input-user-permission-base.element.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/components/input-entity-user-permission/input-entity-user-permission.element.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/components/input-entity-user-permission/input-entity-user-permission.element.ts index f6fe7c2b9c81..bc2b705d7925 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/components/input-entity-user-permission/input-entity-user-permission.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/components/input-entity-user-permission/input-entity-user-permission.element.ts @@ -1,120 +1,24 @@ import type { ManifestEntityUserPermission } from '../../entity-user-permission.extension.js'; -import { UmbChangeEvent } from '@umbraco-cms/backoffice/event'; import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; -import { html, customElement, property, state, nothing, ifDefined, css } from '@umbraco-cms/backoffice/external/lit'; -import type { UmbObserverController } from '@umbraco-cms/backoffice/observable-api'; -import type { UmbUserPermissionVerbElement } from '@umbraco-cms/backoffice/user'; -import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; -import { UmbFormControlMixin } from '@umbraco-cms/backoffice/validation'; +import { customElement } from '@umbraco-cms/backoffice/external/lit'; +import { UmbInputUserPermissionBaseElement } from '../input-user-permission-base.element.js'; @customElement('umb-input-entity-user-permission') -export class UmbInputEntityUserPermissionElement extends UmbFormControlMixin(UmbLitElement) { - @property({ type: String, attribute: 'entity-type' }) - public get entityType(): string { - return this._entityType; - } - public set entityType(value: string) { - if (value === this._entityType) return; - this._entityType = value; - this.#observeEntityUserPermissions(); - } - private _entityType: string = ''; - - @property({ attribute: false }) - allowedVerbs: Array = []; - - @state() - private _manifests: Array = []; - - #manifestObserver?: UmbObserverController>; - - protected override getFormElement() { - return undefined; - } - - #isAllowed(permissionVerbs: Array) { - return permissionVerbs.every((verb) => this.allowedVerbs.includes(verb)); - } +export class UmbInputEntityUserPermissionElement extends UmbInputUserPermissionBaseElement { - #observeEntityUserPermissions() { - this.#manifestObserver?.destroy(); + observePermissions() { + this.manifestObserver?.destroy(); - this.#manifestObserver = this.observe( + this.manifestObserver = this.observe( umbExtensionsRegistry.byType('entityUserPermission'), (userPermissionManifests) => { - this._manifests = userPermissionManifests.filter((manifest) => + this.manifests = userPermissionManifests.filter((manifest) => manifest.forEntityTypes.includes(this.entityType), ); }, 'umbUserPermissionManifestsObserver', ); } - - #onChangeUserPermission(event: UmbChangeEvent, permissionVerbs: Array) { - event.stopPropagation(); - const target = event.target as UmbUserPermissionVerbElement; - if (target.allowed) { - this.#addUserPermission(permissionVerbs); - } else { - this.#removeUserPermission(permissionVerbs); - } - } - - #addUserPermission(permissionVerbs: Array) { - const verbs = [...this.allowedVerbs, ...permissionVerbs]; - // ensure we only have unique verbs - this.allowedVerbs = [...new Set(verbs)]; - this.dispatchEvent(new UmbChangeEvent()); - } - - #removeUserPermission(permissionVerbs: Array) { - this.allowedVerbs = this.allowedVerbs.filter((p) => !permissionVerbs.includes(p)); - this.dispatchEvent(new UmbChangeEvent()); - } - - override render() { - return html`${this.#renderGroupedPermissions(this._manifests)} `; - } - - #renderGroupedPermissions(permissionManifests: Array) { - // TODO: groupBy is not known by TS yet - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-expect-error - const groupedPermissions = Object.groupBy( - permissionManifests, - (manifest: ManifestEntityUserPermission) => manifest.meta.group, - ) as Record>; - return html` - ${Object.entries(groupedPermissions).map( - ([group, manifests]) => html` - ${group !== 'undefined' - ? html`
${group}
` - : nothing} -
${manifests.map((manifest) => html` ${this.#renderPermission(manifest)} `)}
- `, - )} - `; - } - - #renderPermission(manifest: ManifestEntityUserPermission) { - return html` - this.#onChangeUserPermission(event, manifest.meta.verbs)}>`; - } - - override disconnectedCallback() { - super.disconnectedCallback(); - this.#manifestObserver?.destroy(); - } - - static override styles = css` - umb-input-user-permission-verb:not(:last-of-type) { - border-bottom: 1px solid var(--uui-color-divider); - } - `; } export default UmbInputEntityUserPermissionElement; diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/components/input-extension-user-permission/input-extension-user-permission.element.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/components/input-extension-user-permission/input-extension-user-permission.element.ts new file mode 100644 index 000000000000..c875057db3bd --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/components/input-extension-user-permission/input-extension-user-permission.element.ts @@ -0,0 +1,32 @@ +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; +import { customElement, property } from '@umbraco-cms/backoffice/external/lit'; +import type { ManifestExtensionUserPermission } from '../../user-extension-permission.extension.js'; +import { UmbInputUserPermissionBaseElement } from '../input-user-permission-base.element.js'; + +@customElement('umb-input-extension-user-permission') +export class UmbInputExtensionUserPermissionElement extends UmbInputUserPermissionBaseElement { + @property({ type: String, attribute: false }) + forExtension: string = ''; + + observePermissions() { + this.manifestObserver?.destroy(); + + this.manifestObserver = this.observe( + umbExtensionsRegistry.byTypeAndFilter('extensionUserPermission', (m) => m.forExtension === this.forExtension), + (userPermissionManifests) => { + this.manifests = userPermissionManifests.filter((manifest) => + manifest.forEntityTypes.includes(this.entityType), + ); + }, + 'umbExtensionPermissionManifestsObserver', + ); + } +} + +export default UmbInputExtensionUserPermissionElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-input-extension-user-permission': UmbInputExtensionUserPermissionElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/components/input-user-permission-base.element.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/components/input-user-permission-base.element.ts new file mode 100644 index 000000000000..cde1fd3ec879 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/components/input-user-permission-base.element.ts @@ -0,0 +1,107 @@ +import { UmbChangeEvent } from '@umbraco-cms/backoffice/event'; +import type { ManifestElement } from '@umbraco-cms/backoffice/extension-api'; +import { css, html, ifDefined, nothing, property, state } from '@umbraco-cms/backoffice/external/lit'; +import type { UmbObserverController } from '@umbraco-cms/backoffice/observable-api'; +import type { UmbUserPermissionVerbElement } from '@umbraco-cms/backoffice/user'; +import { UmbFormControlMixin } from '@umbraco-cms/backoffice/validation'; +import { UmbLitElement } from 'src/packages/core/lit-element/lit-element.element'; +import type { MetaEntityUserPermission } from '../entity-user-permission.extension'; + +export abstract class UmbInputUserPermissionBaseElement< + ManifestPermissionType extends ManifestElement & { meta: MetaEntityUserPermission }, +> extends UmbFormControlMixin(UmbLitElement) { + @property({ type: String, attribute: 'entity-type' }) + public get entityType(): string { + return this._entityType; + } + public set entityType(value: string) { + if (value === this._entityType) return; + this._entityType = value; + this.observePermissions(); + } + private _entityType: string = ''; + + @property({ attribute: false }) + allowedVerbs: Array = []; + + @state() + protected manifests: Array = []; + + protected manifestObserver?: UmbObserverController>; + + abstract observePermissions(): void; + + protected override getFormElement() { + return undefined; + } + + #isAllowed(permissionVerbs: Array) { + return permissionVerbs.every((verb) => this.allowedVerbs.includes(verb)); + } + + #onChangeUserPermission(event: UmbChangeEvent, permissionVerbs: Array) { + event.stopPropagation(); + const target = event.target as UmbUserPermissionVerbElement; + if (target.allowed) { + this.#addUserPermission(permissionVerbs); + } else { + this.#removeUserPermission(permissionVerbs); + } + } + + #addUserPermission(permissionVerbs: Array) { + const verbs = [...this.allowedVerbs, ...permissionVerbs]; + // ensure we only have unique verbs + this.allowedVerbs = [...new Set(verbs)]; + this.dispatchEvent(new UmbChangeEvent()); + } + + #removeUserPermission(permissionVerbs: Array) { + this.allowedVerbs = this.allowedVerbs.filter((p) => !permissionVerbs.includes(p)); + this.dispatchEvent(new UmbChangeEvent()); + } + + #renderGroupedPermissions(permissionManifests: Array) { + // TODO: groupBy is not known by TS yet + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + const groupedPermissions = Object.groupBy( + permissionManifests, + (manifest: ManifestPermissionType) => manifest.meta.group, + ) as Record>; + return html` + ${Object.entries(groupedPermissions).map( + ([group, manifests]) => html` + ${group !== 'undefined' + ? html`
${group}
` + : nothing} +
${manifests.map((manifest) => html` ${this.#renderPermission(manifest)} `)}
+ `, + )} + `; + } + + #renderPermission(manifest: ManifestPermissionType) { + return html` + this.#onChangeUserPermission(event, manifest.meta.verbs)}>`; + } + + override render() { + return html`${this.#renderGroupedPermissions(this.manifests)} `; + } + + override disconnectedCallback() { + super.disconnectedCallback(); + this.manifestObserver?.destroy(); + } + + static override styles = css` + umb-input-user-permission-verb:not(:last-of-type) { + border-bottom: 1px solid var(--uui-color-divider); + } + `; +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/types.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/types.ts index ffba0215efa7..9e5ae1fa5be9 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/types.ts @@ -1,5 +1,7 @@ export type * from './user-granular-permission.extension.js'; export type * from './entity-user-permission.extension.js'; +export type * from './user-extension-permission.extension.js'; + export interface UmbUserPermissionModel { $type: string; userPermissionType?: string; diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/user-extension-permission.extension.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/user-extension-permission.extension.ts new file mode 100644 index 000000000000..7740d7b7a407 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/user-extension-permission.extension.ts @@ -0,0 +1,33 @@ +import type { ManifestElement } from '@umbraco-cms/backoffice/extension-api'; +import type { MetaEntityUserPermission } from './entity-user-permission.extension'; + +export interface ManifestExtensionPermissions extends ManifestElement { + type: 'extensionPermissions'; + forEntityTypes: Array; + meta: MetaExtensionPermissions; +} + +export interface MetaExtensionPermissions { + extensionAlias: string; + schemaType?: string; + labelKey?: string; + label?: string; + descriptionKey?: string; + description?: string; +} + +export interface ManifestExtensionUserPermission extends ManifestElement { + type: 'extensionUserPermission'; + forEntityTypes: Array; + forExtension: string; + meta: MetaEntityUserPermission; +} + +export interface MetaExtensionUserPermission extends MetaEntityUserPermission {} + +declare global { + interface UmbExtensionManifestMap { + umbExtensionPermissions: ManifestExtensionPermissions; + umbExtensionUserPermission: ManifestExtensionUserPermission; + } +} From 23b44211e8bf57f148ccb5c14bb8b2d679b92157 Mon Sep 17 00:00:00 2001 From: NathanWoulfe Date: Wed, 23 Jul 2025 12:56:58 +1000 Subject: [PATCH 2/3] lint --- .../components/user-group-permission-list-base.element.ts | 4 ++-- .../src/packages/user/user-permission/components/index.ts | 2 +- .../user-permission/user-extension-permission.extension.ts | 2 -- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user-group/workspace/user-group/components/user-group-permission-list-base.element.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user-group/workspace/user-group/components/user-group-permission-list-base.element.ts index fd693a0485ac..6021be168050 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/user-group/workspace/user-group/components/user-group-permission-list-base.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user-group/workspace/user-group/components/user-group-permission-list-base.element.ts @@ -1,8 +1,8 @@ import { html, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; -import { UMB_USER_GROUP_WORKSPACE_CONTEXT } from '../user-group-workspace.context-token'; -import type { UmbSelectionChangeEvent } from 'src/packages/core/event/selection-change.event'; +import { UMB_USER_GROUP_WORKSPACE_CONTEXT } from '../user-group-workspace.context-token.js'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; +import type { UmbSelectionChangeEvent } from '@umbraco-cms/backoffice/event'; export abstract class UmbUserGroupPermissionsListBaseElement extends UmbLitElement { protected userGroupWorkspaceContext?: typeof UMB_USER_GROUP_WORKSPACE_CONTEXT.TYPE; diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/components/index.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/components/index.ts index 5d878f63f284..f599859fb554 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/components/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/components/index.ts @@ -1,7 +1,7 @@ import './input-entity-user-permission/input-entity-user-permission.element.js'; import './input-user-permission-verb/input-user-permission-verb.element.js'; import './input-extension-user-permission/input-extension-user-permission.element.js'; -import './input-user-permission-base.element.js' +import './input-user-permission-base.element.js'; export * from './input-entity-user-permission/input-entity-user-permission.element.js'; export * from './input-user-permission-verb/input-user-permission-verb.element.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/user-extension-permission.extension.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/user-extension-permission.extension.ts index 7740d7b7a407..5b588d7f3f54 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/user-extension-permission.extension.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/user-extension-permission.extension.ts @@ -23,8 +23,6 @@ export interface ManifestExtensionUserPermission extends ManifestElement { meta: MetaEntityUserPermission; } -export interface MetaExtensionUserPermission extends MetaEntityUserPermission {} - declare global { interface UmbExtensionManifestMap { umbExtensionPermissions: ManifestExtensionPermissions; From 9ac76302375381eefb396b94f5a1c44a2aec1538 Mon Sep 17 00:00:00 2001 From: NathanWoulfe Date: Wed, 23 Jul 2025 13:08:32 +1000 Subject: [PATCH 3/3] lint --- .../components/input-user-permission-base.element.ts | 4 ++-- .../user-permission/user-extension-permission.extension.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/components/input-user-permission-base.element.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/components/input-user-permission-base.element.ts index cde1fd3ec879..25af1fbe76e7 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/components/input-user-permission-base.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/components/input-user-permission-base.element.ts @@ -4,8 +4,8 @@ import { css, html, ifDefined, nothing, property, state } from '@umbraco-cms/bac import type { UmbObserverController } from '@umbraco-cms/backoffice/observable-api'; import type { UmbUserPermissionVerbElement } from '@umbraco-cms/backoffice/user'; import { UmbFormControlMixin } from '@umbraco-cms/backoffice/validation'; -import { UmbLitElement } from 'src/packages/core/lit-element/lit-element.element'; -import type { MetaEntityUserPermission } from '../entity-user-permission.extension'; +import type { MetaEntityUserPermission } from '../entity-user-permission.extension.js'; +import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; export abstract class UmbInputUserPermissionBaseElement< ManifestPermissionType extends ManifestElement & { meta: MetaEntityUserPermission }, diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/user-extension-permission.extension.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/user-extension-permission.extension.ts index 5b588d7f3f54..cd27f55e468a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/user-extension-permission.extension.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/user-extension-permission.extension.ts @@ -1,5 +1,5 @@ import type { ManifestElement } from '@umbraco-cms/backoffice/extension-api'; -import type { MetaEntityUserPermission } from './entity-user-permission.extension'; +import type { MetaEntityUserPermission } from './entity-user-permission.extension.js'; export interface ManifestExtensionPermissions extends ManifestElement { type: 'extensionPermissions';