From 08c6b482a31cb77cd398fa70895dac9ec31187df Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 17 Nov 2022 20:17:48 +0100 Subject: [PATCH] add member type tree + editor scaffold --- .../src/backoffice/backoffice.element.ts | 2 + .../src/backoffice/editors/manifests.ts | 9 +++++ .../member-type/editor-member-type.element.ts | 36 ++++++++++++++++++ .../src/backoffice/trees/manifests.ts | 28 ++++++++++---- .../member-types/tree-member-types.element.ts | 30 +++++++++++++++ .../src/core/mocks/browser-handlers.ts | 2 + .../src/core/mocks/data/member-type.data.ts | 23 ++++++----- .../domains/tree-member-type.handlers.ts | 19 ++++++++++ .../src/core/models/index.ts | 1 + .../stores/member-type/member-type.store.ts | 38 +++++++++++++++++++ 10 files changed, 171 insertions(+), 17 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/backoffice/editors/member-type/editor-member-type.element.ts create mode 100644 src/Umbraco.Web.UI.Client/src/backoffice/trees/member-types/tree-member-types.element.ts create mode 100644 src/Umbraco.Web.UI.Client/src/core/mocks/domains/tree-member-type.handlers.ts create mode 100644 src/Umbraco.Web.UI.Client/src/core/stores/member-type/member-type.store.ts diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/backoffice.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/backoffice.element.ts index 8650fc8b6a..b322f6b2d7 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/backoffice.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/backoffice.element.ts @@ -19,6 +19,7 @@ import { UmbModalService } from '../core/services/modal'; import { UmbNotificationService } from '../core/services/notification'; import { UmbDataTypeStore } from '../core/stores/data-type/data-type.store'; import { UmbDocumentTypeStore } from '../core/stores/document-type/document-type.store'; +import { UmbMemberTypeStore } from '../core/stores/member-type/member-type.store'; import { UmbDocumentStore } from '../core/stores/document/document.store'; import { UmbMediaStore } from '../core/stores/media/media.store'; import { UmbNodeStore } from '../core/stores/node.store'; @@ -76,6 +77,7 @@ export class UmbBackofficeElement extends UmbContextConsumerMixin(UmbContextProv this.provideContext('umbNodeStore', new UmbNodeStore(this._umbEntityStore)); this.provideContext('umbDataTypeStore', new UmbDataTypeStore(this._umbEntityStore)); this.provideContext('umbDocumentTypeStore', new UmbDocumentTypeStore(this._umbEntityStore)); + this.provideContext('umbMemberTypeStore', new UmbMemberTypeStore(this._umbEntityStore)); this.provideContext('umbUserStore', new UmbUserStore(this._umbEntityStore)); this.provideContext('umbUserGroupStore', new UmbUserGroupStore(this._umbEntityStore)); this.provideContext('umbMemberGroupStore', new UmbMemberGroupStore(this._umbEntityStore)); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/editors/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/editors/manifests.ts index 46b9711134..8e4864ca3a 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/editors/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/editors/manifests.ts @@ -37,6 +37,15 @@ export const manifests: Array> = [ entityType: 'document-type', }, }, + { + type: 'editor', + alias: 'Umb.Editor.MemberType', + name: 'Member Type Editor', + loader: () => import('./member-type/editor-member-type.element'), + meta: { + entityType: 'member-type', + }, + }, { type: 'editor', alias: 'Umb.Editor.Extensions', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/editors/member-type/editor-member-type.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/editors/member-type/editor-member-type.element.ts new file mode 100644 index 0000000000..95dc175aed --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/editors/member-type/editor-member-type.element.ts @@ -0,0 +1,36 @@ +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { css, html, LitElement } from 'lit'; +import { customElement, property } from 'lit/decorators.js'; + +import '../shared/editor-entity-layout/editor-entity-layout.element'; + +@customElement('umb-editor-member-type') +export class UmbEditorMemberTypeElement extends LitElement { + static styles = [ + UUITextStyles, + css` + :host { + display: block; + width: 100%; + height: 100%; + } + `, + ]; + + @property() + id!: string; + + render() { + return html` + Member Type Editor + `; + } +} + +export default UmbEditorMemberTypeElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-editor-member-type': UmbEditorMemberTypeElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/trees/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/trees/manifests.ts index 1cc64efd9c..1c9085765c 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/trees/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/trees/manifests.ts @@ -15,24 +15,36 @@ export const manifests: Array> = [ }, { type: 'tree', - alias: 'Umb.Tree.DataTypes', - name: 'Data Types Tree', - loader: () => import('./data-types/tree-data-types.element'), + alias: 'Umb.Tree.DocumentTypes', + name: 'Document Types Tree', + loader: () => import('./document-types/tree-document-types.element'), weight: 300, meta: { - label: 'Data Types', + label: 'Document Types', icon: 'umb:folder', sections: ['Umb.Section.Settings'], }, }, { type: 'tree', - alias: 'Umb.Tree.DocumentTypes', - name: 'Document Types Tree', - loader: () => import('./document-types/tree-document-types.element'), + alias: 'Umb.Tree.MemberTypes', + name: 'Member Types Tree', + loader: () => import('./member-types/tree-member-types.element'), weight: 200, meta: { - label: 'Document Types', + label: 'Member Types', + icon: 'umb:folder', + sections: ['Umb.Section.Settings'], + }, + }, + { + type: 'tree', + alias: 'Umb.Tree.DataTypes', + name: 'Data Types Tree', + loader: () => import('./data-types/tree-data-types.element'), + weight: 100, + meta: { + label: 'Data Types', icon: 'umb:folder', sections: ['Umb.Section.Settings'], }, diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/trees/member-types/tree-member-types.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/trees/member-types/tree-member-types.element.ts new file mode 100644 index 0000000000..f36ca1eb4b --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/trees/member-types/tree-member-types.element.ts @@ -0,0 +1,30 @@ +import { html } from 'lit'; +import { customElement } from 'lit/decorators.js'; +import { UmbTreeBase } from '../shared/tree-base.element'; +import { UmbContextConsumerMixin, UmbContextProviderMixin } from '@umbraco-cms/context-api'; +import { UmbMemberTypeStore } from 'src/core/stores/member-type/member-type.store'; + +import '../shared/tree-navigator.element'; + +@customElement('umb-tree-member-types') +export class UmbTreeMemberTypes extends UmbContextConsumerMixin(UmbContextProviderMixin(UmbTreeBase)) { + constructor() { + super(); + + this.consumeContext('umbMemberTypeStore', (store: UmbMemberTypeStore) => { + this.provideContext('umbTreeStore', store); + }); + } + + render() { + return html``; + } +} + +export default UmbTreeMemberTypes; + +declare global { + interface HTMLElementTagNameMap { + 'umb-tree-member-types': UmbTreeMemberTypes; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/browser-handlers.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/browser-handlers.ts index 40864bf2c1..b7807c86d8 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/browser-handlers.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/browser-handlers.ts @@ -17,6 +17,7 @@ import { handlers as treeDocumentHandlers } from './domains/tree-document.handle import { handlers as treeMediaHandlers } from './domains/tree-media.handlers'; import { handlers as treeDataTypeHandlers } from './domains/tree-data-type.handlers'; import { handlers as treeDocumentTypeHandlers } from './domains/tree-document-type.handlers'; +import { handlers as treeMemberTypeHandlers } from './domains/tree-member-type.handlers'; import { handlers as treeMemberGroupHandlers } from './domains/tree-member-group.handlers'; const handlers = [ @@ -38,6 +39,7 @@ const handlers = [ ...treeMediaHandlers, ...treeDataTypeHandlers, ...treeDocumentTypeHandlers, + ...treeMemberTypeHandlers, ...treeMemberGroupHandlers, ]; diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/data/member-type.data.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/data/member-type.data.ts index 1c010558d3..2b8f4bbd9c 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/data/member-type.data.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/data/member-type.data.ts @@ -1,16 +1,17 @@ import { UmbData } from './data'; -import { EntityTreeItem } from '@umbraco-cms/backend-api'; +import { EntityTreeItem, PagedEntityTreeItem } from '@umbraco-cms/backend-api'; import type { MemberTypeDetails } from '@umbraco-cms/models'; export const data: Array = [ { - key: 'd59be02f-1df9-4228-aa1e-01917d806cda', - isContainer: false, - parentKey: null, - name: 'Member', + name: 'Member Type 1', type: 'member-type', icon: 'icon-user', hasChildren: false, + key: 'd59be02f-1df9-4228-aa1e-01917d806cda', + isContainer: false, + parentKey: null, + isTrashed: false, alias: 'memberType1', properties: [], }, @@ -22,12 +23,16 @@ class UmbMemberTypeData extends UmbData { super(data); } - getTreeRoot(): Array { - return this.data.filter((item) => item.parentKey === null); + getTreeRoot(): PagedEntityTreeItem { + const items = this.data.filter((item) => item.parentKey === null); + const total = items.length; + return { items, total }; } - getTreeItemChildren(key: string): Array { - return this.data.filter((item) => item.parentKey === key); + getTreeItemChildren(key: string): PagedEntityTreeItem { + const items = this.data.filter((item) => item.parentKey === key); + const total = items.length; + return { items, total }; } getTreeItem(keys: Array): Array { diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/tree-member-type.handlers.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/tree-member-type.handlers.ts new file mode 100644 index 0000000000..21acb5d242 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/tree-member-type.handlers.ts @@ -0,0 +1,19 @@ +import { rest } from 'msw'; +import { umbMemberTypeData } from '../data/member-type.data'; + +// TODO: add schema +export const handlers = [ + rest.get('/umbraco/management/api/v1/tree/member-type/root', (req, res, ctx) => { + const response = umbMemberTypeData.getTreeRoot(); + return res(ctx.status(200), ctx.json(response)); + }), + + rest.get('/umbraco/management/api/v1/tree/member-type/item', (req, res, ctx) => { + const keys = req.params.keys as string; + if (!keys) return; + + const items = umbMemberTypeData.getTreeItem(keys.split(',')); + + return res(ctx.status(200), ctx.json(items)); + }), +]; diff --git a/src/Umbraco.Web.UI.Client/src/core/models/index.ts b/src/Umbraco.Web.UI.Client/src/core/models/index.ts index 3436b2df0f..66e01b1e7f 100644 --- a/src/Umbraco.Web.UI.Client/src/core/models/index.ts +++ b/src/Umbraco.Web.UI.Client/src/core/models/index.ts @@ -78,6 +78,7 @@ export interface DocumentTypeDetails extends DocumentTypeTreeItem { export interface MemberTypeDetails extends EntityTreeItem { key: string; // TODO: Remove this when the backend is fixed + isTrashed: boolean; // TODO: remove only temp part of refactor alias: string; properties: []; } diff --git a/src/Umbraco.Web.UI.Client/src/core/stores/member-type/member-type.store.ts b/src/Umbraco.Web.UI.Client/src/core/stores/member-type/member-type.store.ts new file mode 100644 index 0000000000..cf83a12119 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/core/stores/member-type/member-type.store.ts @@ -0,0 +1,38 @@ +import { map, Observable } from 'rxjs'; +import { UmbEntityStore } from '../entity.store'; +import { UmbDataStoreBase } from '../store'; +import { MemberTypeResource, ApiError, EntityTreeItem, ProblemDetails } from '@umbraco-cms/backend-api'; +import type { MemberTypeDetails } from '@umbraco-cms/models'; + +/** + * @export + * @class UmbMemberTypeStore + * @extends {UmbDataStoreBase} + * @description - Data Store for Member Types + */ +export class UmbMemberTypeStore extends UmbDataStoreBase { + private _entityStore: UmbEntityStore; + + constructor(entityStore: UmbEntityStore) { + super(); + this._entityStore = entityStore; + } + + getTreeRoot(): Observable> { + MemberTypeResource.getTreeMemberTypeRoot({}).then( + (res) => { + this.update(res.items); + }, + (e) => { + if (e instanceof ApiError) { + const error = e.body as ProblemDetails; + if (e.status === 400) { + console.log(error.detail); + } + } + } + ); + + return this.items.pipe(map((items) => items.filter((item) => item.parentKey === null))); + } +}