From 18bcbe0e9b4068340ed867ea16be83a1073beaa5 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Sat, 14 Sep 2024 21:22:58 +0200 Subject: [PATCH] add create member entity action --- .../entity-actions/create/create.action.ts | 19 ++++ .../member/entity-actions/create/manifests.ts | 29 +++++ .../member-create-options-modal.element.ts | 105 ++++++++++++++++++ .../member-create-options-modal.token.ts | 17 +++ .../member/entity-actions/manifests.ts | 7 +- .../src/packages/members/member/paths.ts | 5 + 6 files changed, 178 insertions(+), 4 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/members/member/entity-actions/create/create.action.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/members/member/entity-actions/create/manifests.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/members/member/entity-actions/create/member-create-options-modal.element.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/members/member/entity-actions/create/member-create-options-modal.token.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/entity-actions/create/create.action.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/entity-actions/create/create.action.ts new file mode 100644 index 0000000000..20994dad83 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/entity-actions/create/create.action.ts @@ -0,0 +1,19 @@ +import { UMB_MEMBER_CREATE_OPTIONS_MODAL } from './member-create-options-modal.token.js'; +import type { UmbEntityActionArgs } from '@umbraco-cms/backoffice/entity-action'; +import { UmbEntityActionBase } from '@umbraco-cms/backoffice/entity-action'; +import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal'; + +export class UmbCreateMemberEntityAction extends UmbEntityActionBase { + constructor(host: UmbControllerHost, args: UmbEntityActionArgs) { + super(host, args); + } + + override async execute() { + const modalManager = await this.getContext(UMB_MODAL_MANAGER_CONTEXT); + const modalContext = modalManager.open(this, UMB_MEMBER_CREATE_OPTIONS_MODAL); + await modalContext.onSubmit(); + } +} + +export { UmbCreateMemberEntityAction as api }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/entity-actions/create/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/entity-actions/create/manifests.ts new file mode 100644 index 0000000000..2bb593b71a --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/entity-actions/create/manifests.ts @@ -0,0 +1,29 @@ +import { UMB_MEMBER_ROOT_ENTITY_TYPE } from '../../entity.js'; +import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry'; + +const entityActions: Array = [ + { + type: 'entityAction', + kind: 'default', + alias: 'Umb.EntityAction.Member.Create', + name: 'Create Member Entity Action', + weight: 1200, + api: () => import('./create.action.js'), + forEntityTypes: [UMB_MEMBER_ROOT_ENTITY_TYPE], + meta: { + icon: 'icon-add', + label: '#actions_create', + }, + }, +]; + +const modals: Array = [ + { + type: 'modal', + alias: 'Umb.Modal.Member.CreateOptions', + name: 'Member Create Options Modal', + js: () => import('./member-create-options-modal.element.js'), + }, +]; + +export const manifests: Array = [...entityActions, ...modals]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/entity-actions/create/member-create-options-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/entity-actions/create/member-create-options-modal.element.ts new file mode 100644 index 0000000000..0ef81df8c2 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/entity-actions/create/member-create-options-modal.element.ts @@ -0,0 +1,105 @@ +import type { + UmbMemberCreateOptionsModalData, + UmbMemberCreateOptionsModalValue, +} from './member-create-options-modal.token.js'; +import { html, customElement, state, repeat, css } from '@umbraco-cms/backoffice/external/lit'; +import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; +import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal'; + +import { UmbMemberTypeTreeRepository } from '@umbraco-cms/backoffice/member-type'; +import { UMB_CREATE_MEMBER_WORKSPACE_PATH_PATTERN, UMB_MEMBER_WORKSPACE_PATH } from '../../paths.js'; + +const elementName = 'umb-member-create-options-modal'; +@customElement(elementName) +export class UmbMemberCreateOptionsModalElement extends UmbModalBaseElement< + UmbMemberCreateOptionsModalData, + UmbMemberCreateOptionsModalValue +> { + @state() + private _options: Array<{ label: string; unique: string; icon: string }> = []; + + #memberTypeTreeRepository = new UmbMemberTypeTreeRepository(this); + + override firstUpdated() { + this.#getOptions(); + } + + async #getOptions() { + //TODO: Should we use the tree repository or make a collection repository? + //TODO: And how would we get all the member types? + //TODO: This only works because member types can't have folders. + const { data } = await this.#memberTypeTreeRepository.requestTreeRootItems({}); + if (!data) return; + + this._options = data.items.map((item) => { + return { + label: item.name, + unique: item.unique, + icon: item.icon || '', + }; + }); + } + + // close the modal when navigating + #onOpen(event: Event, unique: string) { + event?.stopPropagation(); + // TODO: the href does not emit an event, so we need to use the click event + const path = UMB_CREATE_MEMBER_WORKSPACE_PATH_PATTERN.generateAbsolute({ + memberTypeUnique: unique, + }); + history.pushState(null, '', path); + this._submitModal(); + } + + override render() { + return html` + + ${this.#renderOptions()} + + + `; + } + + #renderOptions() { + return html` + + ${repeat( + this._options, + (option) => option.unique, + (option) => html` + this.#onOpen(event, option.unique)}> + + + `, + )} + + `; + } + + static override styles = [ + UmbTextStyles, + css` + #blank { + border-bottom: 1px solid var(--uui-color-border); + } + + #edit-permissions { + margin-top: var(--uui-size-6); + } + `, + ]; +} + +export { UmbMemberCreateOptionsModalElement as element }; + +declare global { + interface HTMLElementTagNameMap { + [elementName]: UmbMemberCreateOptionsModalElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/entity-actions/create/member-create-options-modal.token.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/entity-actions/create/member-create-options-modal.token.ts new file mode 100644 index 0000000000..18a240fcd3 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/entity-actions/create/member-create-options-modal.token.ts @@ -0,0 +1,17 @@ +import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; + +// eslint-disable-next-line @typescript-eslint/no-empty-object-type +export interface UmbMemberCreateOptionsModalData {} + +// eslint-disable-next-line @typescript-eslint/no-empty-object-type +export interface UmbMemberCreateOptionsModalValue {} + +export const UMB_MEMBER_CREATE_OPTIONS_MODAL = new UmbModalToken< + UmbMemberCreateOptionsModalData, + UmbMemberCreateOptionsModalValue +>('Umb.Modal.Member.CreateOptions', { + modal: { + type: 'sidebar', + size: 'small', + }, +}); diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/entity-actions/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/entity-actions/manifests.ts index 5bd8c3ee26..e03f597bd5 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/entity-actions/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/entity-actions/manifests.ts @@ -1,8 +1,8 @@ import { UMB_MEMBER_DETAIL_REPOSITORY_ALIAS, UMB_MEMBER_ITEM_REPOSITORY_ALIAS } from '../repository/index.js'; import { UMB_MEMBER_ENTITY_TYPE } from '../entity.js'; -import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry'; +import { manifests as createManifests } from './create/manifests.js'; -const entityActions: Array = [ +export const manifests: Array = [ { type: 'entityAction', kind: 'delete', @@ -14,6 +14,5 @@ const entityActions: Array = [ itemRepositoryAlias: UMB_MEMBER_ITEM_REPOSITORY_ALIAS, }, }, + ...createManifests, ]; - -export const manifests: Array = [...entityActions]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/paths.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/paths.ts index 0686227fe9..f535e8961f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/paths.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/paths.ts @@ -1,3 +1,4 @@ +import { UmbPathPattern } from '@umbraco-cms/backoffice/router'; import { UMB_MEMBER_MANAGEMENT_SECTION_PATHNAME } from '../section/paths.js'; import { UMB_MEMBER_ENTITY_TYPE, UMB_MEMBER_ROOT_ENTITY_TYPE } from './entity.js'; import { UMB_WORKSPACE_PATH_PATTERN } from '@umbraco-cms/backoffice/workspace'; @@ -11,3 +12,7 @@ export const UMB_MEMBER_ROOT_WORKSPACE_PATH = UMB_WORKSPACE_PATH_PATTERN.generat sectionName: UMB_MEMBER_MANAGEMENT_SECTION_PATHNAME, entityType: UMB_MEMBER_ROOT_ENTITY_TYPE, }); + +export const UMB_CREATE_MEMBER_WORKSPACE_PATH_PATTERN = new UmbPathPattern<{ + memberTypeUnique: string; +}>('create/:memberTypeUnique', UMB_MEMBER_WORKSPACE_PATH);