render entity actions in workspace layout

This commit is contained in:
Mads Rasmussen
2023-02-02 08:34:17 +01:00
parent e41f962420
commit 98556ce25c
5 changed files with 133 additions and 38 deletions

View File

@@ -29,7 +29,7 @@ export class UmbDocumentWorkspaceElement extends UmbLitElement implements UmbWor
}
render() {
return html`<umb-workspace-content alias="Umb.Workspace.Document"></umb-workspace-content>`;
return html`<umb-workspace-content entity-type="document" alias="Umb.Workspace.Document"></umb-workspace-content>`;
}
}

View File

@@ -64,10 +64,6 @@ export class UmbBodyLayout extends LitElement {
`,
];
private hasNodes = (e: Event) => {
return (e.target as HTMLSlotElement).assignedNodes({ flatten: true }).length > 0;
};
/**
* Renders a headline in the header.
* @public
@@ -80,30 +76,51 @@ export class UmbBodyLayout extends LitElement {
@state()
private _headerSlotHasChildren = false;
@state()
private _tabsSlotHasChildren = false;
@state()
private _footerSlotHasChildren = false;
@state()
private _actionsSlotHasChildren = false;
@state()
private _actionsMenuSlotHasChildren = false;
#hasNodes = (e: Event) => {
return (e.target as HTMLSlotElement).assignedNodes({ flatten: true }).length > 0;
};
render() {
return html`
<div
id="header"
style="display:${this.headline || this._headerSlotHasChildren || this._tabsSlotHasChildren ? '' : 'none'}">
style="display:${this.headline ||
this._headerSlotHasChildren ||
this._tabsSlotHasChildren ||
this._actionsMenuSlotHasChildren
? ''
: 'none'}">
${this.headline ? html`<h3 id="headline">${this.headline}</h3>` : nothing}
<slot
name="header"
@slotchange=${(e: Event) => {
this._headerSlotHasChildren = this.hasNodes(e);
this._headerSlotHasChildren = this.#hasNodes(e);
}}></slot>
<slot
id="tabs"
name="tabs"
@slotchange=${(e: Event) => {
this._tabsSlotHasChildren = this.hasNodes(e);
this._tabsSlotHasChildren = this.#hasNodes(e);
}}></slot>
<slot
id="actions-menu"
name="actions-menu"
@slotchange=${(e: Event) => {
this._actionsMenuSlotHasChildren = this.#hasNodes(e);
}}></slot>
</div>
<uui-scroll-container id="main">
@@ -113,14 +130,14 @@ export class UmbBodyLayout extends LitElement {
<slot
name="footer"
@slotchange=${(e: Event) => {
this._footerSlotHasChildren = this.hasNodes(e);
this._footerSlotHasChildren = this.#hasNodes(e);
}}></slot>
<slot
id="actions"
name="actions"
style="display:${this._actionsSlotHasChildren ? '' : 'none'}"
@slotchange=${(e: Event) => {
this._actionsSlotHasChildren = this.hasNodes(e);
this._actionsSlotHasChildren = this.#hasNodes(e);
}}></slot>
</div>
`;

View File

@@ -0,0 +1,43 @@
import { html } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import { ifDefined } from 'lit/directives/if-defined.js';
import { UmbLitElement } from '@umbraco-cms/element';
import { ManifestEntityAction } from 'libs/extensions-registry/entity-action.models';
@customElement('umb-entity-action')
class UmbEntityActionElement extends UmbLitElement {
private _manifest?: ManifestEntityAction;
@property({ type: Object, attribute: false })
public get entityType() {
return this._manifest;
}
public set manifest(value: ManifestEntityAction | undefined) {
if (!value) return;
const oldValue = this._manifest;
this._manifest = value;
if (oldValue !== this._manifest) {
this.#api = new this._manifest.meta.api(this);
this.requestUpdate('manifest', oldValue);
}
}
#api: any;
#onClickLabel() {
this.#api.execute();
}
render() {
return html`
<uui-menu-item
label="${ifDefined(this._manifest?.meta.label)}"
@click-label=${this.#onClickLabel}></uui-menu-item>
`;
}
}
declare global {
interface HTMLElementTagNameMap {
'umb-entity-action': UmbEntityActionElement;
}
}

View File

@@ -15,7 +15,7 @@ import { UmbLitElement } from '@umbraco-cms/element';
* TODO: IMPORTANT TODO: Get rid of the content workspace. Instead we aim to get separate components that can be composed by each workspace.
* Example. Document Workspace would use a Variant-component(variant component would talk directly to the workspace-context)
* As well breadcrumbs etc.
*
*
*/
@customElement('umb-workspace-content')
export class UmbWorkspaceContentElement extends UmbLitElement {
@@ -43,9 +43,12 @@ export class UmbWorkspaceContentElement extends UmbLitElement {
@property()
alias!: string;
@property({ type: String, attribute: 'entity-type' })
public entityType = '';
render() {
return html`
<umb-workspace-layout alias=${this.alias}>
<umb-workspace-layout entity-type=${this.entityType} alias=${this.alias}>
<div id="header" slot="header">
<umb-variant-selector></umb-variant-selector>
</div>

View File

@@ -16,6 +16,9 @@ import type {
import '../../body-layout/body-layout.element';
import '../../extension-slot/extension-slot.element';
import { UmbLitElement } from '@umbraco-cms/element';
import { ManifestEntityAction } from 'libs/extensions-registry/entity-action.models';
import '../entity-action.element';
/**
* @element umb-workspace-layout
@@ -61,6 +64,20 @@ export class UmbWorkspaceLayout extends UmbLitElement {
`,
];
private _entityType = '';
@property({ type: String, attribute: 'entity-type' })
public get entityType() {
return this._entityType;
}
public set entityType(value) {
const oldValue = this._entityType;
this._entityType = value;
if (oldValue !== this._entityType) {
this.#observeEntityActions();
this.requestUpdate('entityType', oldValue);
}
}
@property()
public headline = '';
@@ -97,6 +114,15 @@ export class UmbWorkspaceLayout extends UmbLitElement {
@state()
private _activePath?: string;
@state()
private _entityActions?: Array<ManifestEntityAction>;
#observeEntityActions() {
this.observe(umbExtensionsRegistry.extensionsOfType('entityAction'), (actions) => {
this._entityActions = actions;
});
}
private _observeWorkspaceViews() {
this.observe(
umbExtensionsRegistry
@@ -142,7 +168,34 @@ export class UmbWorkspaceLayout extends UmbLitElement {
}
}
private _renderTabs() {
render() {
return html`
<umb-body-layout .headline=${this.headline}>
<slot name="header" slot="header"></slot>
${this.#renderTabs()} ${this.#renderActionsMenu()}
<umb-router-slot
.routes="${this._routes}"
@init=${(event: UmbRouterSlotInitEvent) => {
this._routerPath = event.target.absoluteRouterPath;
}}
@change=${(event: UmbRouterSlotChangeEvent) => {
this._activePath = event.target.localActiveViewPath;
}}></umb-router-slot>
<slot></slot>
<slot name="footer" slot="footer"></slot>
<umb-extension-slot
slot="actions"
type="workspaceAction"
.filter=${(extension: ManifestWorkspaceAction) =>
extension.meta.workspaces.includes(this.alias)}></umb-extension-slot>
<slot name="actions" slot="actions"></slot>
</umb-body-layout>
`;
}
#renderTabs() {
return html`
${this._workspaceViews.length > 0
? html`
@@ -166,31 +219,10 @@ export class UmbWorkspaceLayout extends UmbLitElement {
`;
}
render() {
return html`
<umb-body-layout .headline=${this.headline}>
<slot name="header" slot="header"></slot>
${this._renderTabs()}
<umb-router-slot
.routes="${this._routes}"
@init=${(event: UmbRouterSlotInitEvent) => {
this._routerPath = event.target.absoluteRouterPath;
}}
@change=${(event: UmbRouterSlotChangeEvent) => {
this._activePath = event.target.localActiveViewPath;
}}></umb-router-slot>
<slot></slot>
<slot name="footer" slot="footer"></slot>
<umb-extension-slot
slot="actions"
type="workspaceAction"
.filter=${(extension: ManifestWorkspaceAction) =>
extension.meta.workspaces.includes(this.alias)}></umb-extension-slot>
<slot name="actions" slot="actions"></slot>
</umb-body-layout>
`;
#renderActionsMenu() {
return html`<div slot="actions-menu">
${this._entityActions?.map((manifest) => html`<umb-entity-action .manifest=${manifest}></umb-entity-action>`)}
</div>`;
}
}