From ab4b8f6add3e7e02a7f85fd0079b2c1c866eeac0 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Wed, 24 Jul 2024 11:41:33 +0200 Subject: [PATCH] fix: show the action button inside a button-group only if there are extensions registered by moving the calculation of the extension controllers from the action-menu element into the action element itself, we can save a few states, simplify the calculation, and conditionally render the action-menu element ensuring, that the UUI styling is correctly applied --- .../workspace-action-menu.element.ts | 86 ++------------- .../default/workspace-action.element.ts | 102 +++++++++++++----- 2 files changed, 87 insertions(+), 101 deletions(-) diff --git a/src/packages/core/workspace/components/workspace-action-menu/workspace-action-menu.element.ts b/src/packages/core/workspace/components/workspace-action-menu/workspace-action-menu.element.ts index 587aa8fb66..cf01d7e666 100644 --- a/src/packages/core/workspace/components/workspace-action-menu/workspace-action-menu.element.ts +++ b/src/packages/core/workspace/components/workspace-action-menu/workspace-action-menu.element.ts @@ -1,85 +1,24 @@ -import type { CSSResultGroup } from '@umbraco-cms/backoffice/external/lit'; import { css, html, customElement, property, state, nothing, repeat } from '@umbraco-cms/backoffice/external/lit'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; -import { - umbExtensionsRegistry, - type ManifestWorkspaceActionMenuItem, -} from '@umbraco-cms/backoffice/extension-registry'; +import type { ManifestWorkspaceActionMenuItem } from '@umbraco-cms/backoffice/extension-registry'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import type { UUIInterfaceColor, UUIInterfaceLook } from '@umbraco-cms/backoffice/external/uui'; -import { - type UmbExtensionElementAndApiInitializer, - UmbExtensionsElementAndApiInitializer, -} from '@umbraco-cms/backoffice/extension-api'; +import type { UmbExtensionElementAndApiInitializer } from '@umbraco-cms/backoffice/extension-api'; -function ExtensionApiArgsMethod(manifest: ManifestWorkspaceActionMenuItem) { - return [{ meta: manifest.meta }]; -} @customElement('umb-workspace-action-menu') export class UmbWorkspaceActionMenuElement extends UmbLitElement { - #extensionsController?: UmbExtensionsElementAndApiInitializer< - ManifestWorkspaceActionMenuItem, - 'workspaceActionMenuItem', - ManifestWorkspaceActionMenuItem - >; - - /** - * The workspace actions to filter the available actions by. - * @example ['Umb.WorkspaceAction.Document.Save', 'Umb.WorkspaceAction.Document.SaveAndPublishNew'] - */ - @property({ attribute: false }) - public set forWorkspaceActions(value: Array) { - if (value === this._forWorkspaceActions) return; - this._forWorkspaceActions = value; - this._filter = (action) => { - return Array.isArray(action.forWorkspaceActions) - ? action.forWorkspaceActions.some((alias) => this.forWorkspaceActions.includes(alias)) - : this.forWorkspaceActions.includes(action.forWorkspaceActions); - }; - this.#observeExtensions(); - } - public get forWorkspaceActions(): Array { - return this._forWorkspaceActions; - } - private _forWorkspaceActions: Array = []; - - @state() - _filter?: (action: ManifestWorkspaceActionMenuItem) => boolean; - @property() look: UUIInterfaceLook = 'secondary'; @property() color: UUIInterfaceColor = 'default'; - @state() - _items: Array> = []; + @property({ type: Array, attribute: false }) + items: Array> = []; @state() _popoverOpen = false; - #observeExtensions(): void { - this.#extensionsController?.destroy(); - if (this._filter) { - this.#extensionsController = new UmbExtensionsElementAndApiInitializer< - ManifestWorkspaceActionMenuItem, - 'workspaceActionMenuItem', - ManifestWorkspaceActionMenuItem - >( - this, - umbExtensionsRegistry, - 'workspaceActionMenuItem', - ExtensionApiArgsMethod, - this._filter, - (extensionControllers) => { - this._items = extensionControllers; - }, - undefined, // We can leave the alias to undefined, as we destroy this our selfs. - ); - //this.#extensionsController.elementProperties = this.#elProps; - } - } - #onPopoverToggle(event: ToggleEvent) { // TODO: This ignorer is just neede for JSON SCHEMA TO WORK, As its not updated with latest TS jet. // eslint-disable-next-line @typescript-eslint/ban-ts-comment @@ -88,7 +27,7 @@ export class UmbWorkspaceActionMenuElement extends UmbLitElement { } override render() { - return this._items && this._items.length > 0 + return this.items?.length ? html` - ${this._items.length > 0 - ? repeat( - this._items, - (ext) => ext.alias, - (ext) => ext.component, - ) - : ''} + ${repeat( + this.items, + (ext) => ext.alias, + (ext) => ext.component, + )} @@ -120,7 +57,7 @@ export class UmbWorkspaceActionMenuElement extends UmbLitElement { : nothing; } - static override styles: CSSResultGroup = [ + static override styles = [ UmbTextStyles, css` :host { @@ -143,7 +80,6 @@ export class UmbWorkspaceActionMenuElement extends UmbLitElement { #popover-trigger { --uui-button-padding-top-factor: 0.5; --uui-button-padding-bottom-factor: 0.1; - --uui-button-border-radius: 0; } `, ]; diff --git a/src/packages/core/workspace/components/workspace-action/default/workspace-action.element.ts b/src/packages/core/workspace/components/workspace-action/default/workspace-action.element.ts index edbbe1afa3..242ed854e4 100644 --- a/src/packages/core/workspace/components/workspace-action/default/workspace-action.element.ts +++ b/src/packages/core/workspace/components/workspace-action/default/workspace-action.element.ts @@ -1,12 +1,18 @@ import type { UmbWorkspaceAction } from '../workspace-action.interface.js'; import { UmbActionExecutedEvent } from '@umbraco-cms/backoffice/event'; -import { html, customElement, property, state, ifDefined } from '@umbraco-cms/backoffice/external/lit'; +import { html, customElement, property, state, ifDefined, when } from '@umbraco-cms/backoffice/external/lit'; import type { UUIButtonState } from '@umbraco-cms/backoffice/external/uui'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; -import type { - ManifestWorkspaceAction, - MetaWorkspaceActionDefaultKind, +import { + umbExtensionsRegistry, + type ManifestWorkspaceAction, + type ManifestWorkspaceActionMenuItem, + type MetaWorkspaceActionDefaultKind, } from '@umbraco-cms/backoffice/extension-registry'; +import { + type UmbExtensionElementAndApiInitializer, + UmbExtensionsElementAndApiInitializer, +} from '@umbraco-cms/backoffice/extension-api'; import '../../workspace-action-menu/index.js'; @@ -17,13 +23,15 @@ export class UmbWorkspaceActionElement< > extends UmbLitElement { #manifest?: ManifestWorkspaceAction; #api?: ApiType; + #extensionsController?: UmbExtensionsElementAndApiInitializer< + ManifestWorkspaceActionMenuItem, + 'workspaceActionMenuItem', + ManifestWorkspaceActionMenuItem + >; @state() private _buttonState?: UUIButtonState; - @state() - private _aliases: Array = []; - @state() _href?: string; @@ -60,6 +68,9 @@ export class UmbWorkspaceActionElement< return this.#api; } + @state() + private _items: Array> = []; + /** * Create a list of original and overwritten aliases of workspace actions for the action. */ @@ -77,7 +88,8 @@ export class UmbWorkspaceActionElement< } } } - this._aliases = Array.from(aliases); + + this.#observeExtensions(Array.from(aliases)); } private async _onClick(event: MouseEvent) { @@ -108,27 +120,61 @@ export class UmbWorkspaceActionElement< ); } - override render() { + #observeExtensions(aliases: string[]): void { + this.#extensionsController?.destroy(); + this.#extensionsController = new UmbExtensionsElementAndApiInitializer< + ManifestWorkspaceActionMenuItem, + 'workspaceActionMenuItem', + ManifestWorkspaceActionMenuItem + >( + this, + umbExtensionsRegistry, + 'workspaceActionMenuItem', + ExtensionApiArgsMethod, + (action) => { + return Array.isArray(action.forWorkspaceActions) + ? action.forWorkspaceActions.some((alias) => aliases.includes(alias)) + : aliases.includes(action.forWorkspaceActions); + }, + (extensionControllers) => { + this._items = extensionControllers; + }, + undefined, // We can leave the alias to undefined, as we destroy this our selfs. + ); + } + + #renderButton() { return html` - - - - + `; } + + #renderActionMenu() { + return html` + + `; + } + + override render() { + return when( + this._items.length, + () => html` ${this.#renderButton()} ${this.#renderActionMenu()} `, + () => this.#renderButton(), + ); + } } export default UmbWorkspaceActionElement; @@ -138,3 +184,7 @@ declare global { 'umb-workspace-action': UmbWorkspaceActionElement; } } + +function ExtensionApiArgsMethod(manifest: ManifestWorkspaceActionMenuItem) { + return [{ meta: manifest.meta }]; +}