added editor action extension, schemas and api

This commit is contained in:
Jesper Møller Jensen
2022-10-04 13:38:28 +02:00
parent 31f559a5ca
commit 23ec98874c
9 changed files with 240 additions and 67 deletions

View File

@@ -486,6 +486,78 @@ components:
- meta
- alias
- name
MetaEditorAction:
type: object
properties:
editors:
type: array
items:
type: string
required:
- editors
IManifestEditorAction:
type: object
properties:
type:
type: string
enum:
- editorAction
meta:
$ref: '#/components/schemas/MetaEditorAction'
js:
type: string
elementName:
type: string
alias:
type: string
name:
type: string
required:
- type
- meta
- alias
- name
MetaEditorView:
type: object
properties:
editors:
type: array
items:
type: string
pathname:
type: string
weight:
type: number
format: float
icon:
type: string
required:
- editors
- pathname
- weight
- icon
IManifestEditorView:
type: object
properties:
type:
type: string
enum:
- editorView
meta:
$ref: '#/components/schemas/MetaEditorView'
js:
type: string
elementName:
type: string
alias:
type: string
name:
type: string
required:
- type
- meta
- alias
- name
MetaTreeItemAction:
type: object
properties:
@@ -624,47 +696,6 @@ components:
- meta
- alias
- name
MetaEditorView:
type: object
properties:
editors:
type: array
items:
type: string
pathname:
type: string
weight:
type: number
format: float
icon:
type: string
required:
- editors
- pathname
- weight
- icon
IManifestEditorView:
type: object
properties:
type:
type: string
enum:
- editorView
meta:
$ref: '#/components/schemas/MetaEditorView'
js:
type: string
elementName:
type: string
alias:
type: string
name:
type: string
required:
- type
- meta
- alias
- name
MetaPropertyAction:
type: object
properties:
@@ -765,10 +796,11 @@ components:
- $ref: '#/components/schemas/IManifestSection'
- $ref: '#/components/schemas/IManifestTree'
- $ref: '#/components/schemas/IManifestEditor'
- $ref: '#/components/schemas/IManifestEditorAction'
- $ref: '#/components/schemas/IManifestEditorView'
- $ref: '#/components/schemas/IManifestTreeItemAction'
- $ref: '#/components/schemas/IManifestPropertyEditorUI'
- $ref: '#/components/schemas/IManifestDashboard'
- $ref: '#/components/schemas/IManifestEditorView'
- $ref: '#/components/schemas/IManifestPropertyAction'
- $ref: '#/components/schemas/IManifestPackageView'
- $ref: '#/components/schemas/IManifestEntrypoint'
@@ -779,10 +811,11 @@ components:
section: '#/components/schemas/IManifestSection'
tree: '#/components/schemas/IManifestTree'
editor: '#/components/schemas/IManifestEditor'
editorAction: '#/components/schemas/IManifestEditorAction'
editorView: '#/components/schemas/IManifestEditorView'
treeItemAction: '#/components/schemas/IManifestTreeItemAction'
propertyEditorUI: '#/components/schemas/IManifestPropertyEditorUI'
dashboard: '#/components/schemas/IManifestDashboard'
editorView: '#/components/schemas/IManifestEditorView'
propertyAction: '#/components/schemas/IManifestPropertyAction'
packageView: '#/components/schemas/IManifestPackageView'
entrypoint: '#/components/schemas/IManifestEntrypoint'

View File

@@ -151,6 +151,34 @@ export interface components {
alias: string;
name: string;
};
MetaEditorAction: {
editors: string[];
};
IManifestEditorAction: {
/** @enum {string} */
type: "editorAction";
meta: components["schemas"]["MetaEditorAction"];
js?: string;
elementName?: string;
alias: string;
name: string;
};
MetaEditorView: {
editors: string[];
pathname: string;
/** Format: float */
weight: number;
icon: string;
};
IManifestEditorView: {
/** @enum {string} */
type: "editorView";
meta: components["schemas"]["MetaEditorView"];
js?: string;
elementName?: string;
alias: string;
name: string;
};
MetaTreeItemAction: {
trees: string[];
label: string;
@@ -206,22 +234,6 @@ export interface components {
alias: string;
name: string;
};
MetaEditorView: {
editors: string[];
pathname: string;
/** Format: float */
weight: number;
icon: string;
};
IManifestEditorView: {
/** @enum {string} */
type: "editorView";
meta: components["schemas"]["MetaEditorView"];
js?: string;
elementName?: string;
alias: string;
name: string;
};
MetaPropertyAction: {
propertyEditors: string[];
};
@@ -264,10 +276,11 @@ export interface components {
| components["schemas"]["IManifestSection"]
| components["schemas"]["IManifestTree"]
| components["schemas"]["IManifestEditor"]
| components["schemas"]["IManifestEditorAction"]
| components["schemas"]["IManifestEditorView"]
| components["schemas"]["IManifestTreeItemAction"]
| components["schemas"]["IManifestPropertyEditorUI"]
| components["schemas"]["IManifestDashboard"]
| components["schemas"]["IManifestEditorView"]
| components["schemas"]["IManifestPropertyAction"]
| components["schemas"]["IManifestPackageView"]
| components["schemas"]["IManifestEntrypoint"]

View File

@@ -0,0 +1,46 @@
import { UUITextStyles } from '@umbraco-ui/uui';
import { CSSResultGroup, html, LitElement } from 'lit';
import { customElement, property, state } from 'lit/decorators.js';
import { createExtensionElement } from '../../../../core/extension';
import type { ManifestEditorAction } from '../../../../core/models';
@customElement('umb-editor-action-extension')
export class UmbEditorActionExtensionElement extends LitElement {
static styles: CSSResultGroup = [UUITextStyles];
private _editorAction?: ManifestEditorAction;
@property({ type: Object })
public get editorAction(): ManifestEditorAction | undefined {
return this._editorAction;
}
public set editorAction(value: ManifestEditorAction | undefined) {
this._editorAction = value;
this._createElement();
}
@state()
private _element?: any;
private async _createElement() {
if (!this.editorAction) return;
try {
this._element = await createExtensionElement(this.editorAction);
if (!this._element) return;
this._element.editorAction = this.editorAction;
} catch (error) {
// TODO: loading JS failed so we should do some nice UI. (This does only happen if extension has a js prop, otherwise we concluded that no source was needed resolved the load.)
}
}
render() {
return html`${this._element}`;
}
}
declare global {
interface HTMLElementTagNameMap {
'umb-editor-action-extension': UmbEditorActionExtensionElement;
}
}

View File

@@ -1,4 +1,5 @@
import '../editor-layout/editor-layout.element';
import '../editor-action-extension/editor-action-extension.element';
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { css, html, LitElement, nothing } from 'lit';
@@ -8,7 +9,7 @@ import { map, Subscription } from 'rxjs';
import { UmbContextConsumerMixin } from '../../../../core/context';
import { createExtensionElement, UmbExtensionRegistry } from '../../../../core/extension';
import type { ManifestEditorView } from '../../../../core/models';
import type { ManifestEditorAction, ManifestEditorView } from '../../../../core/models';
@customElement('umb-editor-entity-layout')
export class UmbEditorEntityLayout extends UmbContextConsumerMixin(LitElement) {
@@ -71,6 +72,9 @@ export class UmbEditorEntityLayout extends UmbContextConsumerMixin(LitElement) {
@state()
private _editorViews: Array<ManifestEditorView> = [];
@state()
private _editorActions: Array<ManifestEditorAction> = [];
@state()
private _currentView = '';
@@ -79,6 +83,7 @@ export class UmbEditorEntityLayout extends UmbContextConsumerMixin(LitElement) {
private _extensionRegistry?: UmbExtensionRegistry;
private _editorViewsSubscription?: Subscription;
private _editorActionsSubscription?: Subscription;
private _routerFolder = '';
constructor() {
@@ -86,7 +91,8 @@ export class UmbEditorEntityLayout extends UmbContextConsumerMixin(LitElement) {
this.consumeContext('umbExtensionRegistry', (extensionRegistry: UmbExtensionRegistry) => {
this._extensionRegistry = extensionRegistry;
this._useEditorViews();
this._observeEditorViews();
this._observeEditorActions();
});
}
@@ -96,7 +102,7 @@ export class UmbEditorEntityLayout extends UmbContextConsumerMixin(LitElement) {
this._routerFolder = window.location.pathname.split('/view')[0];
}
private _useEditorViews() {
private _observeEditorViews() {
this._editorViewsSubscription?.unsubscribe();
this._editorViewsSubscription = this._extensionRegistry
@@ -114,6 +120,17 @@ export class UmbEditorEntityLayout extends UmbContextConsumerMixin(LitElement) {
});
}
private _observeEditorActions() {
this._editorActionsSubscription?.unsubscribe();
this._editorActionsSubscription = this._extensionRegistry
?.extensionsOfType('editorAction')
.pipe(map((extensions) => extensions.filter((extension) => extension.meta.editors.includes(this.alias))))
.subscribe((editorActions) => {
this._editorActions = editorActions;
});
}
private async _createRoutes() {
if (this._editorViews.length > 0) {
this._routes = [];
@@ -184,7 +201,12 @@ export class UmbEditorEntityLayout extends UmbContextConsumerMixin(LitElement) {
<div id="footer" slot="footer">
<slot name="footer"></slot>
<slot id="actions" name="actions"></slot>
<div id="actions">
${this._editorActions.map(
(action) => html`<umb-editor-action-extension .editorAction=${action}></umb-editor-action-extension>`
)}
<slot name="actions"></slot>
</div>
</div>
</umb-editor-layout>
`;

View File

@@ -0,0 +1,24 @@
import { css, html, LitElement, nothing } from 'lit';
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { customElement, state } from 'lit/decorators.js';
@customElement('umb-editor-action-users-save')
export class UmbEditorActionUsersSaveElement extends LitElement {
static styles = [UUITextStyles, css``];
private _handleSave() {
console.log('save');
}
render() {
return html`<uui-button @click=${this._handleSave} look="primary" color="positive" label="save"></uui-button>`;
}
}
export default UmbEditorActionUsersSaveElement;
declare global {
interface HTMLElementTagNameMap {
'umb-editor-action-users-save': UmbEditorActionUsersSaveElement;
}
}

View File

@@ -17,6 +17,7 @@ import type {
ManifestTree,
ManifestTreeItemAction,
ManifestEditor,
ManifestEditorAction,
ManifestCustom,
ManifestPackageView,
} from '../models';
@@ -65,6 +66,7 @@ export class UmbExtensionRegistry {
extensionsOfType(type: 'treeItemAction'): Observable<Array<ManifestTreeItemAction>>;
extensionsOfType(type: 'dashboard'): Observable<Array<ManifestDashboard>>;
extensionsOfType(type: 'editorView'): Observable<Array<ManifestEditorView>>;
extensionsOfType(type: 'editorAction'): Observable<Array<ManifestEditorAction>>;
extensionsOfType(type: 'propertyEditorUI'): Observable<Array<ManifestPropertyEditorUI>>;
extensionsOfType(type: 'propertyAction'): Observable<Array<ManifestPropertyAction>>;
extensionsOfType(type: 'packageView'): Observable<Array<ManifestPackageView>>;

View File

@@ -22,6 +22,7 @@ export type ManifestSection = components['schemas']['IManifestSection'];
export type ManifestTree = components['schemas']['IManifestTree'];
export type ManifestTreeItemAction = components['schemas']['IManifestTreeItemAction'];
export type ManifestEditor = components['schemas']['IManifestEditor'];
export type ManifestEditorAction = components['schemas']['IManifestEditorAction'];
export type ManifestPropertyEditorUI = components['schemas']['IManifestPropertyEditorUI'];
export type ManifestDashboard = components['schemas']['IManifestDashboard'];
export type ManifestEditorView = components['schemas']['IManifestEditorView'];
@@ -40,6 +41,7 @@ export type ManifestElementType =
| ManifestPropertyEditorUI
| ManifestDashboard
| ManifestEditorView
| ManifestEditorAction
| ManifestPackageView;
// eslint-disable-next-line @typescript-eslint/no-explicit-any

View File

@@ -269,6 +269,24 @@ export const internalManifests: Array<ManifestTypes & { loader: () => Promise<ob
icon: 'document',
},
},
{
type: 'editorAction',
alias: 'Umb.EditorAction.Users.Save',
name: 'EditorActionUserSave',
loader: () => import('./backoffice/editors/users/views/users/actions/editor-action-users-save.element'),
meta: {
editors: ['Umb.Editor.Users'],
},
},
{
type: 'editorAction',
alias: 'Umb.EditorAction.Users.Delete',
name: 'EditorActionUserDelete',
loader: () => import('./backoffice/editors/users/views/users/actions/editor-action-users-save.element'),
meta: {
editors: ['Umb.Editor.DataType'],
},
},
{
type: 'editorView',
alias: 'Umb.EditorView.Users.UserGroups',

View File

@@ -33,10 +33,11 @@ export type Manifest =
| IManifestSection
| IManifestTree
| IManifestEditor
| IManifestEditorAction
| IManifestEditorView
| IManifestTreeItemAction
| IManifestPropertyEditorUI
| IManifestDashboard
| IManifestEditorView
| IManifestPropertyAction
| IManifestPackageView
| IManifestEntrypoint
@@ -46,13 +47,15 @@ export type ManifestStandardTypes =
| 'section'
| 'tree'
| 'editor'
| 'editorView'
| 'editorAction'
| 'treeItemAction'
| 'propertyEditorUI'
| 'dashboard'
| 'editorView'
| 'propertyAction'
| 'packageView'
| 'entrypoint';
| 'entrypoint'
;
export interface ManifestsResponse {
manifests: Manifest[];
@@ -156,6 +159,16 @@ export interface IManifestSection extends IManifestElement {
meta: MetaSection;
}
export interface IManifestEditorAction extends IManifestElement {
type: 'editorAction';
meta: MetaEditorAction;
}
export interface MetaEditorAction {
editors: Array<string>;
}
export interface IManifestTree extends IManifestElement {
type: 'tree';
meta: MetaTree;