From 8b064da828bc72fc7eea48d71bb2e21b0b6bb6ef Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 28 Sep 2023 16:22:33 +0200 Subject: [PATCH 01/44] make element to render a list of user permissions based on an entity --- ...-user-permission-settings-modal.element.ts | 3 + .../src/packages/users/index.ts | 1 + .../src/packages/users/manifests.ts | 1 + ...r-group-default-permission-list.element.ts | 65 +++-------- .../workspace/user-group-workspace.context.ts | 25 +++- ...y-user-permission-settings-list.element.ts | 108 ++++++++++++++++++ .../users/user-permission/components/index.ts | 3 + .../packages/users/user-permission/index.ts | 1 + 8 files changed, 154 insertions(+), 53 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/users/user-permission/components/entity-user-permission-settings-list/entity-user-permission-settings-list.element.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/users/user-permission/components/index.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/users/user-permission/index.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/entity-user-permission-settings/entity-user-permission-settings-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/entity-user-permission-settings/entity-user-permission-settings-modal.element.ts index cacdb22527..12ca57fae9 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/entity-user-permission-settings/entity-user-permission-settings-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/entity-user-permission-settings/entity-user-permission-settings-modal.element.ts @@ -40,6 +40,9 @@ export class UmbEntityUserPermissionSettingsModalElement extends UmbLitElement { return html` + + Render user permissions for ${this.data?.entityType} ${this.data?.unique} ${this._userPermissionManifests.map((permission) => this.#renderPermission(permission))} diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/index.ts b/src/Umbraco.Web.UI.Client/src/packages/users/index.ts index 2f1673f76b..14c64c8860 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/index.ts @@ -2,3 +2,4 @@ export * from './current-user/index.js'; export * from './user-groups/index.js'; export * from './users/index.js'; export * from './manifests.js'; +export * from './user-permission/index.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/users/manifests.ts index 74b7562a5d..17ba9f2252 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/manifests.ts @@ -6,5 +6,6 @@ import { manifests as currentUserManifests } from './current-user/manifests.js'; // We need to load any components that are not loaded by the user management bundle to register them in the browser. import './user-groups/components/index.js'; import './users/components/index.js'; +import './user-permission/components/index.js'; export const manifests = [...userGroupManifests, ...userManifests, ...userSectionManifests, ...currentUserManifests]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/workspace/components/user-group-default-permission-list.element.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/workspace/components/user-group-default-permission-list.element.ts index 84d7880f9e..159514af83 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/workspace/components/user-group-default-permission-list.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/workspace/components/user-group-default-permission-list.element.ts @@ -1,20 +1,14 @@ import { UMB_USER_GROUP_WORKSPACE_CONTEXT } from '../user-group-workspace.context.js'; -import { html, customElement, state, ifDefined, nothing } from '@umbraco-cms/backoffice/external/lit'; +import { html, customElement, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; -import { UserGroupResponseModel } from '@umbraco-cms/backoffice/backend-api'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; -import { ManifestUserPermission, umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; -import { UmbChangeEvent } from '@umbraco-cms/backoffice/events'; -import { type UmbUserPermissionSettingElement } from '@umbraco-cms/backoffice/users'; -import { groupBy } from '@umbraco-cms/backoffice/external/lodash'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; +import { UmbSelectedEvent } from '@umbraco-cms/backoffice/events'; @customElement('umb-user-group-default-permission-list') export class UmbUserGroupDefaultPermissionListElement extends UmbLitElement { @state() - private _userGroup?: UserGroupResponseModel; - - @state() - private _manifests: Array = []; + private _userGroupDefaultPermissions?: Array; @state() private _entityTypes: Array = []; @@ -28,27 +22,23 @@ export class UmbUserGroupDefaultPermissionListElement extends UmbLitElement { this.consumeContext(UMB_USER_GROUP_WORKSPACE_CONTEXT, (instance) => { this.#userGroupWorkspaceContext = instance; - this.observe(this.#userGroupWorkspaceContext.data, (userGroup) => (this._userGroup = userGroup)); + this.observe( + this.#userGroupWorkspaceContext.data, + (userGroup) => (this._userGroupDefaultPermissions = userGroup?.permissions), + ); }); } #observeUserPermissions() { this.observe(umbExtensionsRegistry.extensionsOfType('userPermission'), (userPermissionManifests) => { - this._manifests = userPermissionManifests; this._entityTypes = [...new Set(userPermissionManifests.map((manifest) => manifest.meta.entityType))]; }); } - #onChangeUserPermission(event: UmbChangeEvent, userPermissionManifest: ManifestUserPermission) { - const target = event.target as UmbUserPermissionSettingElement; - - target.allowed - ? this.#userGroupWorkspaceContext?.addPermission(userPermissionManifest.alias) - : this.#userGroupWorkspaceContext?.removePermission(userPermissionManifest.alias); - } - - #isAllowed(permissionAlias: string) { - return this._userGroup?.permissions?.includes(permissionAlias); + #onSelectedUserPermission(event: UmbSelectedEvent) { + const target = event.target as any; + const selection = target.selectedPermissions; + this.#userGroupWorkspaceContext?.setDefaultPermissions(selection); } render() { @@ -56,38 +46,15 @@ export class UmbUserGroupDefaultPermissionListElement extends UmbLitElement { } #renderPermissionsByEntityType(entityType: string) { - const permissionsForEntityType = this._manifests.filter((manifest) => manifest.meta.entityType === entityType); return html`

${entityType}

- ${this.#renderGroupedPermissions(permissionsForEntityType)} + `; } - #renderGroupedPermissions(permissions: Array) { - const groupedPermissions = groupBy(permissions, (manifest) => manifest.meta.group); - return html` - ${Object.entries(groupedPermissions).map( - ([group, manifests]) => html` - ${group !== 'undefined' - ? html`
${group}
` - : nothing} - ${manifests.map((manifest) => html` ${this.#renderPermission(manifest)} `)} - `, - )} - `; - } - - #renderPermission(manifest: ManifestUserPermission) { - return html` - this.#onChangeUserPermission(event, manifest)}>`; - } - static styles = [UmbTextStyles]; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/workspace/user-group-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/workspace/user-group-workspace.context.ts index d750f28faf..4fa827c4ec 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/workspace/user-group-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/workspace/user-group-workspace.context.ts @@ -107,22 +107,39 @@ export class UmbUserGroupWorkspaceContext } /** - * Adds a permission to the user group permission array. + * Sets the user group default permissions. + * @param {Array} permissionAliases + * @memberof UmbUserGroupWorkspaceContext + */ + setDefaultPermissions(permissionAliases: Array) { + this.#data.update({ permissions: permissionAliases }); + } + + /** + * Gets the user group default permissions. + * @memberof UmbUserGroupWorkspaceContext + */ + getDefaultPermissions() { + return this.#data.getValue()?.permissions ?? []; + } + + /** + * Allows a default permission on the user group. * @param {string} permissionAlias * @memberof UmbUserGroupWorkspaceContext */ - addPermission(permissionAlias: string) { + allowDefaultPermission(permissionAlias: string) { const permissions = this.#data.getValue()?.permissions ?? []; const newValue = [...permissions, permissionAlias]; this.#data.update({ permissions: newValue }); } /** - * Removes a permission from the user group permission array. + * Disallows a default permission on the user group. * @param {string} permissionAlias * @memberof UmbUserGroupWorkspaceContext */ - removePermission(permissionAlias: string) { + disallowDefaultPermission(permissionAlias: string) { const permissions = this.#data.getValue()?.permissions ?? []; const newValue = permissions.filter((alias) => alias !== permissionAlias); this.#data.update({ permissions: newValue }); diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/components/entity-user-permission-settings-list/entity-user-permission-settings-list.element.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/components/entity-user-permission-settings-list/entity-user-permission-settings-list.element.ts new file mode 100644 index 0000000000..bf86e94b36 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/components/entity-user-permission-settings-list/entity-user-permission-settings-list.element.ts @@ -0,0 +1,108 @@ +import { UmbChangeEvent, UmbSelectedEvent } from '@umbraco-cms/backoffice/events'; +import { + ManifestEntityAction, + ManifestUserPermission, + umbExtensionsRegistry, +} from '@umbraco-cms/backoffice/extension-registry'; +import { css, html, customElement, property, state, nothing, ifDefined } from '@umbraco-cms/backoffice/external/lit'; +import { groupBy } from '@umbraco-cms/backoffice/external/lodash'; +import { UmbObserverController } from '@umbraco-cms/backoffice/observable-api'; +import { UmbUserPermissionSettingElement } from '@umbraco-cms/backoffice/users'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; + +@customElement('umb-entity-user-permission-settings-list') +export class UmbEntityUserPermissionSettingsListElement extends 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.#observeUserPermissions(); + } + private _entityType: string = ''; + + @property({ attribute: false }) + selectedPermissions: Array = []; + + @state() + private _manifests: Array = []; + + #manifestObserver?: UmbObserverController>; + + #isAllowed(permissionAlias: string) { + return this.selectedPermissions?.includes(permissionAlias); + } + + #observeUserPermissions() { + this.#manifestObserver?.destroy(); + + this.#manifestObserver = this.observe( + umbExtensionsRegistry.extensionsOfType('userPermission'), + (userPermissionManifests) => { + this._manifests = userPermissionManifests.filter((manifest) => manifest.meta.entityType === this.entityType); + }, + ); + } + + #onChangeUserPermission(event: UmbChangeEvent, permissionAlias: string) { + event.stopPropagation(); + const target = event.target as UmbUserPermissionSettingElement; + target.allowed ? this.#addUserPermission(permissionAlias) : this.#removeUserPermission(permissionAlias); + } + + #addUserPermission(permissionAlias: string) { + this.selectedPermissions = [...this.selectedPermissions, permissionAlias]; + this.dispatchEvent(new UmbSelectedEvent()); + } + + #removeUserPermission(permissionAlias: string) { + this.selectedPermissions = this.selectedPermissions.filter((alias) => alias !== permissionAlias); + this.dispatchEvent(new UmbSelectedEvent()); + } + + render() { + return html`${this.#renderGroupedPermissions(this._manifests)} `; + } + + #renderGroupedPermissions(permissionManifests: Array) { + const groupedPermissions = groupBy(permissionManifests, (manifest) => manifest.meta.group); + return html` + ${Object.entries(groupedPermissions).map( + ([group, manifests]) => html` + ${group !== 'undefined' + ? html`
${group}
` + : nothing} + ${manifests.map((manifest) => html` ${this.#renderPermission(manifest)} `)} + `, + )} + `; + } + + #renderPermission(manifest: ManifestUserPermission) { + return html` + this.#onChangeUserPermission(event, manifest.alias)}>`; + } + + disconnectedCallback() { + super.disconnectedCallback(); + this.#manifestObserver?.destroy(); + } + + static styles = [css``]; +} + +export default UmbEntityUserPermissionSettingsListElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-entity-user-permission-settings-list': UmbEntityUserPermissionSettingsListElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/components/index.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/components/index.ts new file mode 100644 index 0000000000..782bc56df3 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/components/index.ts @@ -0,0 +1,3 @@ +import './entity-user-permission-settings-list/entity-user-permission-settings-list.element.js'; + +export * from './entity-user-permission-settings-list/entity-user-permission-settings-list.element.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/index.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/index.ts new file mode 100644 index 0000000000..8a8c2711ca --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/index.ts @@ -0,0 +1 @@ +export * from './components/index.js'; From 45fdc76a8dd154c7a412ac6595b7d10f5ede50be Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 28 Sep 2023 19:40:09 +0200 Subject: [PATCH 02/44] move user permission condition --- .../src/packages/users/current-user/index.ts | 1 - .../src/packages/users/current-user/manifests.ts | 8 +------- .../{current-user => user-permission}/conditions/index.ts | 0 .../conditions/user-permission.condition.ts | 0 .../src/packages/users/user-permission/index.ts | 1 + .../src/packages/users/user-permission/manifests.ts | 3 +++ 6 files changed, 5 insertions(+), 8 deletions(-) rename src/Umbraco.Web.UI.Client/src/packages/users/{current-user => user-permission}/conditions/index.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/users/{current-user => user-permission}/conditions/user-permission.condition.ts (100%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/users/user-permission/manifests.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/current-user/index.ts b/src/Umbraco.Web.UI.Client/src/packages/users/current-user/index.ts index 4cbce7fc3e..0b68da794d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/current-user/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/current-user/index.ts @@ -1,3 +1,2 @@ // TODO:Do not export store, but instead export future repository export * from './current-user-history.store.js'; -export * from './conditions/index.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/current-user/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/users/current-user/manifests.ts index 8765bc4d95..f6fe418913 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/current-user/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/current-user/manifests.ts @@ -1,6 +1,5 @@ import { manifests as modalManifests } from './modals/manifests.js'; import { manifests as userProfileAppsManifests } from './user-profile-apps/manifests.js'; -import { manifest as userPermissionConditionManifest } from './conditions/user-permission.condition.js'; import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry'; export const headerApps: Array = [ @@ -24,9 +23,4 @@ export const headerApps: Array = [ }, ]; -export const manifests = [ - ...headerApps, - ...modalManifests, - ...userProfileAppsManifests, - userPermissionConditionManifest, -]; +export const manifests = [...headerApps, ...modalManifests, ...userProfileAppsManifests]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/current-user/conditions/index.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/conditions/index.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/users/current-user/conditions/index.ts rename to src/Umbraco.Web.UI.Client/src/packages/users/user-permission/conditions/index.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/current-user/conditions/user-permission.condition.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/conditions/user-permission.condition.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/users/current-user/conditions/user-permission.condition.ts rename to src/Umbraco.Web.UI.Client/src/packages/users/user-permission/conditions/user-permission.condition.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/index.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/index.ts index 8a8c2711ca..c66b5c4636 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/index.ts @@ -1 +1,2 @@ export * from './components/index.js'; +export * from './conditions/index.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/manifests.ts new file mode 100644 index 0000000000..bfdf656b8f --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/manifests.ts @@ -0,0 +1,3 @@ +import { manifest as userPermissionConditionManifest } from './conditions/user-permission.condition.js'; + +export const manifests = [userPermissionConditionManifest]; From 8c66039a6033466d2d6f8172764f342378d05c4f Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 29 Sep 2023 11:48:17 +0200 Subject: [PATCH 03/44] move user-permission parts to user-permission folder --- .../src/packages/core/modal/common/manifests.ts | 6 ------ .../documents/entity-actions/permissions.action.ts | 4 +--- .../src/packages/users/manifests.ts | 9 ++++++++- .../src/packages/users/user-permission/manifests.ts | 3 ++- .../entity-user-permission-settings-modal.element.ts | 7 ++++--- .../packages/users/user-permission/modals/manifests.ts | 8 ++++++++ 6 files changed, 23 insertions(+), 14 deletions(-) rename src/Umbraco.Web.UI.Client/src/packages/{core/modal/common => users/user-permission/modals}/entity-user-permission-settings/entity-user-permission-settings-modal.element.ts (93%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/users/user-permission/modals/manifests.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/manifests.ts index 9f8b55d4f9..6d7044fd52 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/manifests.ts @@ -61,12 +61,6 @@ const modals: Array = [ name: 'Tree Picker Modal', loader: () => import('./tree-picker/tree-picker-modal.element.js'), }, - { - type: 'modal', - alias: 'Umb.Modal.EntityUserPermissionSettings', - name: 'Entity User Permission Settings Modal', - loader: () => import('./entity-user-permission-settings/entity-user-permission-settings-modal.element.js'), - }, ]; export const manifests = [...modals]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions.action.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions.action.ts index b7f53612c2..fce6a7d59a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions.action.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions.action.ts @@ -25,14 +25,12 @@ export class UmbDocumentPermissionsEntityAction extends UmbEntityActionBase + debugger + .entityType=${this.data?.entityType}> Render user permissions for ${this.data?.entityType} ${this.data?.unique} ${this._userPermissionManifests.map((permission) => this.#renderPermission(permission))} @@ -73,7 +74,7 @@ export class UmbEntityUserPermissionSettingsModalElement extends UmbLitElement { return html`
this.#onChangeUserPermission(event, userPermissionManifest)}>
diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/modals/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/modals/manifests.ts new file mode 100644 index 0000000000..ca7d2173bf --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/modals/manifests.ts @@ -0,0 +1,8 @@ +export const manifests = [ + { + type: 'modal', + alias: 'Umb.Modal.EntityUserPermissionSettings', + name: 'Entity User Permission Settings Modal', + loader: () => import('./entity-user-permission-settings/entity-user-permission-settings-modal.element.js'), + }, +]; From 955dbb0f323b6e58864be674d64e2d29b1dedfe6 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Sun, 1 Oct 2023 19:17:15 +0200 Subject: [PATCH 04/44] remove legacy store code --- .../repository/user-group.store.ts | 73 +------------------ 1 file changed, 2 insertions(+), 71 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/repository/user-group.store.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/repository/user-group.store.ts index 8fe2457412..8ca9044e7c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/repository/user-group.store.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/repository/user-group.store.ts @@ -2,10 +2,7 @@ import type { UserGroupDetails } from '../types.js'; import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; import { UmbArrayState } from '@umbraco-cms/backoffice/observable-api'; -import { UmbEntityDetailStore, UmbStoreBase } from '@umbraco-cms/backoffice/store'; - -// TODO: get rid of this type addition & { ... }: -//export type UmbUserGroupStoreItemType = UserGroupDetails & { users?: Array }; +import { UmbStoreBase } from '@umbraco-cms/backoffice/store'; export const UMB_USER_GROUP_STORE_CONTEXT_TOKEN = new UmbContextToken('UmbUserGroupStore'); @@ -15,74 +12,8 @@ export const UMB_USER_GROUP_STORE_CONTEXT_TOKEN = new UmbContextToken { - #groups = new UmbArrayState([], (x) => x.id); - public groups = this.#groups.asObservable(); - +export class UmbUserGroupStore extends UmbStoreBase { constructor(host: UmbControllerHostElement) { super(host, UMB_USER_GROUP_STORE_CONTEXT_TOKEN.toString(), new UmbArrayState([], (x) => x.id)); } - - getScaffold(entityType: string, parentId: string | null) { - return { - id: '', - name: '', - icon: '', - type: 'user-group', - hasChildren: false, - parentId: '', - sections: [], - permissions: [], - users: [], - } as UserGroupDetails; - } - - getAll() { - // TODO: use Fetcher API. - // TODO: only fetch if the data type is not in the store? - fetch(`/umbraco/backoffice/user-groups/list/items`) - .then((res) => res.json()) - .then((data) => { - this.#groups.append(data.items); - }); - - return this.groups; - } - - getByKey(id: string) { - // TODO: use Fetcher API. - // TODO: only fetch if the data type is not in the store? - fetch(`/umbraco/backoffice/user-groups/details/${id}`) - .then((res) => res.json()) - .then((data) => { - this.#groups.append([data]); - }); - - return this.#groups.asObservablePart((userGroups) => userGroups.find((userGroup) => userGroup.id === id)); - } - - async save(userGroups: Array) { - // TODO: use Fetcher API. - - // TODO: implement so user group store updates the users, but these needs to save as well..? - /* - if (this._userStore && userGroup.users) { - await this._userStore.updateUserGroup(userGroup.users, userGroup.id); - } - */ - - try { - const res = await fetch('/umbraco/backoffice/user-groups/save', { - method: 'POST', - body: JSON.stringify(userGroups), - headers: { - 'Content-Type': 'application/json', - }, - }); - const json = await res.json(); - this.#groups.append(json); - } catch (error) { - console.error('Save Data Type error', error); - } - } } From 72575bbcfb271c4d4b6cf39894a079cfc91ed51b Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Sun, 1 Oct 2023 19:19:56 +0200 Subject: [PATCH 05/44] add method to observe all items in a store --- .../src/packages/core/store/store-base.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/store/store-base.ts b/src/Umbraco.Web.UI.Client/src/packages/core/store/store-base.ts index d8e404867b..004499b99b 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/store/store-base.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/store/store-base.ts @@ -63,4 +63,12 @@ export class UmbStoreBase implements UmbStore) { this._data.remove(uniques); } + + /** + * Returns an observable of the entire store + * @memberof UmbStoreBase + */ + all() { + return this._data.asObservable(); + } } From 9e0edd4daef24e26d70b29d83f253e515f7e5602 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Sun, 1 Oct 2023 19:20:27 +0200 Subject: [PATCH 06/44] add user group collection repository --- .../user-group-collection.repository.ts | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/users/user-groups/repository/collection/user-group-collection.repository.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/repository/collection/user-group-collection.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/repository/collection/user-group-collection.repository.ts new file mode 100644 index 0000000000..5d96360c97 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/repository/collection/user-group-collection.repository.ts @@ -0,0 +1,35 @@ +import { UmbUserGroupCollectionFilterModel } from '../../types.js'; +import { UmbUserGroupCollectionServerDataSource } from '../sources/user-group-collection.server.data.js'; +import { UMB_USER_GROUP_STORE_CONTEXT_TOKEN, UmbUserGroupStore } from '../user-group.store.js'; +import { UserGroupResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import { UmbCollectionDataSource, UmbCollectionRepository } from '@umbraco-cms/backoffice/repository'; +import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; +import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; + +// TODO: implement +export class UmbUserGroupRepository implements UmbCollectionRepository { + #host: UmbControllerHostElement; + #init; + + #detailStore?: UmbUserGroupStore; + #collectionSource: UmbCollectionDataSource; + + constructor(host: UmbControllerHostElement) { + this.#host = host; + this.#collectionSource = new UmbUserGroupCollectionServerDataSource(this.#host); + + this.#init = Promise.all([ + new UmbContextConsumerController(this.#host, UMB_USER_GROUP_STORE_CONTEXT_TOKEN, (instance) => { + this.#detailStore = instance; + }).asPromise(), + ]); + } + + async requestCollection(filter: UmbUserGroupCollectionFilterModel = { skip: 0, take: 100 }) { + await this.#init; + + const { data, error } = await this.#collectionSource.filterCollection(filter); + + return { data, error, asObservable: () => this.#detailStore!.all() }; + } +} From 7d20440cb4619a05e623929a82494be442140c4b Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Sun, 1 Oct 2023 19:25:10 +0200 Subject: [PATCH 07/44] add user group collection repository --- .../repository/collection/user-group-collection.repository.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/repository/collection/user-group-collection.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/repository/collection/user-group-collection.repository.ts index 5d96360c97..76e0c29d71 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/repository/collection/user-group-collection.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/repository/collection/user-group-collection.repository.ts @@ -6,8 +6,7 @@ import { UmbCollectionDataSource, UmbCollectionRepository } from '@umbraco-cms/b import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; -// TODO: implement -export class UmbUserGroupRepository implements UmbCollectionRepository { +export class UmbUserGroupCollectionRepository implements UmbCollectionRepository { #host: UmbControllerHostElement; #init; From 2c0002be2fb7751a5ef0f7046201874c5508859a Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Sun, 1 Oct 2023 19:25:28 +0200 Subject: [PATCH 08/44] remove collection method from detail repository --- .../repository/user-group.repository.ts | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/repository/user-group.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/repository/user-group.repository.ts index 6f4e013de3..8910e5ffed 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/repository/user-group.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/repository/user-group.repository.ts @@ -1,6 +1,5 @@ -import { UmbUserGroupCollectionFilterModel, UmbUserGroupDetailDataSource } from '../types.js'; +import { UmbUserGroupDetailDataSource } from '../types.js'; import { UmbUserGroupServerDataSource } from './sources/user-group.server.data.js'; -import { UmbUserGroupCollectionServerDataSource } from './sources/user-group-collection.server.data.js'; import { UMB_USER_GROUP_ITEM_STORE_CONTEXT_TOKEN, UmbUserGroupItemStore } from './user-group-item.store.js'; import { UMB_USER_GROUP_STORE_CONTEXT_TOKEN, UmbUserGroupStore } from './user-group.store.js'; import { UmbUserGroupItemServerDataSource } from './sources/user-group-item.server.data.js'; @@ -13,8 +12,6 @@ import { UserGroupResponseModel, } from '@umbraco-cms/backoffice/backend-api'; import { - UmbCollectionDataSource, - UmbCollectionRepository, UmbDetailRepository, UmbItemDataSource, UmbItemRepository, @@ -29,7 +26,6 @@ import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controlle export class UmbUserGroupRepository implements UmbDetailRepository, - UmbCollectionRepository, UmbItemRepository { #host: UmbControllerHostElement; @@ -38,8 +34,6 @@ export class UmbUserGroupRepository #detailSource: UmbUserGroupDetailDataSource; #detailStore?: UmbUserGroupStore; - #collectionSource: UmbCollectionDataSource; - #itemSource: UmbItemDataSource; #itemStore?: UmbUserGroupItemStore; @@ -49,7 +43,6 @@ export class UmbUserGroupRepository this.#host = host; this.#detailSource = new UmbUserGroupServerDataSource(this.#host); this.#itemSource = new UmbUserGroupItemServerDataSource(this.#host); - this.#collectionSource = new UmbUserGroupCollectionServerDataSource(this.#host); new UmbContextConsumerController(this.#host, UMB_NOTIFICATION_CONTEXT_TOKEN, (instance) => { this.#notificationContext = instance; @@ -69,16 +62,11 @@ export class UmbUserGroupRepository }).asPromise(), ]); } + createScaffold(parentId: string | null): Promise> { return this.#detailSource.createScaffold(parentId); } - // COLLECTION - async requestCollection(filter: UmbUserGroupCollectionFilterModel = { skip: 0, take: 100 }) { - //TODO: missing observable - return this.#collectionSource.filterCollection(filter); - } - // ITEMS: async requestItems(ids: Array) { if (!ids) throw new Error('Ids are missing'); From 947b38d4abe624da7fada049267b391d9518d64f Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Sun, 1 Oct 2023 19:25:37 +0200 Subject: [PATCH 09/44] export repos --- .../src/packages/users/user-groups/index.ts | 1 + .../src/packages/users/user-groups/repository/index.ts | 2 ++ 2 files changed, 3 insertions(+) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/users/user-groups/repository/index.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/index.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/index.ts index 81c17a6f51..aa325b8354 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/index.ts @@ -1,4 +1,5 @@ export * from './types.js'; export * from './components/index.js'; +export * from './repository/index.js'; export const UMB_USER_GROUP_ENTITY_TYPE = 'user-group'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/repository/index.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/repository/index.ts new file mode 100644 index 0000000000..9b5841d1bb --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/repository/index.ts @@ -0,0 +1,2 @@ +export * from './user-group.repository.js'; +export * from './collection/user-group-collection.repository.js'; From 84f7c5d989c424c56d8911f78156a0240fb93180 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Sun, 1 Oct 2023 19:30:32 +0200 Subject: [PATCH 10/44] move collection source next to collection repo --- .../repository/collection/user-group-collection.repository.ts | 2 +- .../user-group-collection.server.data.ts | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename src/Umbraco.Web.UI.Client/src/packages/users/user-groups/repository/{sources => collection}/user-group-collection.server.data.ts (100%) diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/repository/collection/user-group-collection.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/repository/collection/user-group-collection.repository.ts index 76e0c29d71..6cfaf3c684 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/repository/collection/user-group-collection.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/repository/collection/user-group-collection.repository.ts @@ -1,6 +1,6 @@ import { UmbUserGroupCollectionFilterModel } from '../../types.js'; -import { UmbUserGroupCollectionServerDataSource } from '../sources/user-group-collection.server.data.js'; import { UMB_USER_GROUP_STORE_CONTEXT_TOKEN, UmbUserGroupStore } from '../user-group.store.js'; +import { UmbUserGroupCollectionServerDataSource } from './user-group-collection.server.data.js'; import { UserGroupResponseModel } from '@umbraco-cms/backoffice/backend-api'; import { UmbCollectionDataSource, UmbCollectionRepository } from '@umbraco-cms/backoffice/repository'; import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/repository/sources/user-group-collection.server.data.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/repository/collection/user-group-collection.server.data.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/users/user-groups/repository/sources/user-group-collection.server.data.ts rename to src/Umbraco.Web.UI.Client/src/packages/users/user-groups/repository/collection/user-group-collection.server.data.ts From 42dbdd5f48a69ff61d2d93a2cd9fe27336b14a07 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Sun, 1 Oct 2023 19:35:07 +0200 Subject: [PATCH 11/44] make component folder in collection folder --- .../user-group-collection-header.element.ts | 13 ++++++++++--- .../user-group-table-name-column-layout.element.ts | 0 ...er-group-table-sections-column-layout.element.ts | 0 .../user-group-collection-view.element.ts | 6 +++--- .../collection/user-group-collection.element.ts | 4 ++-- 5 files changed, 15 insertions(+), 8 deletions(-) rename src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/{ => components}/user-group-collection-header.element.ts (76%) rename src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/{ => components}/user-group-table-name-column-layout.element.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/{ => components}/user-group-table-sections-column-layout.element.ts (100%) diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/user-group-collection-header.element.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/components/user-group-collection-header.element.ts similarity index 76% rename from src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/user-group-collection-header.element.ts rename to src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/components/user-group-collection-header.element.ts index d2034339a4..13a3da0c03 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/user-group-collection-header.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/components/user-group-collection-header.element.ts @@ -1,4 +1,4 @@ -import { UmbUserGroupCollectionContext } from './user-group-collection.context.js'; +import { UmbUserGroupCollectionContext } from '../user-group-collection.context.js'; import { UUIInputEvent } from '@umbraco-cms/backoffice/external/uui'; import { css, html, customElement } from '@umbraco-cms/backoffice/external/lit'; import { UMB_COLLECTION_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/collection'; @@ -26,8 +26,15 @@ export class UmbUserGroupCollectionHeaderElement extends UmbLitElement { render() { return html` - - + + `; } static styles = [ diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/user-group-table-name-column-layout.element.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/components/user-group-table-name-column-layout.element.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/user-group-table-name-column-layout.element.ts rename to src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/components/user-group-table-name-column-layout.element.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/user-group-table-sections-column-layout.element.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/components/user-group-table-sections-column-layout.element.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/user-group-table-sections-column-layout.element.ts rename to src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/components/user-group-table-sections-column-layout.element.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/user-group-collection-view.element.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/user-group-collection-view.element.ts index 008728d42a..e046a8c76f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/user-group-collection-view.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/user-group-collection-view.element.ts @@ -1,12 +1,12 @@ import { UmbUserGroupCollectionContext } from './user-group-collection.context.js'; -import { UmbTextStyles } from "@umbraco-cms/backoffice/style"; +import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { css, html, customElement, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; import { UMB_COLLECTION_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/collection'; import { UserGroupResponseModel } from '@umbraco-cms/backoffice/backend-api'; -import './user-group-table-name-column-layout.element.js'; -import './user-group-table-sections-column-layout.element.js'; +import './components/user-group-table-name-column-layout.element.js'; +import './components/user-group-table-sections-column-layout.element.js'; import { UmbTableColumn, UmbTableConfig, diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/user-group-collection.element.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/user-group-collection.element.ts index 31886d123e..f114c45ac0 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/user-group-collection.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/user-group-collection.element.ts @@ -1,11 +1,11 @@ import { UmbUserGroupCollectionContext } from './user-group-collection.context.js'; import { css, html, customElement } from '@umbraco-cms/backoffice/external/lit'; -import { UmbTextStyles } from "@umbraco-cms/backoffice/style"; +import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { UMB_COLLECTION_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/collection'; import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; import './user-group-collection-view.element.js'; -import './user-group-collection-header.element.js'; +import './components/user-group-collection-header.element.js'; @customElement('umb-user-group-collection') export class UmbUserCollectionElement extends UmbLitElement { From 93fdc6ddb05b4b1de0ba464698c8717c4cc235a9 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Sun, 1 Oct 2023 19:35:47 +0200 Subject: [PATCH 12/44] move collection table view into views folder --- .../user-groups/collection/user-group-collection.element.ts | 2 +- .../{ => views}/user-group-collection-view.element.ts | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) rename src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/{ => views}/user-group-collection-view.element.ts (94%) diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/user-group-collection.element.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/user-group-collection.element.ts index f114c45ac0..de99dcab8c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/user-group-collection.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/user-group-collection.element.ts @@ -4,7 +4,7 @@ import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { UMB_COLLECTION_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/collection'; import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; -import './user-group-collection-view.element.js'; +import './views/user-group-collection-view.element.js'; import './components/user-group-collection-header.element.js'; @customElement('umb-user-group-collection') diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/user-group-collection-view.element.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/views/user-group-collection-view.element.ts similarity index 94% rename from src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/user-group-collection-view.element.ts rename to src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/views/user-group-collection-view.element.ts index e046a8c76f..24ceb7cd9f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/user-group-collection-view.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/views/user-group-collection-view.element.ts @@ -1,12 +1,12 @@ -import { UmbUserGroupCollectionContext } from './user-group-collection.context.js'; +import { UmbUserGroupCollectionContext } from '../user-group-collection.context.js'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { css, html, customElement, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; import { UMB_COLLECTION_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/collection'; import { UserGroupResponseModel } from '@umbraco-cms/backoffice/backend-api'; -import './components/user-group-table-name-column-layout.element.js'; -import './components/user-group-table-sections-column-layout.element.js'; +import '../components/user-group-table-name-column-layout.element.js'; +import '../components/user-group-table-sections-column-layout.element.js'; import { UmbTableColumn, UmbTableConfig, From 382fc07c00393d9f518b706826f2fca663eccfb0 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Sun, 1 Oct 2023 19:38:33 +0200 Subject: [PATCH 13/44] add table to name --- .../collection/user-group-collection.element.ts | 2 +- .../views/user-group-collection-view.element.ts | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/user-group-collection.element.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/user-group-collection.element.ts index de99dcab8c..1fcaa48fa8 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/user-group-collection.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/user-group-collection.element.ts @@ -20,7 +20,7 @@ export class UmbUserCollectionElement extends UmbLitElement { return html` - + `; diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/views/user-group-collection-view.element.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/views/user-group-collection-view.element.ts index 24ceb7cd9f..5ae02f3d27 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/views/user-group-collection-view.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/views/user-group-collection-view.element.ts @@ -16,8 +16,8 @@ import { UmbTableSelectedEvent, } from '@umbraco-cms/backoffice/components'; -@customElement('umb-user-group-collection-view') -export class UmbUserGroupCollectionViewElement extends UmbLitElement { +@customElement('umb-user-group-collection-table-view') +export class UmbUserGroupCollectionTableViewElement extends UmbLitElement { @state() private _tableConfig: UmbTableConfig = { allowSelection: true, @@ -134,10 +134,10 @@ export class UmbUserGroupCollectionViewElement extends UmbLitElement { ]; } -export default UmbUserGroupCollectionViewElement; +export default UmbUserGroupCollectionTableViewElement; declare global { interface HTMLElementTagNameMap { - 'umb-user-group-collection-view': UmbUserGroupCollectionViewElement; + 'umb-user-group-collection-table-view': UmbUserGroupCollectionTableViewElement; } } From 29b2984205f0ab51b54e789a63a426450ecb1bf3 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Sun, 1 Oct 2023 19:57:16 +0200 Subject: [PATCH 14/44] register a user group collection repository --- .../collection/user-group-collection.context.ts | 4 ++-- .../users/user-groups/repository/manifests.ts | 11 ++++++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/user-group-collection.context.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/user-group-collection.context.ts index 5e34f817b6..1293a1afa5 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/user-group-collection.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/user-group-collection.context.ts @@ -1,4 +1,4 @@ -import { USER_GROUP_REPOSITORY_ALIAS } from '../repository/manifests.js'; +import { USER_GROUP_COLLECTION_REPOSITORY_ALIAS } from '../repository/manifests.js'; import type { UmbUserGroupCollectionFilterModel } from '../types.js'; import { UmbCollectionContext } from '@umbraco-cms/backoffice/collection'; import type { UserGroupResponseModel } from '@umbraco-cms/backoffice/backend-api'; @@ -9,6 +9,6 @@ export class UmbUserGroupCollectionContext extends UmbCollectionContext< UmbUserGroupCollectionFilterModel > { constructor(host: UmbControllerHostElement) { - super(host, 'user-group', USER_GROUP_REPOSITORY_ALIAS); + super(host, 'user-group', USER_GROUP_COLLECTION_REPOSITORY_ALIAS); } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/repository/manifests.ts index cc7861adc8..4a46c4496b 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/repository/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/repository/manifests.ts @@ -1,9 +1,11 @@ import { UmbUserGroupRepository } from '../repository/user-group.repository.js'; +import { UmbUserGroupCollectionRepository } from './collection/user-group-collection.repository.js'; import { UmbUserGroupItemStore } from './user-group-item.store.js'; import { UmbUserGroupStore } from './user-group.store.js'; import type { ManifestStore, ManifestRepository, ManifestItemStore } from '@umbraco-cms/backoffice/extension-registry'; export const USER_GROUP_REPOSITORY_ALIAS = 'Umb.Repository.UserGroup'; +export const USER_GROUP_COLLECTION_REPOSITORY_ALIAS = 'Umb.Repository.UserGroupCollection'; const repository: ManifestRepository = { type: 'repository', @@ -12,6 +14,13 @@ const repository: ManifestRepository = { class: UmbUserGroupRepository, }; +const collectionRepository: ManifestRepository = { + type: 'repository', + alias: USER_GROUP_COLLECTION_REPOSITORY_ALIAS, + name: 'User Group Collection Repository', + class: UmbUserGroupCollectionRepository, +}; + const store: ManifestStore = { type: 'store', alias: 'Umb.Store.UserGroup', @@ -26,4 +35,4 @@ const itemStore: ManifestItemStore = { class: UmbUserGroupItemStore, }; -export const manifests = [repository, store, itemStore]; +export const manifests = [repository, collectionRepository, store, itemStore]; From ff36ddd97668cdc3ce762adf968141964151205d Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Sun, 1 Oct 2023 20:06:06 +0200 Subject: [PATCH 15/44] move collection repo files into collection folder --- .../packages/users/user-groups/collection/index.ts | 1 + .../users/user-groups/collection/manifests.ts | 3 +++ .../user-groups/collection/repository/index.ts | 1 + .../user-groups/collection/repository/manifests.ts | 13 +++++++++++++ .../repository}/user-group-collection.repository.ts | 2 +- .../user-group-collection.server.data.ts | 0 .../collection/user-group-collection.context.ts | 2 +- .../src/packages/users/user-groups/manifests.ts | 2 ++ .../packages/users/user-groups/repository/index.ts | 1 - .../users/user-groups/repository/manifests.ts | 11 +---------- 10 files changed, 23 insertions(+), 13 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/index.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/manifests.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/repository/index.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/repository/manifests.ts rename src/Umbraco.Web.UI.Client/src/packages/users/user-groups/{repository/collection => collection/repository}/user-group-collection.repository.ts (96%) rename src/Umbraco.Web.UI.Client/src/packages/users/user-groups/{repository/collection => collection/repository}/user-group-collection.server.data.ts (100%) diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/index.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/index.ts new file mode 100644 index 0000000000..3d76f338dd --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/index.ts @@ -0,0 +1 @@ +export * from './repository/index.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/manifests.ts new file mode 100644 index 0000000000..4e1826b900 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/manifests.ts @@ -0,0 +1,3 @@ +import { manifests as repositoryManifests } from './repository/manifests.js'; + +export const manifests = [...repositoryManifests]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/repository/index.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/repository/index.ts new file mode 100644 index 0000000000..b502942922 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/repository/index.ts @@ -0,0 +1 @@ +export * from './user-group-collection.repository.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/repository/manifests.ts new file mode 100644 index 0000000000..173186f61a --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/repository/manifests.ts @@ -0,0 +1,13 @@ +import { UmbUserGroupCollectionRepository } from './user-group-collection.repository.js'; +import { ManifestRepository } from '@umbraco-cms/backoffice/extension-registry'; + +export const USER_GROUP_COLLECTION_REPOSITORY_ALIAS = 'Umb.Repository.UserGroupCollection'; + +const repository: ManifestRepository = { + type: 'repository', + alias: USER_GROUP_COLLECTION_REPOSITORY_ALIAS, + name: 'User Group Collection Repository', + class: UmbUserGroupCollectionRepository, +}; + +export const manifests = [repository]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/repository/collection/user-group-collection.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/repository/user-group-collection.repository.ts similarity index 96% rename from src/Umbraco.Web.UI.Client/src/packages/users/user-groups/repository/collection/user-group-collection.repository.ts rename to src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/repository/user-group-collection.repository.ts index 6cfaf3c684..2516f3884d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/repository/collection/user-group-collection.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/repository/user-group-collection.repository.ts @@ -1,5 +1,5 @@ import { UmbUserGroupCollectionFilterModel } from '../../types.js'; -import { UMB_USER_GROUP_STORE_CONTEXT_TOKEN, UmbUserGroupStore } from '../user-group.store.js'; +import { UMB_USER_GROUP_STORE_CONTEXT_TOKEN, UmbUserGroupStore } from '../../repository/user-group.store.js'; import { UmbUserGroupCollectionServerDataSource } from './user-group-collection.server.data.js'; import { UserGroupResponseModel } from '@umbraco-cms/backoffice/backend-api'; import { UmbCollectionDataSource, UmbCollectionRepository } from '@umbraco-cms/backoffice/repository'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/repository/collection/user-group-collection.server.data.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/repository/user-group-collection.server.data.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/users/user-groups/repository/collection/user-group-collection.server.data.ts rename to src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/repository/user-group-collection.server.data.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/user-group-collection.context.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/user-group-collection.context.ts index 1293a1afa5..da336368a7 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/user-group-collection.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/user-group-collection.context.ts @@ -1,5 +1,5 @@ -import { USER_GROUP_COLLECTION_REPOSITORY_ALIAS } from '../repository/manifests.js'; import type { UmbUserGroupCollectionFilterModel } from '../types.js'; +import { USER_GROUP_COLLECTION_REPOSITORY_ALIAS } from './repository/manifests.js'; import { UmbCollectionContext } from '@umbraco-cms/backoffice/collection'; import type { UserGroupResponseModel } from '@umbraco-cms/backoffice/backend-api'; import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/manifests.ts index 5d01d53186..0fd9d7fe94 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/manifests.ts @@ -1,3 +1,4 @@ +import { manifests as collectionManifests } from './collection/manifests.js'; import { manifests as repositoryManifests } from './repository/manifests.js'; import { manifests as workspaceManifests } from './workspace/manifests.js'; import { manifests as modalManifests } from './modals/manifests.js'; @@ -6,6 +7,7 @@ import { manifests as entityActionManifests } from './entity-actions/manifests.j import { manifests as entityBulkActionManifests } from './entity-bulk-actions/manifests.js'; export const manifests = [ + ...collectionManifests, ...repositoryManifests, ...workspaceManifests, ...modalManifests, diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/repository/index.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/repository/index.ts index 9b5841d1bb..019a8ceb26 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/repository/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/repository/index.ts @@ -1,2 +1 @@ export * from './user-group.repository.js'; -export * from './collection/user-group-collection.repository.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/repository/manifests.ts index 4a46c4496b..cc7861adc8 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/repository/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/repository/manifests.ts @@ -1,11 +1,9 @@ import { UmbUserGroupRepository } from '../repository/user-group.repository.js'; -import { UmbUserGroupCollectionRepository } from './collection/user-group-collection.repository.js'; import { UmbUserGroupItemStore } from './user-group-item.store.js'; import { UmbUserGroupStore } from './user-group.store.js'; import type { ManifestStore, ManifestRepository, ManifestItemStore } from '@umbraco-cms/backoffice/extension-registry'; export const USER_GROUP_REPOSITORY_ALIAS = 'Umb.Repository.UserGroup'; -export const USER_GROUP_COLLECTION_REPOSITORY_ALIAS = 'Umb.Repository.UserGroupCollection'; const repository: ManifestRepository = { type: 'repository', @@ -14,13 +12,6 @@ const repository: ManifestRepository = { class: UmbUserGroupRepository, }; -const collectionRepository: ManifestRepository = { - type: 'repository', - alias: USER_GROUP_COLLECTION_REPOSITORY_ALIAS, - name: 'User Group Collection Repository', - class: UmbUserGroupCollectionRepository, -}; - const store: ManifestStore = { type: 'store', alias: 'Umb.Store.UserGroup', @@ -35,4 +26,4 @@ const itemStore: ManifestItemStore = { class: UmbUserGroupItemStore, }; -export const manifests = [repository, collectionRepository, store, itemStore]; +export const manifests = [repository, store, itemStore]; From 75cac73742035a145a401540e84571e85772484d Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Sun, 1 Oct 2023 20:12:05 +0200 Subject: [PATCH 16/44] export from collection module --- .../src/packages/users/user-groups/index.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/index.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/index.ts index aa325b8354..b52ae132ad 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/index.ts @@ -1,5 +1,6 @@ -export * from './types.js'; +export * from './collection/index.js'; export * from './components/index.js'; export * from './repository/index.js'; +export * from './types.js'; export const UMB_USER_GROUP_ENTITY_TYPE = 'user-group'; From d1e433b2cf25b215a54aaa4b9b8e453dc9ed09fe Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Sun, 1 Oct 2023 21:50:30 +0200 Subject: [PATCH 17/44] update store when items are received so observable works --- .../collection/repository/user-group-collection.repository.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/repository/user-group-collection.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/repository/user-group-collection.repository.ts index 2516f3884d..c0cccf6e8c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/repository/user-group-collection.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/collection/repository/user-group-collection.repository.ts @@ -29,6 +29,10 @@ export class UmbUserGroupCollectionRepository implements UmbCollectionRepository const { data, error } = await this.#collectionSource.filterCollection(filter); + if (data) { + this.#detailStore?.appendItems(data.items); + } + return { data, error, asObservable: () => this.#detailStore!.all() }; } } From 3eb9eab34e1b16f215db5da2d918e872bc7f4977 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Sun, 1 Oct 2023 21:50:53 +0200 Subject: [PATCH 18/44] update user group picker to use collection repository --- .../user-group-picker-modal.element.ts | 52 +++++-------------- 1 file changed, 12 insertions(+), 40 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/modals/user-group-picker/user-group-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/modals/user-group-picker/user-group-picker-modal.element.ts index 18f2f5116d..4a24f3cfbe 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/modals/user-group-picker/user-group-picker-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/modals/user-group-picker/user-group-picker-modal.element.ts @@ -1,12 +1,9 @@ -import type { UmbUserGroupRepository } from '../../repository/user-group.repository.js'; -import { UmbTextStyles } from "@umbraco-cms/backoffice/style"; -import { css, html, customElement, state } from '@umbraco-cms/backoffice/external/lit'; +import { UmbUserGroupCollectionRepository } from '../../collection/repository/index.js'; +import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; +import { css, html, customElement, state, ifDefined } from '@umbraco-cms/backoffice/external/lit'; import { UmbSelectionManagerBase } from '@umbraco-cms/backoffice/utils'; import { UmbModalBaseElement } from '@umbraco-cms/internal/modal'; -import { UmbObserverController } from '@umbraco-cms/backoffice/observable-api'; -import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; import { UserGroupResponseModel } from '@umbraco-cms/backoffice/backend-api'; -import { createExtensionClass } from '@umbraco-cms/backoffice/extension-api'; @customElement('umb-user-group-picker-modal') export class UmbUserGroupPickerModalElement extends UmbModalBaseElement { @@ -14,41 +11,16 @@ export class UmbUserGroupPickerModalElement extends UmbModalBaseElement = []; #selectionManager = new UmbSelectionManagerBase(); - #userGroupRepository?: UmbUserGroupRepository; + #userGroupCollectionRepository = new UmbUserGroupCollectionRepository(this); - connectedCallback(): void { - super.connectedCallback(); - - // TODO: in theory this config could change during the lifetime of the modal, so we could observe it - this.#selectionManager.setMultiple(this.data?.multiple ?? false); - this.#selectionManager.setSelection(this.data?.selection ?? []); - - // TODO: this code is reused in multiple places, so it should be extracted to a function - new UmbObserverController( - this, - umbExtensionsRegistry.getByTypeAndAlias('repository', 'Umb.Repository.UserGroup'), - async (repositoryManifest) => { - if (!repositoryManifest) return; - - try { - const result = await createExtensionClass(repositoryManifest, [this]); - this.#userGroupRepository = result; - this.#observeUserGroups(); - } catch (error) { - throw new Error('Could not create repository with alias: Umb.Repository.User'); - } - } - ); + protected firstUpdated(): void { + this.#observeUserGroups(); } async #observeUserGroups() { - if (!this.#userGroupRepository) return; - // TODO is this the correct end point? - const { data } = await this.#userGroupRepository.requestCollection(); - - if (data) { - this._userGroups = data.items; - } + const { error, asObservable } = await this.#userGroupCollectionRepository.requestCollection(); + if (error) return; + this.observe(asObservable(), (items) => (this._userGroups = items)); } #submit() { @@ -68,14 +40,14 @@ export class UmbUserGroupPickerModalElement extends UmbModalBaseElement html` this.#selectionManager.select(item.id!)} @deselected=${() => this.#selectionManager.deselect(item.id!)} ?selected=${this.#selectionManager.isSelected(item.id!)}> - + - ` + `, )}
From 158e6670f299830cc04c3d51af0c627662096c16 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 2 Oct 2023 09:46:51 +0200 Subject: [PATCH 19/44] wip granular permission entity action --- .../src/packages/core/modal/token/index.ts | 1 + .../modal/token/permissions-modal.token.ts | 15 +++ .../documents/entity-actions/manifests.ts | 15 +-- .../entity-actions/permissions/manifests.ts | 30 ++++++ .../permissions/permissions-modal.element.ts | 93 +++++++++++++++++++ .../{ => permissions}/permissions.action.ts | 16 +++- ...-user-permission-settings-modal.element.ts | 81 +++++++--------- 7 files changed, 184 insertions(+), 67 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/modal/token/permissions-modal.token.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/manifests.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/permissions-modal.element.ts rename src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/{ => permissions}/permissions.action.ts (76%) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/index.ts index 6871d578f7..16e5b7ebb4 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/index.ts @@ -34,3 +34,4 @@ export * from './workspace-modal.token.js'; export * from './data-type-picker-flow-modal.token.js'; export * from './data-type-picker-flow-data-type-picker-modal.token.js'; export * from './entity-user-permission-settings-modal.token.js'; +export * from './permissions-modal.token.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/permissions-modal.token.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/permissions-modal.token.ts new file mode 100644 index 0000000000..01d39b66db --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/permissions-modal.token.ts @@ -0,0 +1,15 @@ +import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; + +export interface UmbPermissionsModalData { + unique: string; + entityType: string; +} + +export type UmbPermissionsModalResult = undefined; + +export const UMB_PERMISSIONS_MODAL = new UmbModalToken( + 'Umb.Modal.Permissions', + { + type: 'sidebar', + }, +); diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/manifests.ts index 6043d524fc..15de3b847f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/manifests.ts @@ -4,10 +4,10 @@ import { UmbPublishDocumentEntityAction } from './publish.action.js'; import { UmbDocumentCultureAndHostnamesEntityAction } from './culture-and-hostnames.action.js'; import { UmbCreateDocumentBlueprintEntityAction } from './create-blueprint.action.js'; import { UmbDocumentPublicAccessEntityAction } from './public-access.action.js'; -import { UmbDocumentPermissionsEntityAction } from './permissions.action.js'; import { UmbUnpublishDocumentEntityAction } from './unpublish.action.js'; import { UmbRollbackDocumentEntityAction } from './rollback.action.js'; import { manifests as createManifests } from './create/manifests.js'; +import { manifests as permissionManifests } from './permissions/manifests.js'; import { UmbCopyEntityAction, UmbMoveEntityAction, @@ -17,6 +17,7 @@ import { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry'; const entityActions: Array = [ ...createManifests, + ...permissionManifests, { type: 'entityAction', alias: 'Umb.EntityAction.Document.CreateBlueprint', @@ -82,18 +83,6 @@ const entityActions: Array = [ entityTypes: [DOCUMENT_ENTITY_TYPE], }, }, - { - type: 'entityAction', - alias: 'Umb.EntityAction.Document.Permissions', - name: 'Document Permissions Entity Action', - meta: { - icon: 'umb:vcard', - label: 'Permissions (TBD)', - repositoryAlias: DOCUMENT_REPOSITORY_ALIAS, - api: UmbDocumentPermissionsEntityAction, - entityTypes: [DOCUMENT_ENTITY_TYPE], - }, - }, { type: 'entityAction', alias: 'Umb.EntityAction.Document.PublicAccess', diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/manifests.ts new file mode 100644 index 0000000000..8513e9a450 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/manifests.ts @@ -0,0 +1,30 @@ +import { DOCUMENT_REPOSITORY_ALIAS } from '../../repository/manifests.js'; +import { UmbDocumentPermissionsEntityAction } from './permissions.action.js'; +import { ManifestEntityAction, ManifestModal } from '@umbraco-cms/backoffice/extension-registry'; +import { DOCUMENT_ENTITY_TYPE } from '@umbraco-cms/backoffice/document'; + +const entityActions: Array = [ + { + type: 'entityAction', + alias: 'Umb.EntityAction.Document.Permissions', + name: 'Document Permissions Entity Action', + meta: { + icon: 'umb:vcard', + label: 'Permissions (TBD)', + repositoryAlias: DOCUMENT_REPOSITORY_ALIAS, + api: UmbDocumentPermissionsEntityAction, + entityTypes: [DOCUMENT_ENTITY_TYPE], + }, + }, +]; + +const modals: Array = [ + { + type: 'modal', + alias: 'Umb.Modal.Permissions', + name: 'Permissions Modal', + loader: () => import('./permissions-modal.element.js'), + }, +]; + +export const manifests = [...entityActions, ...modals]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/permissions-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/permissions-modal.element.ts new file mode 100644 index 0000000000..08529b2421 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/permissions-modal.element.ts @@ -0,0 +1,93 @@ +import { UmbUserGroupCollectionRepository } from '@umbraco-cms/backoffice/user-group'; +import { html, customElement, property, state } from '@umbraco-cms/backoffice/external/lit'; +import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; +import { + UMB_MODAL_MANAGER_CONTEXT_TOKEN, + UMB_USER_GROUP_PICKER_MODAL, + UmbEntityUserPermissionSettingsModalData, + UmbEntityUserPermissionSettingsModalResult, + UmbModalContext, + UmbModalManagerContext, +} from '@umbraco-cms/backoffice/modal'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { UserGroupItemResponseModel } from '@umbraco-cms/backoffice/backend-api'; + +@customElement('umb-permissions-modal') +export class UmbPermissionsModalElement extends UmbLitElement { + @property({ attribute: false }) + modalContext?: UmbModalContext; + + @property({ type: Object }) + data?: UmbEntityUserPermissionSettingsModalData; + + @state() + _userGroups: Array = []; + + #userGroupCollectionRepository = new UmbUserGroupCollectionRepository(this); + #modalManagerContext?: UmbModalManagerContext; + + private _handleConfirm() { + this.modalContext?.submit(); + } + + private _handleCancel() { + this.modalContext?.reject(); + } + + constructor() { + super(); + + this.consumeContext(UMB_MODAL_MANAGER_CONTEXT_TOKEN, (instance) => { + this.#modalManagerContext = instance; + }); + } + + #openUserGroupPickerModal() { + const modalContext = this.#modalManagerContext?.open(UMB_USER_GROUP_PICKER_MODAL); + + modalContext?.onSubmit().then((result) => { + console.log(result); + }); + } + + async firstUpdated() { + const { data } = await this.#userGroupCollectionRepository.requestCollection(); + + if (data) { + this._userGroups = data.items; + } + } + + render() { + return html` + + + Open + + +
    + ${this._userGroups.map((group) => html`
  • ${group}
  • `)} +
+ + Cancel + +
+ `; + } + + static styles = [UmbTextStyles]; +} + +export default UmbPermissionsModalElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-permissions-modal': UmbPermissionsModalElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions.action.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/permissions.action.ts similarity index 76% rename from src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions.action.ts rename to src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/permissions.action.ts index fce6a7d59a..4c31a9f7cf 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions.action.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/permissions.action.ts @@ -1,11 +1,11 @@ -import { type UmbDocumentRepository } from '../repository/document.repository.js'; +import { type UmbDocumentRepository } from '../../repository/document.repository.js'; import { UmbEntityActionBase } from '@umbraco-cms/backoffice/entity-action'; import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; import { UMB_MODAL_MANAGER_CONTEXT_TOKEN, UmbModalManagerContext, - UMB_ENTITY_USER_PERMISSION_MODAL, + UMB_PERMISSIONS_MODAL, } from '@umbraco-cms/backoffice/modal'; export class UmbDocumentPermissionsEntityAction extends UmbEntityActionBase { @@ -20,17 +20,23 @@ export class UmbDocumentPermissionsEntityAction extends UmbEntityActionBase = []; + private _currentUserPermissionsForEntity: Array = []; private _handleConfirm() { this.modalContext?.submit(); @@ -28,63 +38,36 @@ export class UmbEntityUserPermissionSettingsModalElement extends UmbLitElement { this.modalContext?.reject(); } - constructor() { - super(); - this.observe( - umbExtensionsRegistry.extensionsOfType('userPermission'), - (userPermissionManifests) => (this._userPermissionManifests = userPermissionManifests), - ); + #onSelectedUserPermission(event: UmbSelectedEvent) { + const target = event.target as any; + const selection = target.selectedPermissions; } render() { return html` - - debugger + - - - Render user permissions for ${this.data?.entityType} ${this.data?.unique} - ${this._userPermissionManifests.map((permission) => this.#renderPermission(permission))} - - Cancel - + Permissions for ${this.data?.entityType} + Render name here + ${this.data?.entityType + ? html` ` + : nothing} + + Cancel + `; } - #onChangeUserPermission(event: UUIBooleanInputEvent, userPermissionManifest: ManifestUserPermission) { - console.log(userPermissionManifest); - console.log(event.target.checked); - } - - #isAllowed(userPermissionManifest: ManifestUserPermission) { - return true; - //return this._userGroup?.permissions?.includes(userPermissionManifest.alias); - } - - #renderPermission(userPermissionManifest: ManifestUserPermission) { - return html`
- this.#onChangeUserPermission(event, userPermissionManifest)}> -
-
${userPermissionManifest.meta.label}
- ${userPermissionManifest.meta.description} -
-
-
`; - } - static styles = [ UmbTextStyles, css` From ddf5156dd7e38747af2e24adaa23f23bccc3eca7 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 2 Oct 2023 12:56:16 +0200 Subject: [PATCH 20/44] rename selected event to selection change --- .../modal/common/link-picker/link-picker-modal.element.ts | 4 ++-- .../modal/common/tree-picker/tree-picker-modal.element.ts | 6 +++--- .../src/packages/core/tree/tree.context.ts | 6 +++--- .../import/import-dictionary-modal.element.ts | 2 +- .../templating/modals/partial-view-picker-modal.element.ts | 2 +- .../user-group-default-permission-list.element.ts | 6 +++--- .../entity-user-permission-settings-list.element.ts | 6 +++--- .../entity-user-permission-settings-modal.element.ts | 6 +++--- .../src/shared/umb-events/selected.event.ts | 6 ++++-- 9 files changed, 23 insertions(+), 21 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/link-picker/link-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/link-picker/link-picker-modal.element.ts index 941e34451e..bae08949ad 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/link-picker/link-picker-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/link-picker/link-picker-modal.element.ts @@ -154,7 +154,7 @@ export class UmbLinkPickerModalElement extends UmbModalBaseElement this._handleSelectionChange(event, 'document')} + @selection-change=${(event: CustomEvent) => this._handleSelectionChange(event, 'document')} .selection=${[this._selectedKey ?? '']} selectable> @@ -164,7 +164,7 @@ export class UmbLinkPickerModalElement extends UmbModalBaseElement this._handleSelectionChange(event, 'media')} + @selection-change=${(event: CustomEvent) => this._handleSelectionChange(event, 'media')} .selection=${[this._selectedKey ?? '']} selectable>`; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/tree-picker/tree-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/tree-picker/tree-picker-modal.element.ts index adc838d592..07119d8eab 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/tree-picker/tree-picker-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/tree-picker/tree-picker-modal.element.ts @@ -4,7 +4,7 @@ import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { UmbTreePickerModalData, UmbPickerModalValue } from '@umbraco-cms/backoffice/modal'; import { UmbModalBaseElement } from '@umbraco-cms/internal/modal'; import { TreeItemPresentationModel } from '@umbraco-cms/backoffice/backend-api'; -import { UmbSelectedEvent } from '@umbraco-cms/backoffice/events'; +import { UmbSelectionChangeEvent } from '@umbraco-cms/backoffice/events'; @customElement('umb-tree-picker-modal') export class UmbTreePickerModalElement extends UmbModalBaseElement< @@ -28,7 +28,7 @@ export class UmbTreePickerModalElement extends UmbBaseController { @@ -102,12 +102,12 @@ export class UmbTreeContextBase public select(unique: string | null) { if (!this.getSelectable()) return; this.#selectionManager.select(unique); - this._host.getHostElement().dispatchEvent(new UmbSelectedEvent()); + this._host.getHostElement().dispatchEvent(new UmbSelectionChangeEvent()); } public deselect(unique: string | null) { this.#selectionManager.deselect(unique); - this._host.getHostElement().dispatchEvent(new UmbSelectedEvent()); + this._host.getHostElement().dispatchEvent(new UmbSelectionChangeEvent()); } public async requestTreeRoot() { diff --git a/src/Umbraco.Web.UI.Client/src/packages/dictionary/dictionary/entity-actions/import/import-dictionary-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/dictionary/dictionary/entity-actions/import/import-dictionary-modal.element.ts index 105e026be4..ca791dbb67 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/dictionary/dictionary/entity-actions/import/import-dictionary-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/dictionary/dictionary/entity-actions/import/import-dictionary-modal.element.ts @@ -138,7 +138,7 @@ export class UmbImportDictionaryModalLayout extends UmbModalBaseElement< Choose where to import dictionary items (optional) diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/modals/partial-view-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/modals/partial-view-picker-modal.element.ts index 0f9dbc6864..3488a98cff 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/templating/modals/partial-view-picker-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/modals/partial-view-picker-modal.element.ts @@ -43,7 +43,7 @@ export default class UmbPartialViewPickerModalElement extends UmbModalBaseElemen diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/workspace/components/user-group-default-permission-list.element.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/workspace/components/user-group-default-permission-list.element.ts index 159514af83..9ce98ae0a2 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/workspace/components/user-group-default-permission-list.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/workspace/components/user-group-default-permission-list.element.ts @@ -3,7 +3,7 @@ import { html, customElement, state } from '@umbraco-cms/backoffice/external/lit import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; -import { UmbSelectedEvent } from '@umbraco-cms/backoffice/events'; +import { UmbSelectionChangeEvent } from '@umbraco-cms/backoffice/events'; @customElement('umb-user-group-default-permission-list') export class UmbUserGroupDefaultPermissionListElement extends UmbLitElement { @@ -35,7 +35,7 @@ export class UmbUserGroupDefaultPermissionListElement extends UmbLitElement { }); } - #onSelectedUserPermission(event: UmbSelectedEvent) { + #onSelectedUserPermission(event: UmbSelectionChangeEvent) { const target = event.target as any; const selection = target.selectedPermissions; this.#userGroupWorkspaceContext?.setDefaultPermissions(selection); @@ -51,7 +51,7 @@ export class UmbUserGroupDefaultPermissionListElement extends UmbLitElement { + @selection-change=${this.#onSelectedUserPermission}> `; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/components/entity-user-permission-settings-list/entity-user-permission-settings-list.element.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/components/entity-user-permission-settings-list/entity-user-permission-settings-list.element.ts index bf86e94b36..a1e3175094 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/components/entity-user-permission-settings-list/entity-user-permission-settings-list.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/components/entity-user-permission-settings-list/entity-user-permission-settings-list.element.ts @@ -1,4 +1,4 @@ -import { UmbChangeEvent, UmbSelectedEvent } from '@umbraco-cms/backoffice/events'; +import { UmbChangeEvent, UmbSelectionChangeEvent } from '@umbraco-cms/backoffice/events'; import { ManifestEntityAction, ManifestUserPermission, @@ -54,12 +54,12 @@ export class UmbEntityUserPermissionSettingsListElement extends UmbLitElement { #addUserPermission(permissionAlias: string) { this.selectedPermissions = [...this.selectedPermissions, permissionAlias]; - this.dispatchEvent(new UmbSelectedEvent()); + this.dispatchEvent(new UmbSelectionChangeEvent()); } #removeUserPermission(permissionAlias: string) { this.selectedPermissions = this.selectedPermissions.filter((alias) => alias !== permissionAlias); - this.dispatchEvent(new UmbSelectedEvent()); + this.dispatchEvent(new UmbSelectionChangeEvent()); } render() { diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/modals/entity-user-permission-settings/entity-user-permission-settings-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/modals/entity-user-permission-settings/entity-user-permission-settings-modal.element.ts index ed2a6fe24b..0b475ec6ac 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/modals/entity-user-permission-settings/entity-user-permission-settings-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/modals/entity-user-permission-settings/entity-user-permission-settings-modal.element.ts @@ -17,7 +17,7 @@ import { import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; import { ManifestUserPermission, umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; import { UUIBooleanInputEvent } from '@umbraco-cms/backoffice/external/uui'; -import { UmbSelectedEvent } from '@umbraco-cms/backoffice/events'; +import { UmbSelectionChangeEvent } from '@umbraco-cms/backoffice/events'; @customElement('umb-entity-user-permission-settings-modal') export class UmbEntityUserPermissionSettingsModalElement extends UmbLitElement { @@ -38,7 +38,7 @@ export class UmbEntityUserPermissionSettingsModalElement extends UmbLitElement { this.modalContext?.reject(); } - #onSelectedUserPermission(event: UmbSelectedEvent) { + #onSelectedUserPermission(event: UmbSelectionChangeEvent) { const target = event.target as any; const selection = target.selectedPermissions; } @@ -52,7 +52,7 @@ export class UmbEntityUserPermissionSettingsModalElement extends UmbLitElement { ? html` ` + @selection-change=${this.#onSelectedUserPermission}>` : nothing} diff --git a/src/Umbraco.Web.UI.Client/src/shared/umb-events/selected.event.ts b/src/Umbraco.Web.UI.Client/src/shared/umb-events/selected.event.ts index 9ecf5d7767..5b221be196 100644 --- a/src/Umbraco.Web.UI.Client/src/shared/umb-events/selected.event.ts +++ b/src/Umbraco.Web.UI.Client/src/shared/umb-events/selected.event.ts @@ -1,6 +1,8 @@ -export class UmbSelectedEvent extends Event { +export class UmbSelectionChangeEvent extends Event { + public static readonly TYPE = 'selection-change'; + public constructor() { // mimics the native change event - super('selected', { bubbles: true, composed: false, cancelable: false }); + super('selection-change', { bubbles: true, composed: false, cancelable: false }); } } From fa20cecb1d7325bbbd05c01a86f4d2214aeae175 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 2 Oct 2023 13:00:56 +0200 Subject: [PATCH 21/44] update name in type to match element name --- .../views/table/user-collection-table-view.element.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/users/collection/views/table/user-collection-table-view.element.ts b/src/Umbraco.Web.UI.Client/src/packages/users/users/collection/views/table/user-collection-table-view.element.ts index 3fb57752f1..23da09dc8c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/users/collection/views/table/user-collection-table-view.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/users/collection/views/table/user-collection-table-view.element.ts @@ -5,7 +5,7 @@ import { } from '../../../../user-groups/repository/user-group.store.js'; import type { UmbUserDetail } from '../../../types.js'; import { css, html, customElement, state } from '@umbraco-cms/backoffice/external/lit'; -import { UmbTextStyles } from "@umbraco-cms/backoffice/style"; +import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { UmbTableElement, UmbTableColumn, @@ -183,6 +183,6 @@ export default UmbUserCollectionTableViewElement; declare global { interface HTMLElementTagNameMap { - 'umb-workspace-view-users-table': UmbUserCollectionTableViewElement; + 'umb-user-collection-table-view': UmbUserCollectionTableViewElement; } } From d1a9f335b3a5dc232dba83b598bff7032a945e6f Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 2 Oct 2023 13:37:36 +0200 Subject: [PATCH 22/44] look up data in repo instead of store --- .../user-collection-table-view.element.ts | 55 +++++++++---------- 1 file changed, 26 insertions(+), 29 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/users/collection/views/table/user-collection-table-view.element.ts b/src/Umbraco.Web.UI.Client/src/packages/users/users/collection/views/table/user-collection-table-view.element.ts index 23da09dc8c..289235850a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/users/collection/views/table/user-collection-table-view.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/users/collection/views/table/user-collection-table-view.element.ts @@ -1,8 +1,4 @@ import { UmbUserCollectionContext } from '../../user-collection.context.js'; -import { - UmbUserGroupStore, - UMB_USER_GROUP_STORE_CONTEXT_TOKEN, -} from '../../../../user-groups/repository/user-group.store.js'; import type { UmbUserDetail } from '../../../types.js'; import { css, html, customElement, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; @@ -15,12 +11,13 @@ import { UmbTableConfig, UmbTableOrderedEvent, } from '@umbraco-cms/backoffice/components'; -import type { UserGroupEntity } from '@umbraco-cms/backoffice/user-group'; import { UMB_COLLECTION_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/collection'; import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { UmbUserGroupRepository } from '@umbraco-cms/backoffice/user-group'; import './column-layouts/name/user-table-name-column-layout.element.js'; import './column-layouts/status/user-table-status-column-layout.element.js'; +import { UserGroupItemResponseModel } from '@umbraco-cms/backoffice/backend-api'; @customElement('umb-user-collection-table-view') export class UmbUserCollectionTableViewElement extends UmbLitElement { @@ -55,9 +52,9 @@ export class UmbUserCollectionTableViewElement extends UmbLitElement { private _tableItems: Array = []; @state() - private _userGroups: Array = []; + private _userGroupItems: Array = []; - private _userGroupStore?: UmbUserGroupStore; + #UmbUserGroupRepository = new UmbUserGroupRepository(this); @state() private _users: Array = []; @@ -70,36 +67,36 @@ export class UmbUserCollectionTableViewElement extends UmbLitElement { constructor() { super(); - this.consumeContext(UMB_USER_GROUP_STORE_CONTEXT_TOKEN, (instance) => { - this._userGroupStore = instance; - this._observeUserGroups(); - }); - this.consumeContext(UMB_COLLECTION_CONTEXT_TOKEN, (instance) => { this.#collectionContext = instance as UmbUserCollectionContext; this.observe(this.#collectionContext.selection, (selection) => (this._selection = selection)); - this.observe(this.#collectionContext.items, (items) => (this._users = items)); + this.observe(this.#collectionContext.items, (items) => { + this._users = items; + this.#observeUserGroups(); + }); }); } - private _observeUserGroups() { - if (!this._userGroupStore) return; - this.observe(this._userGroupStore.getAll(), (userGroups) => { - this._userGroups = userGroups; - this._createTableItems(this._users); + async #observeUserGroups() { + if (this._users.length === 0) return; + const userGroupsIds = [...new Set(this._users.flatMap((user) => user.userGroupIds ?? []))]; + const { asObservable } = await this.#UmbUserGroupRepository.requestItems(userGroupsIds); + this.observe(asObservable(), (userGroups) => { + this._userGroupItems = userGroups; + this.#createTableItems(); }); } - private _getUserGroupNames(ids: Array) { + #getUserGroupNames(ids: Array) { return ids .map((id: string) => { - return this._userGroups.find((x) => x.id === id)?.name; + return this._userGroupItems.find((x) => x.id === id)?.name; }) .join(', '); } - private _createTableItems(users: Array) { - this._tableItems = users.map((user) => { + #createTableItems() { + this._tableItems = this._users.map((user) => { return { id: user.id ?? '', icon: 'umb:user', @@ -112,7 +109,7 @@ export class UmbUserCollectionTableViewElement extends UmbLitElement { }, { columnAlias: 'userGroup', - value: this._getUserGroupNames(user.userGroupIds ?? []), + value: this.#getUserGroupNames(user.userGroupIds ?? []), }, { columnAlias: 'userLastLogin', @@ -129,21 +126,21 @@ export class UmbUserCollectionTableViewElement extends UmbLitElement { }); } - private _handleSelected(event: UmbTableSelectedEvent) { + #onSelected(event: UmbTableSelectedEvent) { event.stopPropagation(); const table = event.target as UmbTableElement; const selection = table.selection; this.#collectionContext?.setSelection(selection); } - private _handleDeselected(event: UmbTableDeselectedEvent) { + #onDeselected(event: UmbTableDeselectedEvent) { event.stopPropagation(); const table = event.target as UmbTableElement; const selection = table.selection; this.#collectionContext?.setSelection(selection); } - private _handleOrdering(event: UmbTableOrderedEvent) { + #onOrdering(event: UmbTableOrderedEvent) { const table = event.target as UmbTableElement; const orderingColumn = table.orderingColumn; const orderingDesc = table.orderingDesc; @@ -157,9 +154,9 @@ export class UmbUserCollectionTableViewElement extends UmbLitElement { .columns=${this._tableColumns} .items=${this._tableItems} .selection=${this._selection} - @selected="${this._handleSelected}" - @deselected="${this._handleDeselected}" - @ordered="${this._handleOrdering}"> + @selected="${this.#onSelected}" + @deselected="${this.#onDeselected}" + @ordered="${this.#onOrdering}"> `; } From 1a974a49197a6ab3dc17f885ec87bf686ac13e20 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 2 Oct 2023 13:48:16 +0200 Subject: [PATCH 23/44] expose user-permission module --- src/Umbraco.Web.UI.Client/package.json | 1 + .../extension-registry/conditions/types.ts | 2 +- src/Umbraco.Web.UI.Client/tsconfig.json | 41 +++++++++++-------- .../web-test-runner.config.mjs | 1 + 4 files changed, 28 insertions(+), 17 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/package.json b/src/Umbraco.Web.UI.Client/package.json index 5f60362d29..5d7a769b0b 100644 --- a/src/Umbraco.Web.UI.Client/package.json +++ b/src/Umbraco.Web.UI.Client/package.json @@ -68,6 +68,7 @@ "./user-group": "./dist-cms/packages/users/user-groups/index.js", "./current-user": "./dist-cms/packages/users/current-user/index.js", "./users": "./dist-cms/packages/users/users/index.js", + "./user-permission": "./dist-cms/packages/users/user-permission/index.js", "./code-editor": "./dist-cms/packages/templating/code-editor/index.js", "./external/*": "./dist-cms/external/*/index.js" }, diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/conditions/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/conditions/types.ts index 943dbe8d41..50df0dfc1a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/conditions/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/conditions/types.ts @@ -2,7 +2,7 @@ import type { SectionAliasConditionConfig } from './section-alias.condition.js'; import type { SwitchConditionConfig } from './switch.condition.js'; import type { WorkspaceAliasConditionConfig } from '@umbraco-cms/backoffice/workspace'; import type { UmbConditionConfigBase } from '@umbraco-cms/backoffice/extension-api'; -import type { UserPermissionConditionConfig } from '@umbraco-cms/backoffice/current-user'; +import type { UserPermissionConditionConfig } from '@umbraco-cms/backoffice/user-permission'; /* TODO: in theory should't the core package import from other packages. Are there any other way we can do this? */ diff --git a/src/Umbraco.Web.UI.Client/tsconfig.json b/src/Umbraco.Web.UI.Client/tsconfig.json index d4de6fd9d6..af2c59e17a 100644 --- a/src/Umbraco.Web.UI.Client/tsconfig.json +++ b/src/Umbraco.Web.UI.Client/tsconfig.json @@ -19,6 +19,7 @@ "baseUrl": ".", "incremental": true, "paths": { + // TODO: can we combine these of multiple tsconfigs so each package can hold their own? // APPS "@umbraco-cms/backoffice/app": ["src/apps/app"], @@ -79,34 +80,42 @@ "@umbraco-cms/backoffice/workspace": ["src/packages/core/workspace"], "@umbraco-cms/backoffice/culture": ["src/packages/core/culture"], - "@umbraco-cms/backoffice/dictionary": ["./src/packages/dictionary/dictionary/index.ts"], - - "@umbraco-cms/backoffice/document": ["./src/packages/documents/documents/index.ts"], - "@umbraco-cms/backoffice/document-blueprint": ["./src/packages/documents/document-blueprints/index.ts"], - "@umbraco-cms/backoffice/document-type": ["./src/packages/documents/document-types/index.ts"], - "@umbraco-cms/backoffice/media": ["./src/packages/media/media/index.ts"], - "@umbraco-cms/backoffice/media-type": ["./src/packages/media/media-types/index.ts"], - "@umbraco-cms/backoffice/member": ["./src/packages/members/members/index.ts"], - "@umbraco-cms/backoffice/member-group": ["./src/packages/members/member-groups/index.ts"], - "@umbraco-cms/backoffice/member-type": ["./src/packages/members/member-types/index.ts"], - "@umbraco-cms/backoffice/package": ["./src/packages/packages/package/index.ts"], - "@umbraco-cms/backoffice/data-type": ["./src/packages/settings/data-types/index.ts"], "@umbraco-cms/backoffice/language": ["./src/packages/settings/languages/index.ts"], "@umbraco-cms/backoffice/logviewer": ["src/packages/log-viewer/index.ts"], "@umbraco-cms/backoffice/relation-type": ["./src/packages/settings/relation-types/index.ts"], "@umbraco-cms/backoffice/tags": ["./src/packages/tags/index.ts"], - "@umbraco-cms/backoffice/partial-view": ["./src/packages/templating/partial-views/index.ts"], - "@umbraco-cms/backoffice/stylesheet": ["./src/packages/templating/stylesheets/index.ts"], - "@umbraco-cms/backoffice/template": ["./src/packages/templating/templates/index.ts"], - // USERS + "@umbraco-cms/backoffice/dictionary": ["./src/packages/dictionary/dictionary/index.ts"], + + // DOCUMENT MANAGEMENT + "@umbraco-cms/backoffice/document": ["./src/packages/documents/documents/index.ts"], + "@umbraco-cms/backoffice/document-blueprint": ["./src/packages/documents/document-blueprints/index.ts"], + "@umbraco-cms/backoffice/document-type": ["./src/packages/documents/document-types/index.ts"], + + // MEDIA MANAGEMENT + "@umbraco-cms/backoffice/media": ["./src/packages/media/media/index.ts"], + "@umbraco-cms/backoffice/media-type": ["./src/packages/media/media-types/index.ts"], + + // MEMBER MANAGEMENT + "@umbraco-cms/backoffice/member": ["./src/packages/members/members/index.ts"], + "@umbraco-cms/backoffice/member-group": ["./src/packages/members/member-groups/index.ts"], + "@umbraco-cms/backoffice/member-type": ["./src/packages/members/member-types/index.ts"], + + // PACKAGE MANAGEMENT + "@umbraco-cms/backoffice/package": ["./src/packages/packages/package/index.ts"], + + // USER MANAGEMENT "@umbraco-cms/backoffice/user-group": ["src/packages/users/user-groups"], "@umbraco-cms/backoffice/current-user": ["src/packages/users/current-user"], "@umbraco-cms/backoffice/users": ["src/packages/users/users"], + "@umbraco-cms/backoffice/user-permission": ["src/packages/users/user-permission"], // TEMPLATING "@umbraco-cms/backoffice/code-editor": ["src/packages/templating/code-editor"], + "@umbraco-cms/backoffice/partial-view": ["./src/packages/templating/partial-views/index.ts"], + "@umbraco-cms/backoffice/stylesheet": ["./src/packages/templating/stylesheets/index.ts"], + "@umbraco-cms/backoffice/template": ["./src/packages/templating/templates/index.ts"], "@umbraco-cms/backoffice/css": ["src/shared/css/custom-properties.css"], diff --git a/src/Umbraco.Web.UI.Client/web-test-runner.config.mjs b/src/Umbraco.Web.UI.Client/web-test-runner.config.mjs index 397aed2b1b..c1fbdd8be6 100644 --- a/src/Umbraco.Web.UI.Client/web-test-runner.config.mjs +++ b/src/Umbraco.Web.UI.Client/web-test-runner.config.mjs @@ -104,6 +104,7 @@ export default { '@umbraco-cms/backoffice/user-group': './src/packages/users/user-groups/index.ts', '@umbraco-cms/backoffice/current-user': './src/packages/users/current-user/index.ts', '@umbraco-cms/backoffice/users': './src/packages/users/users/index.ts', + '@umbraco-cms/backoffice/user-permission': './src/packages/users/user-permission/index.ts', '@umbraco-cms/backoffice/code-editor': './src/packages/templating/code-editor/index.ts', From 9dce42825a2ba5f7daabae352757124222c92b4b Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 2 Oct 2023 13:48:48 +0200 Subject: [PATCH 24/44] fix import order --- .../src/packages/core/extension-registry/conditions/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/conditions/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/conditions/types.ts index 50df0dfc1a..e2c66be8ed 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/conditions/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/conditions/types.ts @@ -1,8 +1,8 @@ +import type { UserPermissionConditionConfig } from '@umbraco-cms/backoffice/user-permission'; import type { SectionAliasConditionConfig } from './section-alias.condition.js'; import type { SwitchConditionConfig } from './switch.condition.js'; import type { WorkspaceAliasConditionConfig } from '@umbraco-cms/backoffice/workspace'; import type { UmbConditionConfigBase } from '@umbraco-cms/backoffice/extension-api'; -import type { UserPermissionConditionConfig } from '@umbraco-cms/backoffice/user-permission'; /* TODO: in theory should't the core package import from other packages. Are there any other way we can do this? */ From 4298d251725b916f71d70fdf4d3f47e22398f01f Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 2 Oct 2023 13:49:55 +0200 Subject: [PATCH 25/44] rename file to match name --- src/Umbraco.Web.UI.Client/src/shared/umb-events/index.ts | 2 +- .../umb-events/{selected.event.ts => selection-change.event.ts} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename src/Umbraco.Web.UI.Client/src/shared/umb-events/{selected.event.ts => selection-change.event.ts} (100%) diff --git a/src/Umbraco.Web.UI.Client/src/shared/umb-events/index.ts b/src/Umbraco.Web.UI.Client/src/shared/umb-events/index.ts index 5835784021..2e16705e21 100644 --- a/src/Umbraco.Web.UI.Client/src/shared/umb-events/index.ts +++ b/src/Umbraco.Web.UI.Client/src/shared/umb-events/index.ts @@ -2,4 +2,4 @@ export * from './input.event.js'; export * from './change.event.js'; export * from './delete.event.js'; export * from './executed.event.js'; -export * from './selected.event.js'; +export * from './selection-change.event.js'; diff --git a/src/Umbraco.Web.UI.Client/src/shared/umb-events/selected.event.ts b/src/Umbraco.Web.UI.Client/src/shared/umb-events/selection-change.event.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/shared/umb-events/selected.event.ts rename to src/Umbraco.Web.UI.Client/src/shared/umb-events/selection-change.event.ts From 235b5b0e6570c66bc4f39dbf24a3e70ba521388a Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 2 Oct 2023 13:51:29 +0200 Subject: [PATCH 26/44] use static property for type --- .../src/shared/umb-events/selection-change.event.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/shared/umb-events/selection-change.event.ts b/src/Umbraco.Web.UI.Client/src/shared/umb-events/selection-change.event.ts index 5b221be196..ac3351a749 100644 --- a/src/Umbraco.Web.UI.Client/src/shared/umb-events/selection-change.event.ts +++ b/src/Umbraco.Web.UI.Client/src/shared/umb-events/selection-change.event.ts @@ -3,6 +3,6 @@ export class UmbSelectionChangeEvent extends Event { public constructor() { // mimics the native change event - super('selection-change', { bubbles: true, composed: false, cancelable: false }); + super(UmbSelectionChangeEvent.TYPE, { bubbles: true, composed: false, cancelable: false }); } } From 4d9c3bb16505bafad35e3c8b7aef8f8c05aca983 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 2 Oct 2023 14:06:34 +0200 Subject: [PATCH 27/44] add deselected event --- .../src/shared/umb-events/deselected.event.ts | 10 ++++++++++ .../src/shared/umb-events/index.ts | 2 ++ 2 files changed, 12 insertions(+) create mode 100644 src/Umbraco.Web.UI.Client/src/shared/umb-events/deselected.event.ts diff --git a/src/Umbraco.Web.UI.Client/src/shared/umb-events/deselected.event.ts b/src/Umbraco.Web.UI.Client/src/shared/umb-events/deselected.event.ts new file mode 100644 index 0000000000..0f2594503a --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/shared/umb-events/deselected.event.ts @@ -0,0 +1,10 @@ +export class UmbDeselectedEvent extends Event { + public static readonly TYPE = 'deselected'; + public unique: string; + + public constructor(unique: string) { + // mimics the native change event + super(UmbDeselectedEvent.TYPE, { bubbles: true, composed: false, cancelable: false }); + this.unique = unique; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/shared/umb-events/index.ts b/src/Umbraco.Web.UI.Client/src/shared/umb-events/index.ts index 2e16705e21..6c2e2c4464 100644 --- a/src/Umbraco.Web.UI.Client/src/shared/umb-events/index.ts +++ b/src/Umbraco.Web.UI.Client/src/shared/umb-events/index.ts @@ -3,3 +3,5 @@ export * from './change.event.js'; export * from './delete.event.js'; export * from './executed.event.js'; export * from './selection-change.event.js'; +export * from './selected.event.js'; +export * from './deselected.event.js'; From 2b7eabc708a7238c744f9b7f4a6c827630d69fed Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 2 Oct 2023 14:42:12 +0200 Subject: [PATCH 28/44] add selected event --- .../src/shared/umb-events/selected.event.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 src/Umbraco.Web.UI.Client/src/shared/umb-events/selected.event.ts diff --git a/src/Umbraco.Web.UI.Client/src/shared/umb-events/selected.event.ts b/src/Umbraco.Web.UI.Client/src/shared/umb-events/selected.event.ts new file mode 100644 index 0000000000..e3ae853d01 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/shared/umb-events/selected.event.ts @@ -0,0 +1,10 @@ +export class UmbSelectedEvent extends Event { + public static readonly TYPE = 'selected'; + public unique: string; + + public constructor(unique: string) { + // mimics the native change event + super(UmbSelectedEvent.TYPE, { bubbles: true, composed: false, cancelable: false }); + this.unique = unique; + } +} From 38bfdca9b35da951d7a5f6d405c959a57fbbba1e Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 2 Oct 2023 14:43:32 +0200 Subject: [PATCH 29/44] dispatch events for select and deselect --- .../user-group-picker-modal.element.ts | 32 ++++++++++++++++--- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/modals/user-group-picker/user-group-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/modals/user-group-picker/user-group-picker-modal.element.ts index 4a24f3cfbe..6e74832544 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/modals/user-group-picker/user-group-picker-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/modals/user-group-picker/user-group-picker-modal.element.ts @@ -4,6 +4,8 @@ import { css, html, customElement, state, ifDefined } from '@umbraco-cms/backoff import { UmbSelectionManagerBase } from '@umbraco-cms/backoffice/utils'; import { UmbModalBaseElement } from '@umbraco-cms/internal/modal'; import { UserGroupResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import { UUIMenuItemEvent } from '@umbraco-cms/backoffice/external/uui'; +import { UmbSelectedEvent, UmbDeselectedEvent } from '@umbraco-cms/backoffice/events'; @customElement('umb-user-group-picker-modal') export class UmbUserGroupPickerModalElement extends UmbModalBaseElement { @@ -23,10 +25,30 @@ export class UmbUserGroupPickerModalElement extends UmbModalBaseElement (this._userGroups = items)); } + #onSelected(event: UUIMenuItemEvent, item: UserGroupResponseModel) { + if (!item.id) throw new Error('User group id is required'); + event.stopPropagation(); + this.#selectionManager.select(item.id); + this.#updateSelectionValue(); + this.requestUpdate(); + this.modalContext?.dispatchEvent(new UmbSelectedEvent(item.id)); + } + + #onDeselected(event: UUIMenuItemEvent, item: UserGroupResponseModel) { + if (!item.id) throw new Error('User group id is required'); + event.stopPropagation(); + this.#selectionManager.deselect(item.id); + this.#updateSelectionValue(); + this.requestUpdate(); + this.modalContext?.dispatchEvent(new UmbDeselectedEvent(item.id)); + } + + #updateSelectionValue() { + this.modalContext?.updateValue({ selection: this.#selectionManager.getSelection() }); + } + #submit() { - this.modalContext?.submit({ - selection: this.#selectionManager.getSelection(), - }); + this.modalContext?.submit(this._value); } #close() { @@ -42,8 +64,8 @@ export class UmbUserGroupPickerModalElement extends UmbModalBaseElement this.#selectionManager.select(item.id!)} - @deselected=${() => this.#selectionManager.deselect(item.id!)} + @selected=${(event: UUIMenuItemEvent) => this.#onSelected(event, item)} + @deselected=${(event: UUIMenuItemEvent) => this.#onDeselected(event, item)} ?selected=${this.#selectionManager.isSelected(item.id!)}> From 08d8838ec6f64aadce2d4b4680b844bc81a3398d Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 2 Oct 2023 14:43:52 +0200 Subject: [PATCH 30/44] wip listen for select events --- .../permissions/permissions-modal.element.ts | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/permissions-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/permissions-modal.element.ts index 08529b2421..627a220bf4 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/permissions-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/permissions-modal.element.ts @@ -2,6 +2,7 @@ import { UmbUserGroupCollectionRepository } from '@umbraco-cms/backoffice/user-g import { html, customElement, property, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { + UMB_ENTITY_USER_PERMISSION_MODAL, UMB_MODAL_MANAGER_CONTEXT_TOKEN, UMB_USER_GROUP_PICKER_MODAL, UmbEntityUserPermissionSettingsModalData, @@ -11,6 +12,7 @@ import { } from '@umbraco-cms/backoffice/modal'; import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; import { UserGroupItemResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import { UmbSelectedEvent } from '@umbraco-cms/backoffice/events'; @customElement('umb-permissions-modal') export class UmbPermissionsModalElement extends UmbLitElement { @@ -43,10 +45,32 @@ export class UmbPermissionsModalElement extends UmbLitElement { } #openUserGroupPickerModal() { - const modalContext = this.#modalManagerContext?.open(UMB_USER_GROUP_PICKER_MODAL); + if (!this.#modalManagerContext) return; + + const modalContext = this.#modalManagerContext.open(UMB_USER_GROUP_PICKER_MODAL); + + modalContext.addEventListener(UmbSelectedEvent.TYPE, (event) => { + const selectedEvent = event as UmbSelectedEvent; + this.#openUserPermissionsModal(selectedEvent.unique); + }); modalContext?.onSubmit().then((result) => { console.log(result); + debugger; + }); + } + + #openUserPermissionsModal(id: string) { + if (!id) throw new Error('Could not open permissions modal, no id was provided'); + + const modalContext = this.#modalManagerContext?.open(UMB_ENTITY_USER_PERMISSION_MODAL, { + unique: id, + entityType: ['user-group'], + }); + + modalContext?.onSubmit().then((result) => { + console.log(result); + debugger; }); } From 37c4e48fcdbe4060a3489215e9e984c7441fdacc Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 2 Oct 2023 15:46:46 +0200 Subject: [PATCH 31/44] add user group ref element --- .../users/user-groups/components/index.ts | 2 ++ .../user-group-ref/user-group-ref.element.ts | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/users/user-groups/components/user-group-ref/user-group-ref.element.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/components/index.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/components/index.ts index 11d389d6f6..94dd470899 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/components/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/components/index.ts @@ -1,3 +1,5 @@ import './input-user-group/user-group-input.element.js'; +import './user-group-ref/user-group-ref.element.js'; export * from './input-user-group/user-group-input.element.js'; +export * from './user-group-ref/user-group-ref.element.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/components/user-group-ref/user-group-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/components/user-group-ref/user-group-ref.element.ts new file mode 100644 index 0000000000..3c0a2371cf --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/components/user-group-ref/user-group-ref.element.ts @@ -0,0 +1,19 @@ +import { UUIRefNodeElement } from '@umbraco-cms/backoffice/external/uui'; +import { customElement } from '@umbraco-cms/backoffice/external/lit'; +import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api'; + +/** + * @element umb-user-group-ref + * @description - Component for displaying a reference to a User Group + * @extends UUIRefNodeElement + */ +@customElement('umb-user-group-ref') +export class UmbUserGroupRefElement extends UmbElementMixin(UUIRefNodeElement) { + static styles = [...UUIRefNodeElement.styles]; +} + +declare global { + interface HTMLElementTagNameMap { + 'umb-user-group-ref': UmbUserGroupRefElement; + } +} From 82522219a05eb26f02d23c323a36bf871683860f Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 2 Oct 2023 15:47:04 +0200 Subject: [PATCH 32/44] use user group ref element in user group input --- .../input-user-group/user-group-input.element.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/components/input-user-group/user-group-input.element.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/components/input-user-group/user-group-input.element.ts index c2cbe1bcbd..910d439cb9 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/components/input-user-group/user-group-input.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/components/input-user-group/user-group-input.element.ts @@ -1,5 +1,5 @@ import { UmbUserGroupPickerContext } from './user-group-input.context.js'; -import { css, html, customElement, property, state } from '@umbraco-cms/backoffice/external/lit'; +import { css, html, customElement, property, state, ifDefined, nothing } from '@umbraco-cms/backoffice/external/lit'; import { FormControlMixin } from '@umbraco-cms/backoffice/external/uui'; import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; import type { UserGroupItemResponseModel } from '@umbraco-cms/backoffice/backend-api'; @@ -76,13 +76,13 @@ export class UmbUserGroupInputElement extends FormControlMixin(UmbLitElement) { this.addValidator( 'rangeUnderflow', () => this.minMessage, - () => !!this.min && this.#pickerContext.getSelection().length < this.min + () => !!this.min && this.#pickerContext.getSelection().length < this.min, ); this.addValidator( 'rangeOverflow', () => this.maxMessage, - () => !!this.max && this.#pickerContext.getSelection().length > this.max + () => !!this.max && this.#pickerContext.getSelection().length > this.max, ); this.observe(this.#pickerContext.selection, (selection) => (super.value = selection.join(','))); @@ -105,13 +105,15 @@ export class UmbUserGroupInputElement extends FormControlMixin(UmbLitElement) { private _renderItem(item: UserGroupItemResponseModel) { if (!item.id) return; return html` - + + ${item.icon ? html`` : nothing} + this.#pickerContext.requestRemoveItem(item.id!)} label="Remove ${item.name}" >Remove - + `; } From 4edab183de2dabb64a3273aabd7aa5ae4aeb4d28 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 4 Oct 2023 09:22:34 +0200 Subject: [PATCH 33/44] change result to value to align naming --- .../token/entity-user-permission-settings-modal.token.ts | 4 ++-- .../src/packages/core/modal/token/permissions-modal.token.ts | 4 ++-- .../entity-user-permission-settings-modal.element.ts | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/entity-user-permission-settings-modal.token.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/entity-user-permission-settings-modal.token.ts index 62553352fb..b59c79b240 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/entity-user-permission-settings-modal.token.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/entity-user-permission-settings-modal.token.ts @@ -5,11 +5,11 @@ export interface UmbEntityUserPermissionSettingsModalData { entityType: Array; } -export type UmbEntityUserPermissionSettingsModalResult = undefined; +export type UmbEntityUserPermissionSettingsModalValue = undefined; export const UMB_ENTITY_USER_PERMISSION_MODAL = new UmbModalToken< UmbEntityUserPermissionSettingsModalData, - UmbEntityUserPermissionSettingsModalResult + UmbEntityUserPermissionSettingsModalValue >('Umb.Modal.EntityUserPermissionSettings', { type: 'sidebar', }); diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/permissions-modal.token.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/permissions-modal.token.ts index 01d39b66db..e3105cbb3f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/permissions-modal.token.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/permissions-modal.token.ts @@ -5,9 +5,9 @@ export interface UmbPermissionsModalData { entityType: string; } -export type UmbPermissionsModalResult = undefined; +export type UmbPermissionsModalValue = undefined; -export const UMB_PERMISSIONS_MODAL = new UmbModalToken( +export const UMB_PERMISSIONS_MODAL = new UmbModalToken( 'Umb.Modal.Permissions', { type: 'sidebar', diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/modals/entity-user-permission-settings/entity-user-permission-settings-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/modals/entity-user-permission-settings/entity-user-permission-settings-modal.element.ts index 0b475ec6ac..d21c07477d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/modals/entity-user-permission-settings/entity-user-permission-settings-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/modals/entity-user-permission-settings/entity-user-permission-settings-modal.element.ts @@ -11,7 +11,7 @@ import { import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { UmbEntityUserPermissionSettingsModalData, - UmbEntityUserPermissionSettingsModalResult, + UmbEntityUserPermissionSettingsModalValue, UmbModalContext, } from '@umbraco-cms/backoffice/modal'; import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @@ -22,7 +22,7 @@ import { UmbSelectionChangeEvent } from '@umbraco-cms/backoffice/events'; @customElement('umb-entity-user-permission-settings-modal') export class UmbEntityUserPermissionSettingsModalElement extends UmbLitElement { @property({ attribute: false }) - modalContext?: UmbModalContext; + modalContext?: UmbModalContext; @property({ type: Object }) data?: UmbEntityUserPermissionSettingsModalData; From c95f21af6772fc2404942d8308e6935367d3392a Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 4 Oct 2023 13:12:13 +0200 Subject: [PATCH 34/44] render user permissions on user-group-ref --- .../permissions/permissions-modal.element.ts | 126 +++++++++++++----- .../user-group-ref/user-group-ref.element.ts | 50 ++++++- 2 files changed, 141 insertions(+), 35 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/permissions-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/permissions-modal.element.ts index 627a220bf4..467be649c3 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/permissions-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/permissions-modal.element.ts @@ -1,33 +1,80 @@ -import { UmbUserGroupCollectionRepository } from '@umbraco-cms/backoffice/user-group'; -import { html, customElement, property, state } from '@umbraco-cms/backoffice/external/lit'; +import { UmbUserGroupRepository } from '@umbraco-cms/backoffice/user-group'; +import { html, customElement, property, state, ifDefined } from '@umbraco-cms/backoffice/external/lit'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { UMB_ENTITY_USER_PERMISSION_MODAL, UMB_MODAL_MANAGER_CONTEXT_TOKEN, UMB_USER_GROUP_PICKER_MODAL, UmbEntityUserPermissionSettingsModalData, - UmbEntityUserPermissionSettingsModalResult, + UmbEntityUserPermissionSettingsModalValue, UmbModalContext, UmbModalManagerContext, } from '@umbraco-cms/backoffice/modal'; import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; -import { UserGroupItemResponseModel } from '@umbraco-cms/backoffice/backend-api'; import { UmbSelectedEvent } from '@umbraco-cms/backoffice/events'; +import { UmbId } from '@umbraco-cms/backoffice/id'; +import { + UMB_USER_PERMISSION_DOCUMENT_CREATE, + UMB_USER_PERMISSION_DOCUMENT_READ, +} from '@umbraco-cms/backoffice/document'; + +type UserPermissionModel = { + id: string; + target: PermissionTargetType; + permissions: Array; +}; + +type DocumentGranularPermission = { + entityType: 'document'; + documentId: string; + userGroupId: string; +}; + +type UmbUserGroupRefData = { + id: string; + name?: string; + icon?: string | null; + permissions: Array; +}; @customElement('umb-permissions-modal') export class UmbPermissionsModalElement extends UmbLitElement { @property({ attribute: false }) - modalContext?: UmbModalContext; + modalContext?: UmbModalContext; @property({ type: Object }) data?: UmbEntityUserPermissionSettingsModalData; @state() - _userGroups: Array = []; + _userGroups: Array = []; - #userGroupCollectionRepository = new UmbUserGroupCollectionRepository(this); + @state() + _permissions: Array> = [ + { + id: new UmbId().toString(), + target: { + entityType: 'document', + documentId: '1234-1234-1234', + userGroupId: '9d24dc47-a4bf-427f-8a4a-b900f03b8a12', + }, + permissions: [UMB_USER_PERMISSION_DOCUMENT_CREATE], + }, + { + id: new UmbId().toString(), + target: { + entityType: 'document', + documentId: '1234-1234-1234', + userGroupId: 'f4626511-b0d7-4ab1-aebc-a87871a5dcfa', + }, + permissions: [UMB_USER_PERMISSION_DOCUMENT_READ], + }, + ]; + + #userGroupRepository = new UmbUserGroupRepository(this); #modalManagerContext?: UmbModalManagerContext; + #userGroupPickerModal?: UmbModalContext; + private _handleConfirm() { this.modalContext?.submit(); } @@ -44,20 +91,33 @@ export class UmbPermissionsModalElement extends UmbLitElement { }); } + async connectedCallback(): Promise { + super.connectedCallback(); + + const userGroupIds = [...new Set(this._permissions.map((permission) => permission.target.userGroupId))]; + const { data } = await this.#userGroupRepository.requestItems(userGroupIds); + + const userGroups = data ?? []; + + this._userGroups = this._permissions.map((entry) => { + const userGroup = userGroups.find((userGroup) => userGroup.id == entry.target.userGroupId); + return { + id: entry.target.userGroupId, + name: userGroup?.name, + icon: userGroup?.icon, + permissions: entry.permissions, + }; + }); + } + #openUserGroupPickerModal() { if (!this.#modalManagerContext) return; - const modalContext = this.#modalManagerContext.open(UMB_USER_GROUP_PICKER_MODAL); + this.#userGroupPickerModal = this.#modalManagerContext.open(UMB_USER_GROUP_PICKER_MODAL); - modalContext.addEventListener(UmbSelectedEvent.TYPE, (event) => { - const selectedEvent = event as UmbSelectedEvent; - this.#openUserPermissionsModal(selectedEvent.unique); - }); - - modalContext?.onSubmit().then((result) => { - console.log(result); - debugger; - }); + this.#userGroupPickerModal.addEventListener(UmbSelectedEvent.TYPE, (event) => + this.#openUserPermissionsModal((event as UmbSelectedEvent).unique), + ); } #openUserPermissionsModal(id: string) { @@ -65,34 +125,32 @@ export class UmbPermissionsModalElement extends UmbLitElement { const modalContext = this.#modalManagerContext?.open(UMB_ENTITY_USER_PERMISSION_MODAL, { unique: id, - entityType: ['user-group'], + entityType: ['document'], }); - modalContext?.onSubmit().then((result) => { - console.log(result); - debugger; + modalContext?.onSubmit().then((value) => { + console.log(value); }); } - async firstUpdated() { - const { data } = await this.#userGroupCollectionRepository.requestCollection(); - - if (data) { - this._userGroups = data.items; - } - } - render() { return html` - Open + + ${this._userGroups.map( + (userGroup) => + html` + + `, + )} + + Open -
    - ${this._userGroups.map((group) => html`
  • ${group}
  • `)} -
- Cancel { + return []; + } + public set userPermissionAliases(value: Array) { + this.#observeUserPermissions(value); + } + + #userPermissionLabels: Array = []; + + async #observeUserPermissions(value: Array) { + if (value) { + this.observe( + umbExtensionsRegistry.extensionsOfType('userPermission').pipe( + map((manifests) => { + return manifests.filter((manifest) => manifest.alias && value.includes(manifest.alias)); + }), + ), + (userPermissionManifests) => this.#setUserPermissionLabels(userPermissionManifests), + 'userPermissionLabels', + ); + } else { + this.removeControllerByAlias('userPermissionLabels'); + } + } + + #setUserPermissionLabels(manifests: Array) { + this.#userPermissionLabels = manifests.map((manifest) => + manifest.meta.labelKey ? this.localize.term(manifest.meta.labelKey) : manifest.meta.label ?? '', + ); + } + + protected renderDetail() { + const details: string[] = []; + + if (this.#userPermissionLabels.length > 0) { + details.push(this.#userPermissionLabels.join(', ')); + } + + if (this.detail !== '') { + details.push(this.detail); + } + + return html`${details.join(' | ')}`; + } + static styles = [...UUIRefNodeElement.styles]; } From c67db4be48e47937c6f12df50f663b2dbcc22767 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 4 Oct 2023 15:45:45 +0200 Subject: [PATCH 35/44] mock document user permissions --- .../src/mocks/data/document.data.ts | 12 ++++ .../src/mocks/data/entity.data.ts | 4 ++ .../src/mocks/data/user-permission.data.ts | 50 ++++++++++++++++ .../src/mocks/handlers/document/index.ts | 9 ++- .../handlers/document/permission.handlers.ts | 14 +++++ .../permissions/permissions-modal.element.ts | 58 ++++++------------- .../documents/user-permissions/index.ts | 1 + .../documents/user-permissions/manifests.ts | 3 +- .../document-permission.repository.ts | 19 ++++++ .../document-permission.server.data.ts | 32 ++++++++++ .../user-permissions/repository/index.ts | 1 + .../user-permissions/repository/manifests.ts | 13 +++++ .../src/packages/documents/manifests.ts | 2 + .../packages/users/user-permission/index.ts | 13 +++++ 14 files changed, 188 insertions(+), 43 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/mocks/data/user-permission.data.ts create mode 100644 src/Umbraco.Web.UI.Client/src/mocks/handlers/document/permission.handlers.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/documents/documents/user-permissions/repository/document-permission.repository.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/documents/documents/user-permissions/repository/document-permission.server.data.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/documents/documents/user-permissions/repository/index.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/documents/documents/user-permissions/repository/manifests.ts diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/document.data.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/document.data.ts index d7d2a183b3..5af8384cb4 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/document.data.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/document.data.ts @@ -1,4 +1,5 @@ import { umbDocumentTypeData } from './document-type.data.js'; +import { umbUserPermissionData } from './user-permission.data.js'; import { UmbEntityData } from './entity.data.js'; import { createDocumentTreeItem } from './utils.js'; import { @@ -10,6 +11,7 @@ import { PagedDocumentTypeResponseModel, PagedRecycleBinItemResponseModel, } from '@umbraco-cms/backoffice/backend-api'; +import { DOCUMENT_ENTITY_TYPE } from '@umbraco-cms/backoffice/document'; export const data: Array = [ { @@ -673,6 +675,16 @@ class UmbDocumentData extends UmbEntityData { const total = items.length; return { items: treeItems, total }; } + + // permissions + + getUserPermissionsForDocument(id: string): Array { + return umbUserPermissionData + .getAll() + .filter( + (permission) => permission.target.entityType === DOCUMENT_ENTITY_TYPE && permission.target.documentId === id, + ); + } } export const umbDocumentData = new UmbDocumentData(); diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/entity.data.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/entity.data.ts index d6c442fe89..9da17cc4f2 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/entity.data.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/entity.data.ts @@ -8,6 +8,10 @@ export class UmbEntityData extends UmbData { super(data); } + getAll() { + return this.data; + } + getList(skip: number, take: number) { return this.data.slice(skip, skip + take); } diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/user-permission.data.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/user-permission.data.ts new file mode 100644 index 0000000000..84ce815969 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/user-permission.data.ts @@ -0,0 +1,50 @@ +import { UmbEntityData } from './entity.data.js'; +import { + DOCUMENT_ENTITY_TYPE, + UMB_USER_PERMISSION_DOCUMENT_CREATE, + UMB_USER_PERMISSION_DOCUMENT_READ, +} from '@umbraco-cms/backoffice/document'; + +export type UserPermissionModel = { + id: string; + target: unknown; + permissions: Array; +}; + +export const data: Array = [ + { + id: '408074bb-f776-485e-b85e-c2473e45663b', + target: { + entityType: DOCUMENT_ENTITY_TYPE, + documentId: 'simple-document-id', + userGroupId: '9d24dc47-a4bf-427f-8a4a-b900f03b8a12', + }, + permissions: [UMB_USER_PERMISSION_DOCUMENT_READ], + }, + { + id: 'b70b1453-a912-4157-ba62-20c2f0ab6a88', + target: { + entityType: DOCUMENT_ENTITY_TYPE, + documentId: 'simple-document-id', + userGroupId: 'f4626511-b0d7-4ab1-aebc-a87871a5dcfa', + }, + permissions: [UMB_USER_PERMISSION_DOCUMENT_READ, UMB_USER_PERMISSION_DOCUMENT_CREATE], + }, + { + id: 'b70b1453-a912-4157-ba62-20c2f0ab6a88', + target: { + entityType: DOCUMENT_ENTITY_TYPE, + documentId: 'c05da24d-7740-447b-9cdc-bd8ce2172e38', + userGroupId: '9d24dc47-a4bf-427f-8a4a-b900f03b8a12', + }, + permissions: [UMB_USER_PERMISSION_DOCUMENT_READ], + }, +]; + +class UmbUserPermissionData extends UmbEntityData { + constructor() { + super(data); + } +} + +export const umbUserPermissionData = new UmbUserPermissionData(); diff --git a/src/Umbraco.Web.UI.Client/src/mocks/handlers/document/index.ts b/src/Umbraco.Web.UI.Client/src/mocks/handlers/document/index.ts index e847bf2188..f02652bc13 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/handlers/document/index.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/handlers/document/index.ts @@ -2,5 +2,12 @@ import { handlers as recycleBinHandlers } from './recycle-bin.handlers.js'; import { handlers as treeHandlers } from './tree.handlers.js'; import { handlers as documentHandlers } from './document.handlers.js'; import { handlers as itemHandlers } from './item.handlers.js'; +import { handlers as permissionHandlers } from './permission.handlers.js'; -export const handlers = [...recycleBinHandlers, ...treeHandlers, ...itemHandlers, ...documentHandlers]; +export const handlers = [ + ...recycleBinHandlers, + ...permissionHandlers, + ...treeHandlers, + ...itemHandlers, + ...documentHandlers, +]; diff --git a/src/Umbraco.Web.UI.Client/src/mocks/handlers/document/permission.handlers.ts b/src/Umbraco.Web.UI.Client/src/mocks/handlers/document/permission.handlers.ts new file mode 100644 index 0000000000..b130b533f4 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/mocks/handlers/document/permission.handlers.ts @@ -0,0 +1,14 @@ +const { rest } = window.MockServiceWorker; +import { umbDocumentData } from '../../data/document.data.js'; +import { slug } from './slug.js'; +import { umbracoPath } from '@umbraco-cms/backoffice/utils'; + +// TODO: temp handlers until we have a real API +export const handlers = [ + rest.get(umbracoPath(`${slug}/:id/permissions`), (req, res, ctx) => { + const id = req.params.id as string; + if (!id) return; + const response = umbDocumentData.getUserPermissionsForDocument(id); + return res(ctx.status(200), ctx.json(response)); + }), +]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/permissions-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/permissions-modal.element.ts index 467be649c3..d9ef6e0ad3 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/permissions-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/permissions-modal.element.ts @@ -1,3 +1,4 @@ +import { UmbDocumentPermissionRepository } from '../../user-permissions/index.js'; import { UmbUserGroupRepository } from '@umbraco-cms/backoffice/user-group'; import { html, customElement, property, state, ifDefined } from '@umbraco-cms/backoffice/external/lit'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; @@ -12,23 +13,6 @@ import { } from '@umbraco-cms/backoffice/modal'; import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; import { UmbSelectedEvent } from '@umbraco-cms/backoffice/events'; -import { UmbId } from '@umbraco-cms/backoffice/id'; -import { - UMB_USER_PERMISSION_DOCUMENT_CREATE, - UMB_USER_PERMISSION_DOCUMENT_READ, -} from '@umbraco-cms/backoffice/document'; - -type UserPermissionModel = { - id: string; - target: PermissionTargetType; - permissions: Array; -}; - -type DocumentGranularPermission = { - entityType: 'document'; - documentId: string; - userGroupId: string; -}; type UmbUserGroupRefData = { id: string; @@ -49,28 +33,10 @@ export class UmbPermissionsModalElement extends UmbLitElement { _userGroups: Array = []; @state() - _permissions: Array> = [ - { - id: new UmbId().toString(), - target: { - entityType: 'document', - documentId: '1234-1234-1234', - userGroupId: '9d24dc47-a4bf-427f-8a4a-b900f03b8a12', - }, - permissions: [UMB_USER_PERMISSION_DOCUMENT_CREATE], - }, - { - id: new UmbId().toString(), - target: { - entityType: 'document', - documentId: '1234-1234-1234', - userGroupId: 'f4626511-b0d7-4ab1-aebc-a87871a5dcfa', - }, - permissions: [UMB_USER_PERMISSION_DOCUMENT_READ], - }, - ]; + _userPermissions: Array = []; #userGroupRepository = new UmbUserGroupRepository(this); + #documentPermissionRepository = new UmbDocumentPermissionRepository(this); #modalManagerContext?: UmbModalManagerContext; #userGroupPickerModal?: UmbModalContext; @@ -91,15 +57,23 @@ export class UmbPermissionsModalElement extends UmbLitElement { }); } + protected async firstUpdated(): Promise { + if (!this.data?.unique) throw new Error('Could not load permissions, no unique was provided'); + const { data } = await this.#documentPermissionRepository.requestPermissions(this.data.unique); + if (data) { + this._userPermissions = data; + } + } + async connectedCallback(): Promise { super.connectedCallback(); - const userGroupIds = [...new Set(this._permissions.map((permission) => permission.target.userGroupId))]; + const userGroupIds = [...new Set(this._userPermissions.map((permission) => permission.target.userGroupId))]; const { data } = await this.#userGroupRepository.requestItems(userGroupIds); const userGroups = data ?? []; - this._userGroups = this._permissions.map((entry) => { + this._userGroups = this._userPermissions.map((entry) => { const userGroup = userGroups.find((userGroup) => userGroup.id == entry.target.userGroupId); return { id: entry.target.userGroupId, @@ -148,7 +122,9 @@ export class UmbPermissionsModalElement extends UmbLitElement { `, )} - Open + Select user group Cancel @@ -157,7 +133,7 @@ export class UmbPermissionsModalElement extends UmbLitElement { id="confirm" color="positive" look="primary" - label="Confirm" + label="Save" @click=${this._handleConfirm}>
`; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/user-permissions/index.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/user-permissions/index.ts index 1e95b5d703..78c94f0582 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/user-permissions/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/user-permissions/index.ts @@ -1 +1,2 @@ export * from './manifests.js'; +export * from './repository/index.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/user-permissions/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/user-permissions/manifests.ts index 3b8dc13f4f..08f16fa720 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/user-permissions/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/user-permissions/manifests.ts @@ -1,3 +1,4 @@ +import { manifests as repositoryManifests } from './repository/manifests.js'; import type { ManifestUserGranularPermission, ManifestUserPermission, @@ -202,4 +203,4 @@ export const granularPermissions: Array = [ }, ]; -export const manifests = [...permissions, ...granularPermissions]; +export const manifests = [...repositoryManifests, ...permissions, ...granularPermissions]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/user-permissions/repository/document-permission.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/user-permissions/repository/document-permission.repository.ts new file mode 100644 index 0000000000..dd5c7bab41 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/user-permissions/repository/document-permission.repository.ts @@ -0,0 +1,19 @@ +import { t } from 'msw/lib/glossary-de6278a9.js'; +import { UmbDocumentPermissionServerDataSource } from './document-permission.server.data.js'; +import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; + +export class UmbDocumentPermissionRepository { + #host: UmbControllerHostElement; + + #permissionSource: UmbDocumentPermissionServerDataSource; + + constructor(host: UmbControllerHostElement) { + this.#host = host; + this.#permissionSource = new UmbDocumentPermissionServerDataSource(this.#host); + } + + async requestPermissions(id: string) { + if (!id) throw new Error(`id is required`); + return this.#permissionSource.requestPermissions(id); + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/user-permissions/repository/document-permission.server.data.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/user-permissions/repository/document-permission.server.data.ts new file mode 100644 index 0000000000..2b093c3137 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/user-permissions/repository/document-permission.server.data.ts @@ -0,0 +1,32 @@ +import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; +import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; + +/** + * @export + * @class UmbUserGroupCollectionServerDataSource + * @implements {RepositoryDetailDataSource} + */ +export class UmbDocumentPermissionServerDataSource { + #host: UmbControllerHostElement; + + /** + * Creates an instance of UmbDocumentPermissionServerDataSource. + * @param {UmbControllerHostElement} host + * @memberof UmbDocumentPermissionServerDataSource + */ + constructor(host: UmbControllerHostElement) { + this.#host = host; + } + + requestPermissions(id: string) { + return tryExecuteAndNotify( + this.#host, + fetch(`/umbraco/management/api/v1/document/${id}/permissions`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + }, + }).then((res) => res.json()), + ); + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/user-permissions/repository/index.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/user-permissions/repository/index.ts new file mode 100644 index 0000000000..79337c7f92 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/user-permissions/repository/index.ts @@ -0,0 +1 @@ +export * from './document-permission.repository.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/user-permissions/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/user-permissions/repository/manifests.ts new file mode 100644 index 0000000000..7f00473726 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/user-permissions/repository/manifests.ts @@ -0,0 +1,13 @@ +import { UmbDocumentPermissionRepository } from './document-permission.repository.js'; +import { ManifestRepository } from '@umbraco-cms/backoffice/extension-registry'; + +export const UMB_DOCUMENT_PERMISSION_REPOSITORY_ALIAS = 'Umb.Repository.Document.Permission'; + +const repository: ManifestRepository = { + type: 'repository', + alias: UMB_DOCUMENT_PERMISSION_REPOSITORY_ALIAS, + name: 'Document Permission Repository', + class: UmbDocumentPermissionRepository, +}; + +export const manifests = [repository]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/manifests.ts index 17fc8e51b5..0ece551478 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/manifests.ts @@ -4,6 +4,7 @@ import { manifests as contentMenuManifest } from './menu.manifests.js'; import { manifests as documentBlueprintManifests } from './document-blueprints/manifests.js'; import { manifests as documentTypeManifests } from './document-types/manifests.js'; import { manifests as documentManifests } from './documents/manifests.js'; +import { manifests as documentPermissionManifests } from './documents/user-permissions/index.js'; export const manifests = [ ...dashboardManifests, @@ -12,4 +13,5 @@ export const manifests = [ ...documentBlueprintManifests, ...documentTypeManifests, ...documentManifests, + ...documentPermissionManifests, ]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/index.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/index.ts index c66b5c4636..8eed47ad34 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/index.ts @@ -1,2 +1,15 @@ export * from './components/index.js'; export * from './conditions/index.js'; + +export type UserPermissionModel = { + id: string; + target: PermissionTargetType; + permissions: Array; +}; + +// TODO: this should only be known by the document +export type UmbDocumentGranularPermission = { + entityType: 'document'; + documentId: string; + userGroupId: string; +}; From cfb3bcaf112ede8fc9965d8a932c67eccfb7d659 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 4 Oct 2023 15:53:10 +0200 Subject: [PATCH 36/44] map to UI --- .../permissions/permissions-modal.element.ts | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/permissions-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/permissions-modal.element.ts index d9ef6e0ad3..25d47cc311 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/permissions-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/permissions-modal.element.ts @@ -30,15 +30,12 @@ export class UmbPermissionsModalElement extends UmbLitElement { data?: UmbEntityUserPermissionSettingsModalData; @state() - _userGroups: Array = []; - - @state() - _userPermissions: Array = []; + _userGroupRefs: Array = []; + #userPermissions: Array = []; #userGroupRepository = new UmbUserGroupRepository(this); #documentPermissionRepository = new UmbDocumentPermissionRepository(this); #modalManagerContext?: UmbModalManagerContext; - #userGroupPickerModal?: UmbModalContext; private _handleConfirm() { @@ -61,19 +58,18 @@ export class UmbPermissionsModalElement extends UmbLitElement { if (!this.data?.unique) throw new Error('Could not load permissions, no unique was provided'); const { data } = await this.#documentPermissionRepository.requestPermissions(this.data.unique); if (data) { - this._userPermissions = data; + this.#userPermissions = data; + this.#mapToUserGroupRefs(); } } - async connectedCallback(): Promise { - super.connectedCallback(); - - const userGroupIds = [...new Set(this._userPermissions.map((permission) => permission.target.userGroupId))]; + async #mapToUserGroupRefs() { + const userGroupIds = [...new Set(this.#userPermissions.map((permission) => permission.target.userGroupId))]; const { data } = await this.#userGroupRepository.requestItems(userGroupIds); const userGroups = data ?? []; - this._userGroups = this._userPermissions.map((entry) => { + this._userGroupRefs = this.#userPermissions.map((entry) => { const userGroup = userGroups.find((userGroup) => userGroup.id == entry.target.userGroupId); return { id: entry.target.userGroupId, @@ -112,7 +108,7 @@ export class UmbPermissionsModalElement extends UmbLitElement { - ${this._userGroups.map( + ${this._userGroupRefs.map( (userGroup) => html` Date: Wed, 4 Oct 2023 15:55:15 +0200 Subject: [PATCH 37/44] show permission modal for user group when clicking on the ref name --- .../entity-actions/permissions/permissions-modal.element.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/permissions-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/permissions-modal.element.ts index 25d47cc311..4006a39594 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/permissions-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/permissions-modal.element.ts @@ -113,6 +113,7 @@ export class UmbPermissionsModalElement extends UmbLitElement { html` this.#openUserPermissionsModal(userGroup.id)} border> `, From 28f0c017d6adc106b25358663e8ae08b824ae858 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 4 Oct 2023 16:52:02 +0200 Subject: [PATCH 38/44] temp clean up --- .../permissions/permissions.action.ts | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/permissions.action.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/permissions.action.ts index 4c31a9f7cf..f20cd187e4 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/permissions.action.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/permissions.action.ts @@ -23,23 +23,9 @@ export class UmbDocumentPermissionsEntityAction extends UmbEntityActionBase Date: Wed, 4 Oct 2023 16:52:13 +0200 Subject: [PATCH 39/44] show entity name in headline --- .../permissions/permissions-modal.element.ts | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/permissions-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/permissions-modal.element.ts index 4006a39594..f2b7c6e7b1 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/permissions-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/permissions-modal.element.ts @@ -1,4 +1,5 @@ import { UmbDocumentPermissionRepository } from '../../user-permissions/index.js'; +import { UmbDocumentRepository } from '../../repository/index.js'; import { UmbUserGroupRepository } from '@umbraco-cms/backoffice/user-group'; import { html, customElement, property, state, ifDefined } from '@umbraco-cms/backoffice/external/lit'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; @@ -29,12 +30,16 @@ export class UmbPermissionsModalElement extends UmbLitElement { @property({ type: Object }) data?: UmbEntityUserPermissionSettingsModalData; + @state() + _entityItem?: any; + @state() _userGroupRefs: Array = []; #userPermissions: Array = []; #userGroupRepository = new UmbUserGroupRepository(this); #documentPermissionRepository = new UmbDocumentPermissionRepository(this); + #documentRepository = new UmbDocumentRepository(this); #modalManagerContext?: UmbModalManagerContext; #userGroupPickerModal?: UmbModalContext; @@ -56,7 +61,18 @@ export class UmbPermissionsModalElement extends UmbLitElement { protected async firstUpdated(): Promise { if (!this.data?.unique) throw new Error('Could not load permissions, no unique was provided'); - const { data } = await this.#documentPermissionRepository.requestPermissions(this.data.unique); + this.#getEntityItem(this.data.unique); + this.#getEntityPermissions(this.data.unique); + } + + async #getEntityItem(unique: string) { + const { data } = await this.#documentRepository.requestItems([unique]); + if (!data) throw new Error('Could not load item'); + this._entityItem = data[0]; + } + + async #getEntityPermissions(unique: string) { + const { data } = await this.#documentPermissionRepository.requestPermissions(unique); if (data) { this.#userPermissions = data; this.#mapToUserGroupRefs(); @@ -105,7 +121,7 @@ export class UmbPermissionsModalElement extends UmbLitElement { render() { return html` - + ${this._userGroupRefs.map( From c942acadb30a29cfb456267ceed7d0b2ee2b6e0d Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 4 Oct 2023 16:59:42 +0200 Subject: [PATCH 40/44] fix missing missing toggles --- .../entity-user-permission-settings-modal.token.ts | 2 +- .../permissions/permissions-modal.element.ts | 3 ++- ...entity-user-permission-settings-modal.element.ts | 13 +------------ 3 files changed, 4 insertions(+), 14 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/entity-user-permission-settings-modal.token.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/entity-user-permission-settings-modal.token.ts index b59c79b240..79895108e6 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/entity-user-permission-settings-modal.token.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/entity-user-permission-settings-modal.token.ts @@ -2,7 +2,7 @@ import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; export interface UmbEntityUserPermissionSettingsModalData { unique: string; - entityType: Array; + entityType: string; } export type UmbEntityUserPermissionSettingsModalValue = undefined; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/permissions-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/permissions-modal.element.ts index f2b7c6e7b1..413eef0ecc 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/permissions-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/permissions-modal.element.ts @@ -108,10 +108,11 @@ export class UmbPermissionsModalElement extends UmbLitElement { #openUserPermissionsModal(id: string) { if (!id) throw new Error('Could not open permissions modal, no id was provided'); + if (!this.data?.entityType) throw new Error('Could not open permissions modal, no entity type was provided'); const modalContext = this.#modalManagerContext?.open(UMB_ENTITY_USER_PERMISSION_MODAL, { unique: id, - entityType: ['document'], + entityType: this.data.entityType, }); modalContext?.onSubmit().then((value) => { diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/modals/entity-user-permission-settings/entity-user-permission-settings-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/modals/entity-user-permission-settings/entity-user-permission-settings-modal.element.ts index d21c07477d..2d3f176b70 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/modals/entity-user-permission-settings/entity-user-permission-settings-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/modals/entity-user-permission-settings/entity-user-permission-settings-modal.element.ts @@ -1,13 +1,4 @@ -import { - html, - customElement, - property, - state, - css, - ifDefined, - nothing, - PropertyValueMap, -} from '@umbraco-cms/backoffice/external/lit'; +import { html, customElement, property, state, css, nothing } from '@umbraco-cms/backoffice/external/lit'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { UmbEntityUserPermissionSettingsModalData, @@ -15,8 +6,6 @@ import { UmbModalContext, } from '@umbraco-cms/backoffice/modal'; import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; -import { ManifestUserPermission, umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; -import { UUIBooleanInputEvent } from '@umbraco-cms/backoffice/external/uui'; import { UmbSelectionChangeEvent } from '@umbraco-cms/backoffice/events'; @customElement('umb-entity-user-permission-settings-modal') From bff2dc439bc7e250df093e7532e3a72a04461e9a Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 4 Oct 2023 20:54:17 +0200 Subject: [PATCH 41/44] set headline --- ...ty-user-permission-settings-modal.token.ts | 6 +++- .../permissions/permissions-modal.element.ts | 5 +++ ...-user-permission-settings-modal.element.ts | 34 +++++++++++++------ 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/entity-user-permission-settings-modal.token.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/entity-user-permission-settings-modal.token.ts index 79895108e6..2638f4db07 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/entity-user-permission-settings-modal.token.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/entity-user-permission-settings-modal.token.ts @@ -3,9 +3,13 @@ import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; export interface UmbEntityUserPermissionSettingsModalData { unique: string; entityType: string; + allowedPermissions: Array; + headline?: string; } -export type UmbEntityUserPermissionSettingsModalValue = undefined; +export type UmbEntityUserPermissionSettingsModalValue = { + allowedPermissions: Array; +}; export const UMB_ENTITY_USER_PERMISSION_MODAL = new UmbModalToken< UmbEntityUserPermissionSettingsModalData, diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/permissions-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/permissions-modal.element.ts index 413eef0ecc..8e34d9322c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/permissions-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/permissions-modal.element.ts @@ -110,9 +110,13 @@ export class UmbPermissionsModalElement extends UmbLitElement { if (!id) throw new Error('Could not open permissions modal, no id was provided'); if (!this.data?.entityType) throw new Error('Could not open permissions modal, no entity type was provided'); + const userGroupRef = this._userGroupRefs.find((userGroup) => userGroup.id == id); + const modalContext = this.#modalManagerContext?.open(UMB_ENTITY_USER_PERMISSION_MODAL, { unique: id, entityType: this.data.entityType, + allowedPermissions: userGroupRef?.permissions || [], + headline: `Permissions for ${userGroupRef?.name}`, }); modalContext?.onSubmit().then((value) => { @@ -124,6 +128,7 @@ export class UmbPermissionsModalElement extends UmbLitElement { return html` + Permissions set for User Groups for document: ${this.data?.entityType}: ${this._userGroupRefs.map( (userGroup) => diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/modals/entity-user-permission-settings/entity-user-permission-settings-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/modals/entity-user-permission-settings/entity-user-permission-settings-modal.element.ts index 2d3f176b70..f33ef8c34c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/modals/entity-user-permission-settings/entity-user-permission-settings-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/modals/entity-user-permission-settings/entity-user-permission-settings-modal.element.ts @@ -1,4 +1,4 @@ -import { html, customElement, property, state, css, nothing } from '@umbraco-cms/backoffice/external/lit'; +import { html, customElement, property, css, nothing, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { UmbEntityUserPermissionSettingsModalData, @@ -13,14 +13,29 @@ export class UmbEntityUserPermissionSettingsModalElement extends UmbLitElement { @property({ attribute: false }) modalContext?: UmbModalContext; + #data?: UmbEntityUserPermissionSettingsModalData; + @property({ type: Object }) - data?: UmbEntityUserPermissionSettingsModalData; + get data(): UmbEntityUserPermissionSettingsModalData | undefined { + return this.#data; + } + set data(data: UmbEntityUserPermissionSettingsModalData | undefined) { + this._entityType = data?.entityType; + this._allowedPermissions = data?.allowedPermissions ?? []; + this._headline = data?.headline ?? this._headline; + } @state() - private _currentUserPermissionsForEntity: Array = []; + _headline: string = 'Set permissions'; + + @state() + _entityType?: string; + + @state() + _allowedPermissions: Array = []; private _handleConfirm() { - this.modalContext?.submit(); + this.modalContext?.submit({ allowedPermissions: this._allowedPermissions }); } private _handleCancel() { @@ -29,18 +44,17 @@ export class UmbEntityUserPermissionSettingsModalElement extends UmbLitElement { #onSelectedUserPermission(event: UmbSelectionChangeEvent) { const target = event.target as any; - const selection = target.selectedPermissions; + this._allowedPermissions = target.selectedPermissions; } render() { return html` - + - Permissions for ${this.data?.entityType} + Render name here - ${this.data?.entityType + ${this._entityType ? html` ` : nothing} From 148a8360fd475de90403574b940264a3661dba64 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 4 Oct 2023 21:14:49 +0200 Subject: [PATCH 42/44] add translation key --- src/Umbraco.Web.UI.Client/src/assets/lang/da-dk.ts | 4 +++- src/Umbraco.Web.UI.Client/src/assets/lang/en-us.ts | 4 +++- .../user-group-picker/user-group-picker-modal.element.ts | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/assets/lang/da-dk.ts b/src/Umbraco.Web.UI.Client/src/assets/lang/da-dk.ts index acd5f33aae..ec140cb744 100644 --- a/src/Umbraco.Web.UI.Client/src/assets/lang/da-dk.ts +++ b/src/Umbraco.Web.UI.Client/src/assets/lang/da-dk.ts @@ -1829,7 +1829,9 @@ export default { searchAllChildren: "Søg alle 'børn'", languagesHelp: 'Tilføj sprog for at give brugerne adgang til at redigere', sectionsHelp: 'Tilføj sektioner for at give brugerne adgang', - selectUserGroups: 'Vælg brugergrupper', + selectUserGroup: (multiple: boolean) => { + return multiple ? 'Vælg brugergrupper' : 'Vælg brugergruppe'; + }, noStartNode: 'Ingen startnode valgt', noStartNodes: 'Ingen startnoder valgt', startnode: 'Indhold startnode', diff --git a/src/Umbraco.Web.UI.Client/src/assets/lang/en-us.ts b/src/Umbraco.Web.UI.Client/src/assets/lang/en-us.ts index 37adbf86e2..d2f2882fe8 100644 --- a/src/Umbraco.Web.UI.Client/src/assets/lang/en-us.ts +++ b/src/Umbraco.Web.UI.Client/src/assets/lang/en-us.ts @@ -1830,7 +1830,9 @@ export default { languagesHelp: 'Limit the languages users have access to edit', allowAccessToAllLanguages: 'Allow access to all languages', sectionsHelp: 'Add sections to give users access', - selectUserGroups: 'Select user groups', + selectUserGroup: (multiple: boolean) => { + return multiple ? 'Select User Groups' : 'Select User Group'; + }, noStartNode: 'No start node selected', noStartNodes: 'No start nodes selected', startnode: 'Content start node', diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/modals/user-group-picker/user-group-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/modals/user-group-picker/user-group-picker-modal.element.ts index 6e74832544..cf8e9fb964 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/modals/user-group-picker/user-group-picker-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/modals/user-group-picker/user-group-picker-modal.element.ts @@ -57,7 +57,7 @@ export class UmbUserGroupPickerModalElement extends UmbModalBaseElement + ${this._userGroups.map( (item) => html` From 3219dce087e990bf2502760529e7c4cd78bec4ef Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 10 Oct 2023 20:46:50 +0200 Subject: [PATCH 43/44] manual merges --- .../documents/entity-actions/manifests.ts | 12 ----- .../entity-actions/permissions/manifests.ts | 2 +- .../permissions/permissions-modal.element.ts | 2 +- .../user-permissions/repository/manifests.ts | 2 +- .../user-group-ref/user-group-ref.element.ts | 0 ...y-user-permission-settings-list.element.ts | 4 +- .../user-permission/components/index.ts | 0 .../user/user-permission/conditions/index.ts | 1 + .../conditions/user-permission.condition.ts | 44 +++++++++++++++++++ .../{users => user}/user-permission/index.ts | 0 .../user-permission/manifests.ts | 0 ...-user-permission-settings-modal.element.ts | 2 +- .../user-permission/modals/manifests.ts | 0 13 files changed, 51 insertions(+), 18 deletions(-) rename src/Umbraco.Web.UI.Client/src/packages/{users/user-groups => user/user-group}/components/user-group-ref/user-group-ref.element.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/{users => user}/user-permission/components/entity-user-permission-settings-list/entity-user-permission-settings-list.element.ts (98%) rename src/Umbraco.Web.UI.Client/src/packages/{users => user}/user-permission/components/index.ts (100%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/user/user-permission/conditions/index.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/user/user-permission/conditions/user-permission.condition.ts rename src/Umbraco.Web.UI.Client/src/packages/{users => user}/user-permission/index.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/{users => user}/user-permission/manifests.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/{users => user}/user-permission/modals/entity-user-permission-settings/entity-user-permission-settings-modal.element.ts (99%) rename src/Umbraco.Web.UI.Client/src/packages/{users => user}/user-permission/modals/manifests.ts (100%) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/manifests.ts index 1d42e3b0f5..529db4ea71 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/manifests.ts @@ -83,18 +83,6 @@ const entityActions: Array = [ entityTypes: [DOCUMENT_ENTITY_TYPE], }, }, - { - type: 'entityAction', - alias: 'Umb.EntityAction.Document.Permissions', - name: 'Document Permissions Entity Action', - api: UmbDocumentPermissionsEntityAction, - meta: { - icon: 'umb:vcard', - label: 'Permissions (TBD)', - repositoryAlias: DOCUMENT_REPOSITORY_ALIAS, - entityTypes: [DOCUMENT_ENTITY_TYPE], - }, - }, { type: 'entityAction', alias: 'Umb.EntityAction.Document.PublicAccess', diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/manifests.ts index 8513e9a450..47f639e0a3 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/manifests.ts @@ -8,11 +8,11 @@ const entityActions: Array = [ type: 'entityAction', alias: 'Umb.EntityAction.Document.Permissions', name: 'Document Permissions Entity Action', + api: UmbDocumentPermissionsEntityAction, meta: { icon: 'umb:vcard', label: 'Permissions (TBD)', repositoryAlias: DOCUMENT_REPOSITORY_ALIAS, - api: UmbDocumentPermissionsEntityAction, entityTypes: [DOCUMENT_ENTITY_TYPE], }, }, diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/permissions-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/permissions-modal.element.ts index 8e34d9322c..52723230e7 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/permissions-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/permissions/permissions-modal.element.ts @@ -13,7 +13,7 @@ import { UmbModalManagerContext, } from '@umbraco-cms/backoffice/modal'; import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; -import { UmbSelectedEvent } from '@umbraco-cms/backoffice/events'; +import { UmbSelectedEvent } from '@umbraco-cms/backoffice/event'; type UmbUserGroupRefData = { id: string; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/user-permissions/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/user-permissions/repository/manifests.ts index 7f00473726..d20227b8c3 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/user-permissions/repository/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/user-permissions/repository/manifests.ts @@ -7,7 +7,7 @@ const repository: ManifestRepository = { type: 'repository', alias: UMB_DOCUMENT_PERMISSION_REPOSITORY_ALIAS, name: 'Document Permission Repository', - class: UmbDocumentPermissionRepository, + api: UmbDocumentPermissionRepository, }; export const manifests = [repository]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/components/user-group-ref/user-group-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user-group/components/user-group-ref/user-group-ref.element.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/users/user-groups/components/user-group-ref/user-group-ref.element.ts rename to src/Umbraco.Web.UI.Client/src/packages/user/user-group/components/user-group-ref/user-group-ref.element.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/components/entity-user-permission-settings-list/entity-user-permission-settings-list.element.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/components/entity-user-permission-settings-list/entity-user-permission-settings-list.element.ts similarity index 98% rename from src/Umbraco.Web.UI.Client/src/packages/users/user-permission/components/entity-user-permission-settings-list/entity-user-permission-settings-list.element.ts rename to src/Umbraco.Web.UI.Client/src/packages/user/user-permission/components/entity-user-permission-settings-list/entity-user-permission-settings-list.element.ts index a1e3175094..2203b1f362 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/components/entity-user-permission-settings-list/entity-user-permission-settings-list.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/components/entity-user-permission-settings-list/entity-user-permission-settings-list.element.ts @@ -1,4 +1,4 @@ -import { UmbChangeEvent, UmbSelectionChangeEvent } from '@umbraco-cms/backoffice/events'; +import { UmbChangeEvent, UmbSelectionChangeEvent } from '@umbraco-cms/backoffice/event'; import { ManifestEntityAction, ManifestUserPermission, @@ -7,7 +7,7 @@ import { import { css, html, customElement, property, state, nothing, ifDefined } from '@umbraco-cms/backoffice/external/lit'; import { groupBy } from '@umbraco-cms/backoffice/external/lodash'; import { UmbObserverController } from '@umbraco-cms/backoffice/observable-api'; -import { UmbUserPermissionSettingElement } from '@umbraco-cms/backoffice/users'; +import { UmbUserPermissionSettingElement } from '@umbraco-cms/backoffice/user'; import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-entity-user-permission-settings-list') diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/components/index.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/components/index.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/users/user-permission/components/index.ts rename to src/Umbraco.Web.UI.Client/src/packages/user/user-permission/components/index.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/conditions/index.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/conditions/index.ts new file mode 100644 index 0000000000..64b786466c --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/conditions/index.ts @@ -0,0 +1 @@ +export * from './user-permission.condition.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/conditions/user-permission.condition.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/conditions/user-permission.condition.ts new file mode 100644 index 0000000000..90a5d1c8b4 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/conditions/user-permission.condition.ts @@ -0,0 +1,44 @@ +import { UMB_AUTH } from '@umbraco-cms/backoffice/auth'; +import { UmbBaseController } from '@umbraco-cms/backoffice/controller-api'; +import { + ManifestCondition, + UmbConditionConfigBase, + UmbConditionControllerArguments, + UmbExtensionCondition, +} from '@umbraco-cms/backoffice/extension-api'; + +export class UmbUserPermissionCondition extends UmbBaseController implements UmbExtensionCondition { + config: UserPermissionConditionConfig; + permitted = false; + #onChange: () => void; + + constructor(args: UmbConditionControllerArguments) { + super(args.host); + this.config = args.config; + this.#onChange = args.onChange; + + this.consumeContext(UMB_AUTH, (context) => { + this.observe(context.currentUser, (currentUser) => { + this.permitted = currentUser?.permissions?.includes(this.config.match) || false; + this.#onChange(); + }); + }); + } +} + +export type UserPermissionConditionConfig = UmbConditionConfigBase<'Umb.Condition.UserPermission'> & { + /** + * + * + * @example + * "Umb.UserPermission.Document.Create" + */ + match: string; +}; + +export const manifest: ManifestCondition = { + type: 'condition', + name: 'User Permission Condition', + alias: 'Umb.Condition.UserPermission', + api: UmbUserPermissionCondition, +}; diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/index.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/index.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/users/user-permission/index.ts rename to src/Umbraco.Web.UI.Client/src/packages/user/user-permission/index.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/manifests.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/users/user-permission/manifests.ts rename to src/Umbraco.Web.UI.Client/src/packages/user/user-permission/manifests.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/modals/entity-user-permission-settings/entity-user-permission-settings-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/modals/entity-user-permission-settings/entity-user-permission-settings-modal.element.ts similarity index 99% rename from src/Umbraco.Web.UI.Client/src/packages/users/user-permission/modals/entity-user-permission-settings/entity-user-permission-settings-modal.element.ts rename to src/Umbraco.Web.UI.Client/src/packages/user/user-permission/modals/entity-user-permission-settings/entity-user-permission-settings-modal.element.ts index f33ef8c34c..c61c8c3f55 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/modals/entity-user-permission-settings/entity-user-permission-settings-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/modals/entity-user-permission-settings/entity-user-permission-settings-modal.element.ts @@ -6,7 +6,7 @@ import { UmbModalContext, } from '@umbraco-cms/backoffice/modal'; import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; -import { UmbSelectionChangeEvent } from '@umbraco-cms/backoffice/events'; +import { UmbSelectionChangeEvent } from '@umbraco-cms/backoffice/event'; @customElement('umb-entity-user-permission-settings-modal') export class UmbEntityUserPermissionSettingsModalElement extends UmbLitElement { diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-permission/modals/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user-permission/modals/manifests.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/users/user-permission/modals/manifests.ts rename to src/Umbraco.Web.UI.Client/src/packages/user/user-permission/modals/manifests.ts From 3d3c19b0f8816d221ff66d942c54f2298ae67963 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 11 Oct 2023 10:28:31 +0200 Subject: [PATCH 44/44] fix compile errors --- .../src/mocks/data/document-type.data.ts | 5 ----- .../src/mocks/data/document.data.ts | 10 ++++------ .../src/mocks/data/entity.data.ts | 5 ++++- .../src/mocks/data/user-group.data.ts | 13 +------------ .../src/mocks/data/user.data.ts | 8 -------- 5 files changed, 9 insertions(+), 32 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/document-type.data.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/document-type.data.ts index f510fa8468..ef912e8795 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/document-type.data.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/document-type.data.ts @@ -1107,11 +1107,6 @@ class UmbDocumentTypeData extends UmbEntityData { const items = this.treeData.filter((item) => allowedTypeKeys.includes(item.id ?? '')); return items.map((item) => item); } - - /** For internal use */ - getAll() { - return this.data; - } } export const umbDocumentTypeData = new UmbDocumentTypeData(); diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/document.data.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/document.data.ts index 5af8384cb4..5c4edfb0d2 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/document.data.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/document.data.ts @@ -656,10 +656,7 @@ class UmbDocumentData extends UmbEntityData { } getAllowedDocumentTypesAtRoot(): PagedDocumentTypeResponseModel { - const items = umbDocumentTypeData.getAll(); //.filter((docType) => docType.allowedAsRoot); - - const total = items?.length; - return { items, total }; + return umbDocumentTypeData.getAll(); //.filter((docType) => docType.allowedAsRoot); } getRecycleBinRoot(): PagedRecycleBinItemResponseModel { @@ -681,8 +678,9 @@ class UmbDocumentData extends UmbEntityData { getUserPermissionsForDocument(id: string): Array { return umbUserPermissionData .getAll() - .filter( - (permission) => permission.target.entityType === DOCUMENT_ENTITY_TYPE && permission.target.documentId === id, + .items.filter( + (permission: any) => + permission.target.entityType === DOCUMENT_ENTITY_TYPE && permission.target.documentId === id, ); } } diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/entity.data.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/entity.data.ts index 9da17cc4f2..cc63fa64dd 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/entity.data.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/entity.data.ts @@ -9,7 +9,10 @@ export class UmbEntityData extends UmbData { } getAll() { - return this.data; + return { + total: this.data.length, + items: this.data, + }; } getList(skip: number, take: number) { diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/user-group.data.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/user-group.data.ts index 4fea6c2999..1fd17caccf 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/user-group.data.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/user-group.data.ts @@ -4,11 +4,7 @@ import { UMB_USER_PERMISSION_DOCUMENT_DELETE, UMB_USER_PERMISSION_DOCUMENT_READ, } from '@umbraco-cms/backoffice/document'; -import { - PagedUserGroupResponseModel, - UserGroupItemResponseModel, - UserGroupResponseModel, -} from '@umbraco-cms/backoffice/backend-api'; +import { UserGroupItemResponseModel, UserGroupResponseModel } from '@umbraco-cms/backoffice/backend-api'; const createUserGroupItem = (item: UserGroupResponseModel): UserGroupItemResponseModel => { return { @@ -24,13 +20,6 @@ class UmbUserGroupData extends UmbEntityData { super(data); } - getAll(): PagedUserGroupResponseModel { - return { - total: this.data.length, - items: this.data, - }; - } - getItems(ids: Array): Array { const items = this.data.filter((item) => ids.includes(item.id ?? '')); return items.map((item) => createUserGroupItem(item)); diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/user.data.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/user.data.ts index 18dbc0ce37..77d0c6b639 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/user.data.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/user.data.ts @@ -2,7 +2,6 @@ import { UmbEntityData } from './entity.data.js'; import { umbUserGroupData } from './user-group.data.js'; import { UmbLoggedInUser } from '@umbraco-cms/backoffice/auth'; import { - PagedUserResponseModel, UpdateUserGroupsOnUserRequestModel, UserItemResponseModel, UserResponseModel, @@ -22,13 +21,6 @@ class UmbUserData extends UmbEntityData { super(data); } - getAll(): PagedUserResponseModel { - return { - total: this.data.length, - items: this.data, - }; - } - getItems(ids: Array): Array { const items = this.data.filter((item) => ids.includes(item.id ?? '')); return items.map((item) => createUserItem(item));