render entity actions in collection

This commit is contained in:
Mads Rasmussen
2023-02-06 12:18:16 +01:00
parent 394032ba6f
commit 3c7e2fdd7b
7 changed files with 130 additions and 18 deletions

View File

@@ -5,7 +5,7 @@ export const manifests: Array<ManifestCollectionView> = [
type: 'collectionView',
alias: 'Umb.CollectionView.Document.Table',
name: 'Document Table Collection View',
loader: () => import('./document-table-collection-view.element'),
loader: () => import('./views/table/document-table-collection-view.element'),
weight: 200,
meta: {
label: 'Table',

View File

@@ -0,0 +1,78 @@
import { css, html, LitElement, nothing } from 'lit';
import { ifDefined } from 'lit-html/directives/if-defined.js';
import { customElement, property, state } from 'lit/decorators.js';
import type { UmbTableColumn, UmbTableItem } from '../../../../../../shared/components/table';
// TODO: this could be done more generic, but for now we just need it for the document table
@customElement('umb-document-table-actions-column-layout')
export class UmbDocumentTableActionColumnLayoutElement extends LitElement {
static styles = [
css`
#action-menu-popover {
display: block;
}
#action-menu-dropdown {
overflow: hidden;
z-index: -1;
background-color: var(--uui-combobox-popover-background-color, var(--uui-color-surface));
border: 1px solid var(--uui-color-border);
border-radius: var(--uui-border-radius);
width: 100%;
height: 100%;
box-sizing: border-box;
box-shadow: var(--uui-shadow-depth-3);
width: 500px;
}
`,
];
@property({ type: Object, attribute: false })
column!: UmbTableColumn;
@property({ type: Object, attribute: false })
item!: UmbTableItem;
@property({ attribute: false })
value!: any;
@state()
private _actionMenuIsOpen = false;
#close() {
this._actionMenuIsOpen = false;
}
#open(event: Event) {
event.stopPropagation();
this._actionMenuIsOpen = true;
}
render() {
return html`
<uui-popover id="action-menu-popover" .open=${this._actionMenuIsOpen} @close=${this.#close}>
<uui-button slot="trigger" compact @click=${this.#open}><uui-symbol-more></uui-symbol-more></uui-button>
${this._actionMenuIsOpen ? this.#renderDropdown() : nothing}
</uui-popover>
`;
}
#renderDropdown() {
return html`
<div id="action-menu-dropdown" slot="popover">
<uui-scroll-container>
<umb-entity-action-list
entity-type=${ifDefined(this.value.entityType)}
unique=${ifDefined(this.item.key)}></umb-entity-action-list>
</uui-scroll-container>
</div>
`;
}
}
export default UmbDocumentTableActionColumnLayoutElement;
declare global {
interface HTMLElementTagNameMap {
'umb-document-table-actions-column-layout': UmbDocumentTableActionColumnLayoutElement;
}
}

View File

@@ -1,7 +1,10 @@
import { UUITextStyles } from '@umbraco-ui/uui-css';
import { css, html } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { UmbCollectionContext, UMB_COLLECTION_CONTEXT_TOKEN } from '../../../shared/collection/collection.context';
import {
UmbCollectionContext,
UMB_COLLECTION_CONTEXT_TOKEN,
} from '../../../../../shared/collection/collection.context';
import {
UmbTableColumn,
UmbTableConfig,
@@ -10,11 +13,13 @@ import {
UmbTableItem,
UmbTableOrderedEvent,
UmbTableSelectedEvent,
} from '../../../shared/components/table';
} from '../../../../../shared/components/table';
import type { DocumentDetails } from '@umbraco-cms/models';
import { UmbLitElement } from '@umbraco-cms/element';
import { EntityTreeItem } from '@umbraco-cms/backend-api';
import './column-layouts/document-table-actions-column-layout.element';
type EntityType = DocumentDetails;
@customElement('umb-document-table-collection-view')
@@ -50,10 +55,14 @@ export class UmbDocumentTableCollectionViewElement extends UmbLitElement {
{
name: 'Name',
alias: 'entityName',
allowSorting: true,
},
// TODO: actions should live in an UmbTable element when we have moved the current UmbTable to UUI.
{
name: 'Actions',
alias: 'entityActions',
elementName: 'umb-document-table-actions-column-layout',
width: '80px',
},
];
@@ -100,7 +109,9 @@ export class UmbDocumentTableCollectionViewElement extends UmbLitElement {
},
{
columnAlias: 'entityActions',
value: item.name || 'Untitled',
value: {
entityType: item.type,
},
},
],
};

View File

@@ -1,9 +1,9 @@
import { html } from 'lit';
import { customElement, property, state } from 'lit/decorators.js';
import { map } from 'rxjs';
import { UmbLitElement } from '@umbraco-cms/element';
import { umbExtensionsRegistry } from '@umbraco-cms/extensions-api';
import { ManifestEntityAction } from 'libs/extensions-registry/entity-action.models';
import { map } from 'rxjs';
@customElement('umb-entity-action-list')
class UmbEntityActionListElement extends UmbLitElement {
@@ -27,6 +27,7 @@ class UmbEntityActionListElement extends UmbLitElement {
@state()
private _entityActions?: Array<ManifestEntityAction>;
// TODO: find a solution to use extension slot
#observeEntityActions() {
// TODO: filter on entity type
this.observe(

View File

@@ -3,6 +3,7 @@ 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';
import { UUIMenuItemEvent } from '@umbraco-ui/uui';
@customElement('umb-entity-action')
class UmbEntityActionElement extends UmbLitElement {
@@ -43,13 +44,23 @@ class UmbEntityActionElement extends UmbLitElement {
#api: any;
async #onClickLabel() {
async #onClickLabel(event: UUIMenuItemEvent) {
event.stopPropagation();
await this.#api.execute();
}
// TODO: we need to stop the regular click event from bubbling up to the table so it doesn't select the row.
// This should probably be handled in the UUI Menu item component. so we don't dispatch a label-click event and click event at the same time.
#onClick(event: PointerEvent) {
event.stopPropagation();
}
render() {
return html`
<uui-menu-item label="${ifDefined(this._manifest?.meta.label)}" @click-label=${this.#onClickLabel}>
<uui-menu-item
label="${ifDefined(this._manifest?.meta.label)}"
@click-label=${this.#onClickLabel}
@click=${this.#onClick}>
${this._manifest?.meta.icon
? html`<uui-icon slot="icon" name="${this._manifest?.meta.icon}"></uui-icon>`
: nothing}

View File

@@ -1,14 +1,15 @@
import { UUITextStyles } from '@umbraco-ui/uui-css';
import { css, html, LitElement } from 'lit';
import { css, html, LitElement, nothing } from 'lit';
import { ifDefined } from 'lit-html/directives/if-defined.js';
import { when } from 'lit-html/directives/when.js';
import { customElement, property, state } from 'lit/decorators.js';
import { repeat } from 'lit/directives/repeat.js';
// TODO: move to UI Library
// TODO: move to UI Library - entity actions should NOT be moved to UI Library but stay in an UmbTable element
export interface UmbTableItem {
key: string;
icon?: string;
entityType?: string;
data: Array<UmbTableItemData>;
}
@@ -21,6 +22,8 @@ export interface UmbTableColumn {
name: string;
alias: string;
elementName?: string;
width?: string;
allowSorting?: boolean;
}
export interface UmbTableConfig {
@@ -219,13 +222,20 @@ export class UmbTableElement extends LitElement {
private _renderHeaderCell(column: UmbTableColumn) {
return html`
<uui-table-head-cell style="--uui-table-cell-padding: 0">
<button
style="padding: var(--uui-size-4) var(--uui-size-5);"
@click="${() => this._handleOrderingChange(column)}">
${column.name}
<uui-symbol-sort ?active=${this.orderingColumn === column.alias} ?descending=${this.orderingDesc}>
</uui-symbol-sort></button
></uui-table-head-cell>
${column.allowSorting ? html`${this._renderSortingUI(column)}` : nothing}
</uui-table-head-cell>
`;
}
private _renderSortingUI(column: UmbTableColumn) {
return html`
<button
style="padding: var(--uui-size-4) var(--uui-size-5);"
@click="${() => this._handleOrderingChange(column)}">
${column.name}
<uui-symbol-sort ?active=${this.orderingColumn === column.alias} ?descending=${this.orderingDesc}>
</uui-symbol-sort>
</button>
`;
}

View File

@@ -49,9 +49,9 @@ export class UmbWorkspaceLayout extends UmbLitElement {
border-left: 1px solid var(--uui-color-border);
border-right: 1px solid var(--uui-color-border);
}
router-slot {
#router-slot {
height: 100%;
flex: 0;
}
umb-extension-slot[slot='actions'] {
@@ -150,6 +150,7 @@ export class UmbWorkspaceLayout extends UmbLitElement {
<slot name="action-menu" slot="action-menu"></slot>
<umb-router-slot
id="router-slot"
.routes="${this._routes}"
@init=${(event: UmbRouterSlotInitEvent) => {
this._routerPath = event.target.absoluteRouterPath;