diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-actions/document-trash.entity-action.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-actions/document-trash.entity-action.ts index 9fc01de4f5..b0fbd7eb35 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-actions/document-trash.entity-action.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-actions/document-trash.entity-action.ts @@ -12,7 +12,7 @@ export class TrashDocumentEntityAction { constructor(host: UmbControllerHostInterface, key: string) { this.#host = host; this.#key = key; - this.#documentRepository = new UmbDocumentRepository(this.#host); + this.#documentRepository = new UmbDocumentRepository(this.#host); // TODO: make repository injectable new UmbContextConsumerController(this.#host, UMB_MODAL_SERVICE_CONTEXT_TOKEN, (instance) => { this.#modalService = instance; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/document-workspace.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/document-workspace.element.ts index e57cb8fb9f..e3d635ef3f 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/document-workspace.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/document-workspace.element.ts @@ -1,6 +1,6 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import { css, html } from 'lit'; -import { customElement, property } from 'lit/decorators.js'; +import { css, html, nothing } from 'lit'; +import { customElement, property, state } from 'lit/decorators.js'; import type { UmbWorkspaceEntityElement } from '../../../shared/components/workspace/workspace-entity-element.interface'; import { UmbDocumentWorkspaceContext } from './document-workspace.context'; import { UmbLitElement } from '@umbraco-cms/element'; @@ -20,8 +20,12 @@ export class UmbDocumentWorkspaceElement extends UmbLitElement implements UmbWor private _workspaceContext: UmbDocumentWorkspaceContext = new UmbDocumentWorkspaceContext(this); + @state() + _unique?: string; + public load(entityKey: string) { this._workspaceContext.load(entityKey); + this._unique = entityKey; } public create(parentKey: string | null) { @@ -29,7 +33,16 @@ export class UmbDocumentWorkspaceElement extends UmbLitElement implements UmbWor } render() { - return html``; + return html` + ${this._unique + ? html` + + ` + : nothing} + `; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/entity-actions/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/entity-actions/manifests.ts new file mode 100644 index 0000000000..7db0c24aa0 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/entity-actions/manifests.ts @@ -0,0 +1,18 @@ +import { TrashMediaEntityAction } from './trash-media.entity-action'; +import { ManifestEntityAction } from 'libs/extensions-registry/entity-action.models'; + +const entityActions: Array = [ + { + type: 'entityAction', + alias: 'Umb.EntityAction.Media.Trash', + name: 'Trash Media Entity Action ', + meta: { + entityType: 'media', + icon: 'umb:trash', + label: 'Trash', + api: TrashMediaEntityAction, + }, + }, +]; + +export const manifests = [...entityActions]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/entity-actions/trash-media.entity-action.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/entity-actions/trash-media.entity-action.ts new file mode 100644 index 0000000000..95df7ca65e --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/entity-actions/trash-media.entity-action.ts @@ -0,0 +1,15 @@ +import { UmbControllerHostInterface } from '@umbraco-cms/controller'; + +export class TrashMediaEntityAction { + #host: UmbControllerHostInterface; + #key: string; + + constructor(host: UmbControllerHostInterface, key: string) { + this.#host = host; + this.#key = key; + } + + async execute() { + alert('trash media'); + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/manifests.ts index a4edc8b4f1..978a3ce42b 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/manifests.ts @@ -1,5 +1,11 @@ import { manifests as sidebarMenuItemManifests } from './sidebar-menu-item/manifests'; import { manifests as treeManifests } from './tree/manifests'; import { manifests as workspaceManifests } from './workspace/manifests'; +import { manifests as entityActionsManifests } from './entity-actions/manifests'; -export const manifests = [...sidebarMenuItemManifests, ...treeManifests, ...workspaceManifests]; +export const manifests = [ + ...sidebarMenuItemManifests, + ...treeManifests, + ...workspaceManifests, + ...entityActionsManifests, +]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/index.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/index.ts index d4aaf7fac5..294ce752e2 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/index.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/index.ts @@ -14,3 +14,4 @@ import './section/section-sidebar/section-sidebar.element'; import './section/section.element'; import './tree/tree.element'; import './workspace/workspace-content/workspace-content.element'; +import './workspace/workspace-action-menu/workspace-action-menu.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-action-menu/workspace-action-menu.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-action-menu/workspace-action-menu.element.ts new file mode 100644 index 0000000000..3880305334 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-action-menu/workspace-action-menu.element.ts @@ -0,0 +1,88 @@ +import { UUITextStyles } from '@umbraco-ui/uui-css'; +import { css, html } from 'lit'; +import { customElement, property, state } from 'lit/decorators.js'; +import { UmbLitElement } from '@umbraco-cms/element'; +import { umbExtensionsRegistry } from '@umbraco-cms/extensions-api'; +import { ManifestEntityAction } from 'libs/extensions-registry/entity-action.models'; + +@customElement('umb-workspace-action-menu') +export class UmbWorkspaceActionMenuElement extends UmbLitElement { + static styles = [ + UUITextStyles, + 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; + } + `, + ]; + + 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); + } + } + + @state() + private _entityActions?: Array; + + @state() + private _actionMenuIsOpen = false; + + #observeEntityActions() { + // TODO: filter on entity type + this.observe(umbExtensionsRegistry.extensionsOfType('entityAction'), (actions) => { + this._entityActions = actions; + }); + } + + #close() { + this._actionMenuIsOpen = false; + } + + #open() { + this._actionMenuIsOpen = true; + } + + render() { + return html` ${this.#renderActionsMenu()} `; + } + + #renderActionsMenu() { + return html` + + +
+ + ${this._entityActions?.map((manifest) => html``)} + +
+
+ `; + } +} + +declare global { + interface HTMLElementTagNameMap { + 'umb-workspace-action-menu': UmbWorkspaceActionMenuElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-content/workspace-content.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-content/workspace-content.element.ts index 49de100c77..56b7a21a89 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-content/workspace-content.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-content/workspace-content.element.ts @@ -1,6 +1,6 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, html } from 'lit'; -import { customElement, property } from 'lit/decorators.js'; +import { customElement, property, state } from 'lit/decorators.js'; import '../workspace-layout/workspace-layout.element'; import '../../variant-selector/variant-selector.element'; @@ -11,6 +11,8 @@ import './views/edit/workspace-view-content-edit.element'; import './views/info/workspace-view-content-info.element'; import { UmbLitElement } from '@umbraco-cms/element'; +import '../entity-action.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) @@ -43,16 +45,15 @@ export class UmbWorkspaceContentElement extends UmbLitElement { @property() alias!: string; - @property({ type: String, attribute: 'entity-type' }) - public entityType = ''; - render() { 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 c585c09ca6..6986763e9d 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 @@ -16,9 +16,6 @@ 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,39 +58,9 @@ export class UmbWorkspaceLayout extends UmbLitElement { display: flex; gap: var(--uui-size-space-2); } - - #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; - } `, ]; - 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 = ''; @@ -130,15 +97,6 @@ export class UmbWorkspaceLayout extends UmbLitElement { @state() private _activePath?: string; - @state() - private _entityActions?: Array; - - #observeEntityActions() { - this.observe(umbExtensionsRegistry.extensionsOfType('entityAction'), (actions) => { - this._entityActions = actions; - }); - } - private _observeWorkspaceViews() { this.observe( umbExtensionsRegistry @@ -188,7 +146,8 @@ export class UmbWorkspaceLayout extends UmbLitElement { return html` - ${this.#renderTabs()} ${this.#renderActionsMenu()} + ${this.#renderTabs()} + - - -
- - ${this._entityActions?.map((manifest) => html``)} - -
-
- - `; - } } declare global {