From 3c7e2fdd7b309c2cd75ca7384f8f3ae9d90ddc93 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 6 Feb 2023 12:18:16 +0100 Subject: [PATCH] render entity actions in collection --- .../documents/collection/manifests.ts | 2 +- ...ent-table-actions-column-layout.element.ts | 78 +++++++++++++++++++ .../document-table-collection-view.element.ts | 17 +++- .../entity-action-list.element.ts | 3 +- .../entity-action/entity-action.element.ts | 15 +++- .../shared/components/table/table.element.ts | 28 ++++--- .../workspace-layout.element.ts | 5 +- 7 files changed, 130 insertions(+), 18 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/collection/views/table/column-layouts/document-table-actions-column-layout.element.ts rename src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/collection/{ => views/table}/document-table-collection-view.element.ts (87%) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/collection/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/collection/manifests.ts index 5ccec908b4..0942914f4a 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/collection/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/collection/manifests.ts @@ -5,7 +5,7 @@ export const manifests: Array = [ 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', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/collection/views/table/column-layouts/document-table-actions-column-layout.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/collection/views/table/column-layouts/document-table-actions-column-layout.element.ts new file mode 100644 index 0000000000..5c7f1a9a4e --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/collection/views/table/column-layouts/document-table-actions-column-layout.element.ts @@ -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` + + + ${this._actionMenuIsOpen ? this.#renderDropdown() : nothing} + + `; + } + + #renderDropdown() { + return html` +
+ + + +
+ `; + } +} + +export default UmbDocumentTableActionColumnLayoutElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-document-table-actions-column-layout': UmbDocumentTableActionColumnLayoutElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/collection/document-table-collection-view.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/collection/views/table/document-table-collection-view.element.ts similarity index 87% rename from src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/collection/document-table-collection-view.element.ts rename to src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/collection/views/table/document-table-collection-view.element.ts index 637bc90c03..6105371d62 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/collection/document-table-collection-view.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/collection/views/table/document-table-collection-view.element.ts @@ -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, + }, }, ], }; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/entity-action/entity-action-list.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/entity-action/entity-action-list.element.ts index 0819a71d8c..a0e0c50956 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/entity-action/entity-action-list.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/entity-action/entity-action-list.element.ts @@ -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; + // TODO: find a solution to use extension slot #observeEntityActions() { // TODO: filter on entity type this.observe( diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/entity-action/entity-action.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/entity-action/entity-action.element.ts index c08b1b8b6a..2ae2150934 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/entity-action/entity-action.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/entity-action/entity-action.element.ts @@ -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` - + ${this._manifest?.meta.icon ? html`` : nothing} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/table/table.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/table/table.element.ts index edd194d815..bf3b0863b4 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/table/table.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/table/table.element.ts @@ -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; } @@ -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` - + ${column.allowSorting ? html`${this._renderSortingUI(column)}` : nothing} + + `; + } + + private _renderSortingUI(column: UmbTableColumn) { + return html` + `; } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-layout/workspace-layout.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-layout/workspace-layout.element.ts index f2cfdf468e..dc22dc56c3 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-layout/workspace-layout.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-layout/workspace-layout.element.ts @@ -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 { { this._routerPath = event.target.absoluteRouterPath;