allow multiple editors in settings section

This commit is contained in:
Mads Rasmussen
2022-07-04 16:44:18 +02:00
parent cf349aa045
commit f4d5acb9a6
8 changed files with 221 additions and 88 deletions

View File

@@ -13,7 +13,9 @@ import './components/backoffice-notification-container.element';
import './components/editor-layout.element';
import './components/editor-property-layout.element';
import './components/node-property.element';
import './components/section-layout.element';
import './components/section-sidebar.element';
import './components/section-main.element';
@defineElement('umb-backoffice')
export default class UmbBackoffice extends UmbContextProviderMixin(LitElement) {

View File

@@ -0,0 +1,27 @@
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { css, html, LitElement } from 'lit';
import { customElement } from 'lit/decorators.js';
@customElement('umb-section-layout')
export class UmbSectionLayout extends LitElement {
static styles = [
UUITextStyles,
css`
:host {
display: flex;
width: 100%;
height: 100%;
}
`,
];
render() {
return html`<slot></slot>`;
}
}
declare global {
interface HTMLElementTagNameMap {
'umb-section-layout': UmbSectionLayout;
}
}

View File

@@ -0,0 +1,26 @@
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { css, html, LitElement } from 'lit';
import { customElement } from 'lit/decorators.js';
@customElement('umb-section-main')
export class UmbSectionMain extends LitElement {
static styles = [
UUITextStyles,
css`
:host {
flex: 1 1 auto;
height: 100%;
}
`,
];
render() {
return html`<slot></slot>`;
}
}
declare global {
interface HTMLElementTagNameMap {
'umb-section-main': UmbSectionMain;
}
}

View File

@@ -0,0 +1,11 @@
import { html, LitElement } from 'lit';
import { customElement } from 'lit/decorators.js';
@customElement('umb-editor-data-type')
export class UmbEditorDataType extends LitElement {
render() {
return html`<div>Data types</div>`;
}
}
export default UmbEditorDataType;

View File

@@ -0,0 +1,72 @@
import { html, LitElement } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { Subscription } from 'rxjs';
import { UmbContextConsumerMixin } from '../../core/context';
import { UmbExtensionManifest, UmbExtensionRegistry } from '../../core/extension';
@customElement('umb-editor-extensions')
export class UmbEditorExtensions extends UmbContextConsumerMixin(LitElement) {
@state()
private _extensions: Array<UmbExtensionManifest> = [];
private _extensionRegistry?: UmbExtensionRegistry;
private _extensionsSubscription?: Subscription;
constructor() {
super();
this.consumeContext('umbExtensionRegistry', (_instance: UmbExtensionRegistry) => {
this._extensionRegistry = _instance;
this._extensionsSubscription?.unsubscribe();
// TODO: Niels: Could we make it easier to unsubscribe? If we invented a Pattern/Mixin/class ala Lit-Controllers we could make it auto unsubscribe.
// ContextConsumers could be turned into single classes which uses the 'Controller' ability to hook into connected and disconnected.
// Generally that means that a web component must have the ControllerMixin?? and then controllers can easily be attached, they would know about life cycle and thereby be able to unsubscribe on disconnected etc.
//
// All code regarding subscription could be boiled down to:
// OurUmbracoSubscribeMethod(this, this._extensionRegistry.extensions, (extensions) => {}); // uses `this` to append the subscription to the controller array.
// Or:
// this.attachSubscription(this._extensionRegistry.extensions, (extensions) => {});
this._extensionsSubscription = this._extensionRegistry.extensions.subscribe((extensions) => {
this._extensions = [...extensions]; // TODO: Though, this is a shallow clone, wouldn't we either do a deep clone or no clone at all?
});
this._extensionsSubscription = this._extensionRegistry.extensionsOfType('section').subscribe((sections) => {
// In this callback sections are typed. Example meta.weight...
console.log(sections[0].meta.weight);
});
});
}
disconnectedCallback(): void {
super.disconnectedCallback();
this._extensionsSubscription?.unsubscribe();
}
render() {
return html`
<uui-box headline="Extensions">
<uui-table>
<uui-table-head>
<uui-table-head-cell>Type</uui-table-head-cell>
<uui-table-head-cell>Name</uui-table-head-cell>
<uui-table-head-cell>Alias</uui-table-head-cell>
</uui-table-head>
${this._extensions.map(
(extension) => html`
<uui-table-row>
<uui-table-cell>${extension.type}</uui-table-cell>
<uui-table-cell>${extension.name}</uui-table-cell>
<uui-table-cell>${extension.alias}</uui-table-cell>
</uui-table-row>
`
)}
</uui-table>
</uui-box>
`;
}
}
export default UmbEditorExtensions;

View File

@@ -0,0 +1,33 @@
import { css, html, LitElement } from 'lit';
import { customElement } from 'lit/decorators.js';
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
@customElement('umb-settings-section-tree')
class UmbSettingsSectionTree extends LitElement {
static styles = [
UUITextStyles,
css`
h3 {
padding: var(--uui-size-4) var(--uui-size-8);
}
`,
];
render() {
return html`
<a href="${'/section/settings'}">
<h3>Settings</h3>
</a>
<!-- TODO: hardcoded tree items. These should come the extensions -->
<uui-menu-item label="Extensions" href="/section/settings/extensions"></uui-menu-item>
<uui-menu-item label="Data Types" href="/section/settings/data-types"></uui-menu-item>
`;
}
}
declare global {
interface HTMLElementTagNameMap {
'umb-settings-section-tree': UmbSettingsSectionTree;
}
}

View File

@@ -1,81 +1,43 @@
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { css, html, LitElement } from 'lit';
import { html, LitElement } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { Subscription } from 'rxjs';
import { IRoute } from 'router-slot';
import { UmbContextConsumerMixin } from '../../../core/context';
import { UmbExtensionManifest, UmbExtensionRegistry } from '../../../core/extension';
import './settings-section-tree.element';
@customElement('umb-settings-section')
export class UmbSettingsSection extends UmbContextConsumerMixin(LitElement) {
static styles = [
UUITextStyles,
css`
:host {
display: block;
padding: var(--uui-size-space-5);
}
`,
];
// TODO: hardcoded tree routes. These should come from extensions
@state()
private _extensions: Array<UmbExtensionManifest> = [];
private _extensionRegistry?: UmbExtensionRegistry;
private _extensionsSubscription?: Subscription;
constructor() {
super();
this.consumeContext('umbExtensionRegistry', (_instance: UmbExtensionRegistry) => {
this._extensionRegistry = _instance;
this._extensionsSubscription?.unsubscribe();
// TODO: Niels: Could we make it easier to unsubscribe? If we invented a Pattern/Mixin/class ala Lit-Controllers we could make it auto unsubscribe.
// ContextConsumers could be turned into single classes which uses the 'Controller' ability to hook into connected and disconnected.
// Generally that means that a web component must have the ControllerMixin?? and then controllers can easily be attached, they would know about life cycle and thereby be able to unsubscribe on disconnected etc.
//
// All code regarding subscription could be boiled down to:
// OurUmbracoSubscribeMethod(this, this._extensionRegistry.extensions, (extensions) => {}); // uses `this` to append the subscription to the controller array.
// Or:
// this.attachSubscription(this._extensionRegistry.extensions, (extensions) => {});
this._extensionsSubscription = this._extensionRegistry.extensions.subscribe((extensions) => {
this._extensions = [...extensions]; // TODO: Though, this is a shallow clone, wouldn't we either do a deep clone or no clone at all?
});
this._extensionsSubscription = this._extensionRegistry.extensionsOfType('section').subscribe((sections) => {
// In this callback sections are typed. Example meta.weight...
console.log(sections[0].meta.weight);
});
});
}
disconnectedCallback(): void {
super.disconnectedCallback();
this._extensionsSubscription?.unsubscribe();
}
private _routes: Array<IRoute> = [
{
path: 'dashboard',
component: () => import('../../components/section-dashboards.element'),
},
{
path: 'extensions',
component: () => import('../../editors/editor-extensions.element'),
},
{
path: 'data-types',
component: () => import('../../editors/editor-data-type.element'),
},
{
path: '**',
redirectTo: 'dashboard',
},
];
render() {
return html`
<uui-box headline="Extensions">
<uui-table>
<uui-table-head>
<uui-table-head-cell>Type</uui-table-head-cell>
<uui-table-head-cell>Name</uui-table-head-cell>
<uui-table-head-cell>Alias</uui-table-head-cell>
</uui-table-head>
<umb-section-layout>
<umb-section-sidebar>
<umb-settings-section-tree></umb-settings-section-tree>
</umb-section-sidebar>
${this._extensions.map(
(extension) => html`
<uui-table-row>
<uui-table-cell>${extension.type}</uui-table-cell>
<uui-table-cell>${extension.name}</uui-table-cell>
<uui-table-cell>${extension.alias}</uui-table-cell>
</uui-table-row>
`
)}
</uui-table>
</uui-box>
<umb-section-main>
<router-slot id="router-slot" .routes="${this._routes}"></router-slot>
</umb-section-main>
</umb-section-layout>
`;
}
}

View File

@@ -112,24 +112,24 @@ export const internalManifests: Array<UmbExtensionManifestCore> = [
icon: 'info',
},
},
{
type: 'propertyAction',
alias: 'Umb.PropertyAction.Copy',
name: 'Copy',
elementName: 'umb-property-action-copy',
js: () => import('./backoffice/property-actions/property-action-copy.element'),
meta: {
propertyEditors: ['Umb.PropertyEditorUI.Text']
}
},
{
type: 'propertyAction',
alias: 'Umb.PropertyAction.Clear',
name: 'Clear',
elementName: 'umb-property-action-clear',
js: () => import('./backoffice/property-actions/property-action-clear.element'),
meta: {
propertyEditors: ['Umb.PropertyEditorUI.Text']
}
}
{
type: 'propertyAction',
alias: 'Umb.PropertyAction.Copy',
name: 'Copy',
elementName: 'umb-property-action-copy',
js: () => import('./backoffice/property-actions/property-action-copy.element'),
meta: {
propertyEditors: ['Umb.PropertyEditorUI.Text'],
},
},
{
type: 'propertyAction',
alias: 'Umb.PropertyAction.Clear',
name: 'Clear',
elementName: 'umb-property-action-clear',
js: () => import('./backoffice/property-actions/property-action-clear.element'),
meta: {
propertyEditors: ['Umb.PropertyEditorUI.Text'],
},
},
];