added editor action extension, schemas and api
This commit is contained in:
@@ -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'
|
||||
|
||||
@@ -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"]
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
`;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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>>;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user