add content service
This commit is contained in:
@@ -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`
|
||||
<umb-node-editor-layout>
|
||||
<uui-input slot="name" value="Home"></uui-input>
|
||||
<uui-input slot="name" .value="${this._node?.name}"></uui-input>
|
||||
<uui-tab-group slot="apps">
|
||||
<uui-tab active>Content</uui-tab>
|
||||
<uui-tab>Info</uui-tab>
|
||||
<uui-tab disabled>Actions</uui-tab>
|
||||
<uui-tab label="Content" active></uui-tab>
|
||||
<uui-tab label="Info"></uui-tab>
|
||||
<uui-tab label="Actions" disabled></uui-tab>
|
||||
</uui-tab-group>
|
||||
|
||||
<uui-box slot="content">
|
||||
<h1 style="margin-bottom: 40px;">RENDER NODE WITH ID: ${this.id}</h1>
|
||||
<!-- TODO: Make sure map get data from data object?, parse on property object. -->
|
||||
${this.nodeData.properties.map(
|
||||
${this._node?.properties.map(
|
||||
property => html`
|
||||
<umb-node-property
|
||||
.property=${property}
|
||||
@@ -160,9 +120,9 @@ class UmbContentEditor extends LitElement {
|
||||
</uui-box>
|
||||
|
||||
<div slot="actions">
|
||||
<uui-button @click=${this._onSaveAndPreview}>Save and preview</uui-button>
|
||||
<uui-button @click=${this._onSave} look="secondary">Save</uui-button>
|
||||
<uui-button @click=${this._onSaveAndPublish} look="primary" color="positive">Save and publish</uui-button>
|
||||
<uui-button @click=${this._onSaveAndPreview} label="Save and preview"></uui-button>
|
||||
<uui-button @click=${this._onSave} look="secondary" label="Save"></uui-button>
|
||||
<uui-button @click=${this._onSaveAndPublish} look="primary" color="positive" label="Save and publish"></uui-button>
|
||||
</div>
|
||||
</umb-node-editor-layout>
|
||||
`;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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<any> = [
|
||||
{
|
||||
id: '1',
|
||||
name: 'Hello World',
|
||||
icon: 'document',
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
name: 'Hello World 2',
|
||||
icon: 'document',
|
||||
}
|
||||
];
|
||||
_tree: Array<any> = [];
|
||||
|
||||
@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();
|
||||
|
||||
138
src/Umbraco.Web.UI.Client/src/content/content.service.ts
Normal file
138
src/Umbraco.Web.UI.Client/src/content/content.service.ts
Normal file
@@ -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<DocumentNode> = [
|
||||
{
|
||||
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<Array<DocumentNode>> = new BehaviorSubject(<Array<DocumentNode>>[]);
|
||||
public readonly nodes: Observable<Array<DocumentNode>> = this._nodes.asObservable();
|
||||
|
||||
constructor () {
|
||||
this._nodes.next(data);
|
||||
}
|
||||
|
||||
getById (id: string): Observable<DocumentNode | null> {
|
||||
return this.nodes.pipe(map(((nodes: Array<DocumentNode>) => nodes.find((node: DocumentNode) => node.id === id) || null)));
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user