From 962fe374d028cd1403115f15d441f1c86d4bcc2f Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 30 May 2022 13:00:56 +0200 Subject: [PATCH] add content service --- .../src/content/content-editor.element.ts | 118 +++++---------- .../src/content/content-section.element.ts | 10 +- .../src/content/content-tree.element.ts | 17 +-- .../src/content/content.service.ts | 138 ++++++++++++++++++ 4 files changed, 189 insertions(+), 94 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/content/content.service.ts diff --git a/src/Umbraco.Web.UI.Client/src/content/content-editor.element.ts b/src/Umbraco.Web.UI.Client/src/content/content-editor.element.ts index 5191d065f4..9e529e051c 100644 --- a/src/Umbraco.Web.UI.Client/src/content/content-editor.element.ts +++ b/src/Umbraco.Web.UI.Client/src/content/content-editor.element.ts @@ -1,9 +1,12 @@ import { css, html, LitElement } from 'lit'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import { customElement, property } from 'lit/decorators.js'; +import { customElement, property, state } from 'lit/decorators.js'; +import { UmbContextConsumerMixin } from '../core/context'; +import { DocumentNode, UmbContentService } from './content.service'; +import { Subscription } from 'rxjs'; @customElement('umb-content-editor') -class UmbContentEditor extends LitElement { +class UmbContentEditor extends UmbContextConsumerMixin(LitElement) { static styles = [ UUITextStyles, css` @@ -41,12 +44,25 @@ class UmbContentEditor extends LitElement { `, ]; + @state() + _node?: DocumentNode; + @property() id!: string; + private _contentService?: UmbContentService; + private _nodeSubscription?: Subscription; + + constructor () { + super(); + + this.consumeContext('umbContentService', (contentService: UmbContentService) => { + this._contentService = contentService; + this._useNode(); + }); + } private _onPropertyDataTypeChange(e: CustomEvent) { - const target = (e.target as any) console.log(target.value) @@ -54,6 +70,15 @@ class UmbContentEditor extends LitElement { //this.nodeData.properties.find(x => x.propertyAlias === target.propertyAlias)?.tempValue = target.value; } + private _useNode() { + this._nodeSubscription?.unsubscribe(); + + this._nodeSubscription = this._contentService?.getById(this.id).subscribe(node => { + if (!node) return; + this._node = node; + }); + } + private _onSaveAndPublish() { console.log('Save and publish'); } @@ -66,89 +91,24 @@ class UmbContentEditor extends LitElement { console.log('Save and preview'); } - /* - // Properties mock data: - private properties = [ - { - propertyAlias: 'myHeadline', - label: 'Text string label', - description: 'This is the a text string property', - dataTypeAlias: 'myTextStringEditor' - }, - { - propertyAlias: 'myDescription', - label: 'Textarea label', - description: 'this is a textarea property', - dataTypeAlias: 'myTextAreaEditor' - } - ]; - */ - - private nodeData = { - name: 'my node 1', - key: '1234-1234-1234', - alias: 'myNode1', - documentTypeAlias: 'myDocumentType', - documentTypeKey: '1234-1234-1234', - /* example of layout: - layout: [ - { - type: 'group', - children: [ - { - type: 'property', - alias: 'myHeadline' - }, - { - type: 'property', - alias: 'myDescription' - } - ] - } - ], - */ - properties: [ - { - alias: 'myHeadline', - label: 'Textarea label', - description: 'this is a textarea property', - dataTypeAlias: 'myTextStringEditor', - tempValue: 'hello world' - }, - { - alias: 'myDescription', - label: 'Text string label', - description: 'This is the a text string property', - dataTypeAlias: 'myTextAreaEditor', - tempValue: 'Tex areaaaa' - }, - ], - data: [ - { - alias: 'myHeadline', - value: 'hello world', - }, - { - alias: 'myDescription', - value: 'Teeeeexxxt areaaaaaa', - }, - ] + disconnectedCallback(): void { + super.disconnectedCallback(); + this._nodeSubscription?.unsubscribe(); } render() { return html` - + - Content - Info - Actions + + + -

RENDER NODE WITH ID: ${this.id}

- ${this.nodeData.properties.map( + ${this._node?.properties.map( property => html`
- Save and preview - Save - Save and publish + + +
`; diff --git a/src/Umbraco.Web.UI.Client/src/content/content-section.element.ts b/src/Umbraco.Web.UI.Client/src/content/content-section.element.ts index f4042fa9f3..f4e23e93c3 100644 --- a/src/Umbraco.Web.UI.Client/src/content/content-section.element.ts +++ b/src/Umbraco.Web.UI.Client/src/content/content-section.element.ts @@ -1,14 +1,16 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import { css, html, LitElement, PropertyValueMap } from 'lit'; +import { css, html, LitElement } from 'lit'; import { customElement } from 'lit/decorators.js'; -import { UmbContextConsumerMixin } from '../core/context'; +import { UmbContextConsumerMixin, UmbContextProviderMixin } from '../core/context'; import { UmbRouteLocation, UmbRouter } from '../core/router'; +import { UmbContentService } from './content.service'; import './content-tree.element'; import './content-dashboards.element'; import './content-editor.element'; + @customElement('umb-content-section') -export class UmbContentSection extends UmbContextConsumerMixin(LitElement) { +export class UmbContentSection extends UmbContextProviderMixin(UmbContextConsumerMixin(LitElement)) { static styles = [ UUITextStyles, css` @@ -26,6 +28,8 @@ export class UmbContentSection extends UmbContextConsumerMixin(LitElement) { constructor () { super(); + this.provideContext('umbContentService', new UmbContentService()); + this.consumeContext('umbRouter', (_instance: UmbRouter) => { this._router = _instance; this._useLocation(); diff --git a/src/Umbraco.Web.UI.Client/src/content/content-tree.element.ts b/src/Umbraco.Web.UI.Client/src/content/content-tree.element.ts index 30b4be0ffb..8f917f4ebc 100644 --- a/src/Umbraco.Web.UI.Client/src/content/content-tree.element.ts +++ b/src/Umbraco.Web.UI.Client/src/content/content-tree.element.ts @@ -5,6 +5,7 @@ import { UmbContextConsumerMixin } from '../core/context'; import { UmbRouteLocation, UmbRouter } from '../core/router'; import { Subscription } from 'rxjs'; import { UUIMenuItemElement } from '@umbraco-ui/uui'; +import { data } from './content.service'; @customElement('umb-content-tree') class UmbContentTree extends UmbContextConsumerMixin(LitElement) { @@ -20,18 +21,7 @@ class UmbContentTree extends UmbContextConsumerMixin(LitElement) { // simplified tree for testing @state() - _tree: Array = [ - { - id: '1', - name: 'Hello World', - icon: 'document', - }, - { - id: '2', - name: 'Hello World 2', - icon: 'document', - } - ]; + _tree: Array = []; @state() _section?: string; @@ -46,6 +36,9 @@ class UmbContentTree extends UmbContextConsumerMixin(LitElement) { constructor () { super(); + // TODO: implement correct tree data + this._tree = data; + this.consumeContext('umbRouter', (router: UmbRouter) => { this._router = router; this._useLocation(); diff --git a/src/Umbraco.Web.UI.Client/src/content/content.service.ts b/src/Umbraco.Web.UI.Client/src/content/content.service.ts new file mode 100644 index 0000000000..d456307c59 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/content/content.service.ts @@ -0,0 +1,138 @@ +import { BehaviorSubject, map, Observable } from 'rxjs'; + +export interface DocumentNode { + id: string; + key: string; + name: string; + alias: string; + icon: string; // TODO: should come from the doc type? + properties: NodeProperty[]; + data: any; // TODO: define data type + layout?: any; // TODO: define layout type - make it non-optional +} + +export interface NodeProperty { + alias: string; + label: string; + description: string; + dataTypeAlias: string; + tempValue: string; // TODO: remove this - only used for testing +} + +export const data: Array = [ + { + id: '1', + key: '74e4008a-ea4f-4793-b924-15e02fd380d3', + name: 'Document 1', + alias: 'document1', + icon: 'document', + properties: [ + { + alias: 'myHeadline', + label: 'Textarea label', + description: 'this is a textarea property', + dataTypeAlias: 'myTextStringEditor', + tempValue: 'hello world 1' + }, + { + alias: 'myDescription', + label: 'Text string label', + description: 'This is the a text string property', + dataTypeAlias: 'myTextAreaEditor', + tempValue: 'Tex areaaaa 1' + }, + ], + data: [ + { + alias: 'myHeadline', + value: 'hello world', + }, + { + alias: 'myDescription', + value: 'Teeeeexxxt areaaaaaa', + }, + ], + /* + layout: [ + { + type: 'group', + children: [ + { + type: 'property', + alias: 'myHeadline' + }, + { + type: 'property', + alias: 'myDescription' + } + ] + } + ], + */ + }, + { + id: '2', + key: '74e4008a-ea4f-4793-b924-15e02fd380d3', + name: 'Document 2', + alias: 'document2', + icon: 'favorite', + properties: [ + { + alias: 'myHeadline', + label: 'Textarea label', + description: 'this is a textarea property', + dataTypeAlias: 'myTextStringEditor', + tempValue: 'hello world 2' + }, + { + alias: 'myDescription', + label: 'Text string label', + description: 'This is the a text string property', + dataTypeAlias: 'myTextAreaEditor', + tempValue: 'Tex areaaaa 2' + }, + ], + data: [ + { + alias: 'myHeadline', + value: 'hello world', + }, + { + alias: 'myDescription', + value: 'Teeeeexxxt areaaaaaa', + }, + ], + /* + layout: [ + { + type: 'group', + children: [ + { + type: 'property', + alias: 'myHeadline' + }, + { + type: 'property', + alias: 'myDescription' + } + ] + } + ], + */ + } +]; + +export class UmbContentService { + + private _nodes: BehaviorSubject> = new BehaviorSubject(>[]); + public readonly nodes: Observable> = this._nodes.asObservable(); + + constructor () { + this._nodes.next(data); + } + + getById (id: string): Observable { + return this.nodes.pipe(map(((nodes: Array) => nodes.find((node: DocumentNode) => node.id === id) || null))); + } + +} \ No newline at end of file