Merge pull request #1358 from umbraco/feature/property-action-refactor
refactor property actions
This commit is contained in:
@@ -122,7 +122,7 @@ export class UmbExtensionElementAndApiInitializer<
|
||||
|
||||
// TODO: we could optimize this so we only re-set the updated props.
|
||||
Object.keys(this.#apiProps).forEach((key) => {
|
||||
(this.#component as any)[key] = this.#apiProps![key];
|
||||
(this.#api as any)[key] = this.#apiProps![key];
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ import type { ManifestMenu } from './menu.model.js';
|
||||
import type { ManifestMenuItem, ManifestMenuItemTreeKind } from './menu-item.model.js';
|
||||
import type { ManifestModal } from './modal.model.js';
|
||||
import type { ManifestPackageView } from './package-view.model.js';
|
||||
import type { ManifestPropertyAction } from './property-action.model.js';
|
||||
import type { ManifestPropertyAction, ManifestPropertyActionDefaultKind } from './property-action.model.js';
|
||||
import type { ManifestPropertyEditorUi, ManifestPropertyEditorSchema } from './property-editor.model.js';
|
||||
import type { ManifestRepository } from './repository.model.js';
|
||||
import type { ManifestSection } from './section.model.js';
|
||||
@@ -109,6 +109,8 @@ export type ManifestEntityActions =
|
||||
|
||||
export type ManifestWorkspaceActions = ManifestWorkspaceAction | ManifestWorkspaceActionDefaultKind;
|
||||
|
||||
export type ManifestPropertyActions = ManifestPropertyAction | ManifestPropertyActionDefaultKind;
|
||||
|
||||
export type ManifestTypes =
|
||||
| ManifestBundle<ManifestTypes>
|
||||
| ManifestCondition
|
||||
@@ -134,7 +136,7 @@ export type ManifestTypes =
|
||||
| ManifestMenuItemTreeKind
|
||||
| ManifestModal
|
||||
| ManifestPackageView
|
||||
| ManifestPropertyAction
|
||||
| ManifestPropertyActions
|
||||
| ManifestPropertyEditorSchema
|
||||
| ManifestPropertyEditorUi
|
||||
| ManifestRepository
|
||||
|
||||
@@ -1,13 +1,43 @@
|
||||
import type { ConditionTypes } from '../conditions/types.js';
|
||||
import type { ManifestElement, ManifestWithDynamicConditions } from '@umbraco-cms/backoffice/extension-api';
|
||||
import type { UmbPropertyAction } from '../../property-action/components/property-action/property-action.interface.js';
|
||||
import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
|
||||
import type { ManifestElementAndApi, ManifestWithDynamicConditions } from '@umbraco-cms/backoffice/extension-api';
|
||||
|
||||
export interface ManifestPropertyAction
|
||||
extends ManifestElement<HTMLElement>,
|
||||
export interface ManifestPropertyAction<MetaType extends MetaPropertyAction = MetaPropertyAction>
|
||||
extends ManifestElementAndApi<UmbControllerHostElement, UmbPropertyAction<MetaType>>,
|
||||
ManifestWithDynamicConditions<ConditionTypes> {
|
||||
type: 'propertyAction';
|
||||
meta: MetaPropertyAction;
|
||||
forPropertyEditorUis: string[];
|
||||
meta: MetaType;
|
||||
}
|
||||
|
||||
export interface MetaPropertyAction {
|
||||
propertyEditors: string[];
|
||||
export interface MetaPropertyAction {}
|
||||
|
||||
export interface ManifestPropertyActionDefaultKind<
|
||||
MetaType extends MetaPropertyActionDefaultKind = MetaPropertyActionDefaultKind,
|
||||
> extends ManifestPropertyAction<MetaType> {
|
||||
type: 'propertyAction';
|
||||
kind: 'default';
|
||||
}
|
||||
|
||||
export interface MetaPropertyActionDefaultKind extends MetaPropertyAction {
|
||||
/**
|
||||
* An icon to represent the action to be performed
|
||||
*
|
||||
* @examples [
|
||||
* "icon-box",
|
||||
* "icon-grid"
|
||||
* ]
|
||||
*/
|
||||
icon: string;
|
||||
|
||||
/**
|
||||
* The friendly name of the action to perform
|
||||
*
|
||||
* @examples [
|
||||
* "Create",
|
||||
* "Create Content Template"
|
||||
* ]
|
||||
*/
|
||||
label: string;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { ConditionTypes } from '../conditions/types.js';
|
||||
import type { UmbWorkspaceActionMenuItem } from '../../workspace/components/workspace-action-menu-item/workspace-action-menu-item.interface.js';
|
||||
import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
|
||||
import type { ManifestElementAndApi, ManifestWithDynamicConditions } from '@umbraco-cms/backoffice/extension-api';
|
||||
import type { UmbWorkspaceActionMenuItem } from '@umbraco-cms/backoffice/workspace';
|
||||
|
||||
export interface ManifestWorkspaceActionMenuItem<
|
||||
MetaType extends MetaWorkspaceActionMenuItem = MetaWorkspaceActionMenuItem,
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
import { UmbPropertyActionBase } from '../../components/property-action/property-action-base.controller.js';
|
||||
import { UMB_PROPERTY_CONTEXT } from '@umbraco-cms/backoffice/property';
|
||||
|
||||
export class UmbClearPropertyAction extends UmbPropertyActionBase {
|
||||
async execute() {
|
||||
const propertyContext = await this.getContext(UMB_PROPERTY_CONTEXT);
|
||||
propertyContext.clearValue();
|
||||
}
|
||||
}
|
||||
export default UmbClearPropertyAction;
|
||||
@@ -1,57 +0,0 @@
|
||||
import type { UmbPropertyAction } from '../../shared/property-action/property-action.interface.js';
|
||||
import type { UmbPropertyContext } from '@umbraco-cms/backoffice/property';
|
||||
import { UMB_PROPERTY_CONTEXT } from '@umbraco-cms/backoffice/property';
|
||||
import { html, customElement, property } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
|
||||
|
||||
@customElement('umb-property-action-clear')
|
||||
export class UmbPropertyActionClearElement extends UmbLitElement implements UmbPropertyAction {
|
||||
@property()
|
||||
value = '';
|
||||
|
||||
// THESE OUT COMMENTED CODE IS USED FOR THE EXAMPLE BELOW, TODO: Should be transferred to some documentation.
|
||||
//private _propertyActionMenuContext?: UmbPropertyActionMenuContext;
|
||||
private _propertyContext?: UmbPropertyContext;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
/*
|
||||
this.consumeContext('umbPropertyActionMenu', (propertyActionsContext: UmbPropertyActionMenuContext) => {
|
||||
this._propertyActionMenuContext = propertyActionsContext;
|
||||
});
|
||||
*/
|
||||
this.consumeContext(UMB_PROPERTY_CONTEXT, (propertyContext: UmbPropertyContext) => {
|
||||
this._propertyContext = propertyContext;
|
||||
});
|
||||
}
|
||||
|
||||
private _handleLabelClick() {
|
||||
this._clearValue();
|
||||
this.dispatchEvent(new CustomEvent('close', { bubbles: true, composed: true }));
|
||||
// Or you can do this:
|
||||
//this._propertyActionMenuContext?.close();
|
||||
}
|
||||
|
||||
private _clearValue() {
|
||||
// TODO: how do we want to update the value? Testing an event based approach. We need to test an api based approach too.
|
||||
//this.value = '';// This is though bad as it assumes we are dealing with a string. So wouldn't work as a generalized element.
|
||||
//this.dispatchEvent(new CustomEvent('property-value-change'));
|
||||
// Or you can do this:
|
||||
this._propertyContext?.resetValue(); // This resets value to what the property wants.
|
||||
}
|
||||
|
||||
render() {
|
||||
return html` <uui-menu-item label="Clear" @click-label="${this._handleLabelClick}">
|
||||
<uui-icon slot="icon" name="delete"></uui-icon>
|
||||
</uui-menu-item>`;
|
||||
}
|
||||
}
|
||||
|
||||
export default UmbPropertyActionClearElement;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'umb-property-action-clear': UmbPropertyActionClearElement;
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
import type { Meta, Story } from '@storybook/web-components';
|
||||
import type { UmbPropertyActionClearElement } from './property-action-clear.element.js';
|
||||
import { html } from '@umbraco-cms/backoffice/external/lit';
|
||||
|
||||
import './property-action-clear.element.js';
|
||||
|
||||
export default {
|
||||
title: 'Property Actions/Clear',
|
||||
component: 'umb-property-action-clear',
|
||||
id: 'umb-property-action-clear',
|
||||
} as Meta;
|
||||
|
||||
export const AAAOverview: Story<UmbPropertyActionClearElement> = () =>
|
||||
html` <umb-property-action-clear></umb-property-action-clear>`;
|
||||
AAAOverview.storyName = 'Overview';
|
||||
@@ -0,0 +1,16 @@
|
||||
import { UmbPropertyActionBase } from '../../components/property-action/property-action-base.controller.js';
|
||||
import { UMB_NOTIFICATION_CONTEXT, type UmbNotificationDefaultData } from '@umbraco-cms/backoffice/notification';
|
||||
import { UMB_PROPERTY_CONTEXT } from '@umbraco-cms/backoffice/property';
|
||||
|
||||
export class UmbCopyPropertyAction extends UmbPropertyActionBase {
|
||||
async execute() {
|
||||
const propertyContext = await this.getContext(UMB_PROPERTY_CONTEXT);
|
||||
const value = propertyContext.getValue();
|
||||
|
||||
const notificationContext = await this.getContext(UMB_NOTIFICATION_CONTEXT);
|
||||
// TODO: Temporary solution to make something happen: [NL]
|
||||
const data: UmbNotificationDefaultData = { headline: 'Copied to clipboard', message: value };
|
||||
notificationContext?.peek('positive', { data });
|
||||
}
|
||||
}
|
||||
export default UmbCopyPropertyAction;
|
||||
@@ -1,48 +0,0 @@
|
||||
import type { UmbPropertyAction } from '../../shared/property-action/property-action.interface.js';
|
||||
import { html, customElement, property } from '@umbraco-cms/backoffice/external/lit';
|
||||
import type { UmbNotificationDefaultData, UmbNotificationContext } from '@umbraco-cms/backoffice/notification';
|
||||
import { UMB_NOTIFICATION_CONTEXT } from '@umbraco-cms/backoffice/notification';
|
||||
//import { UMB_WORKSPACE_PROPERTY_CONTEXT } from '@umbraco-cms/backoffice/workspace';
|
||||
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
|
||||
|
||||
@customElement('umb-property-action-copy')
|
||||
export class UmbPropertyActionCopyElement extends UmbLitElement implements UmbPropertyAction {
|
||||
@property()
|
||||
value = '';
|
||||
|
||||
private _notificationContext?: UmbNotificationContext;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
//this.consumeContext(UMB_WORKSPACE_PROPERTY_CONTEXT, (property) => {
|
||||
//console.log('Got a reference to the editor element', property.getEditor());
|
||||
// Be aware that the element might switch, so using the direct reference is not recommended, instead observe the .element Observable()
|
||||
//});
|
||||
|
||||
this.consumeContext(UMB_NOTIFICATION_CONTEXT, (instance) => {
|
||||
this._notificationContext = instance;
|
||||
});
|
||||
}
|
||||
|
||||
private _handleLabelClick() {
|
||||
const data: UmbNotificationDefaultData = { message: 'Copied to clipboard' };
|
||||
this._notificationContext?.peek('positive', { data });
|
||||
// TODO: how do we want to close the menu? Testing an event based approach
|
||||
this.dispatchEvent(new CustomEvent('close', { bubbles: true, composed: true }));
|
||||
}
|
||||
|
||||
render() {
|
||||
return html` <uui-menu-item label="Copy" @click-label="${this._handleLabelClick}">
|
||||
<uui-icon slot="icon" name="copy"></uui-icon>
|
||||
</uui-menu-item>`;
|
||||
}
|
||||
}
|
||||
|
||||
export default UmbPropertyActionCopyElement;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'umb-property-action-copy': UmbPropertyActionCopyElement;
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
import type { Meta, Story } from '@storybook/web-components';
|
||||
import type { UmbPropertyActionCopyElement } from './property-action-copy.element.js';
|
||||
import { html } from '@umbraco-cms/backoffice/external/lit';
|
||||
|
||||
import './property-action-copy.element.js';
|
||||
|
||||
export default {
|
||||
title: 'Property Actions/Copy',
|
||||
component: 'umb-property-action-copy',
|
||||
id: 'umb-property-action-copy',
|
||||
} as Meta;
|
||||
|
||||
export const AAAOverview: Story<UmbPropertyActionCopyElement> = () =>
|
||||
html` <umb-property-action-copy></umb-property-action-copy>`;
|
||||
AAAOverview.storyName = 'Overview';
|
||||
@@ -1,39 +1,35 @@
|
||||
import type { UmbPropertyActionArgs } from '../property-action/types.js';
|
||||
import type { CSSResultGroup } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { css, html, customElement, property, state, repeat, nothing } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
|
||||
import type { ManifestPropertyAction, ManifestTypes } from '@umbraco-cms/backoffice/extension-registry';
|
||||
import type {
|
||||
ManifestPropertyAction,
|
||||
ManifestTypes,
|
||||
MetaPropertyAction,
|
||||
} from '@umbraco-cms/backoffice/extension-registry';
|
||||
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';
|
||||
import type { UmbExtensionElementInitializer } from '@umbraco-cms/backoffice/extension-api';
|
||||
import { UmbExtensionsElementInitializer } from '@umbraco-cms/backoffice/extension-api';
|
||||
import type { UmbExtensionElementAndApiInitializer } from '@umbraco-cms/backoffice/extension-api';
|
||||
import { UmbExtensionsElementAndApiInitializer } from '@umbraco-cms/backoffice/extension-api';
|
||||
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
|
||||
|
||||
function ExtensionApiArgsMethod(manifest: ManifestPropertyAction): [UmbPropertyActionArgs<MetaPropertyAction>] {
|
||||
return [{ meta: manifest.meta }];
|
||||
}
|
||||
@customElement('umb-property-action-menu')
|
||||
export class UmbPropertyActionMenuElement extends UmbLitElement {
|
||||
#actionsInitializer?: UmbExtensionsElementInitializer<ManifestTypes, 'propertyAction'>;
|
||||
#value: unknown;
|
||||
#actionsInitializer?: UmbExtensionsElementAndApiInitializer<ManifestTypes, 'propertyAction'>;
|
||||
#propertyEditorUiAlias = '';
|
||||
|
||||
@property({ attribute: false })
|
||||
public set value(value: unknown) {
|
||||
this.#value = value;
|
||||
if (this.#actionsInitializer) {
|
||||
this.#actionsInitializer.properties = { value };
|
||||
}
|
||||
}
|
||||
public get value(): unknown {
|
||||
return this.#value;
|
||||
}
|
||||
|
||||
@property()
|
||||
set propertyEditorUiAlias(alias: string) {
|
||||
this.#propertyEditorUiAlias = alias;
|
||||
// TODO: Stop using string for 'propertyAction', we need to start using Const.
|
||||
// TODO: Align property actions with entity actions.
|
||||
this.#actionsInitializer = new UmbExtensionsElementInitializer(
|
||||
// TODO: Stop using string for 'propertyAction', we need to start using Const. [NL]
|
||||
this.#actionsInitializer = new UmbExtensionsElementAndApiInitializer(
|
||||
this,
|
||||
umbExtensionsRegistry,
|
||||
'propertyAction',
|
||||
(propertyAction) => propertyAction.meta.propertyEditors.includes(alias),
|
||||
ExtensionApiArgsMethod,
|
||||
(propertyAction) => propertyAction.forPropertyEditorUis.includes(alias),
|
||||
(ctrls) => {
|
||||
this._actions = ctrls;
|
||||
},
|
||||
@@ -45,7 +41,7 @@ export class UmbPropertyActionMenuElement extends UmbLitElement {
|
||||
}
|
||||
|
||||
@state()
|
||||
private _actions: Array<UmbExtensionElementInitializer<ManifestPropertyAction, never>> = [];
|
||||
private _actions: Array<UmbExtensionElementAndApiInitializer<ManifestPropertyAction, never>> = [];
|
||||
|
||||
render() {
|
||||
return this._actions.length > 0
|
||||
@@ -54,13 +50,17 @@ export class UmbPropertyActionMenuElement extends UmbLitElement {
|
||||
id="popover-trigger"
|
||||
popovertarget="property-action-popover"
|
||||
look="secondary"
|
||||
label="More"
|
||||
label="Open actions menu"
|
||||
compact>
|
||||
<uui-symbol-more id="more-symbol"></uui-symbol-more>
|
||||
</uui-button>
|
||||
<uui-popover-container id="property-action-popover">
|
||||
<umb-popover-layout>
|
||||
<div id="dropdown">${repeat(this._actions, (action) => action.component)}</div>
|
||||
${repeat(
|
||||
this._actions,
|
||||
(action) => action.alias,
|
||||
(action) => action.component,
|
||||
)}
|
||||
</umb-popover-layout>
|
||||
</uui-popover-container>
|
||||
`
|
||||
@@ -0,0 +1,18 @@
|
||||
import type { UmbBackofficeManifestKind } from '@umbraco-cms/backoffice/extension-registry';
|
||||
|
||||
export const manifest: UmbBackofficeManifestKind = {
|
||||
type: 'kind',
|
||||
alias: 'Umb.Kind.PropertyAction.Default',
|
||||
matchKind: 'default',
|
||||
matchType: 'propertyAction',
|
||||
manifest: {
|
||||
type: 'propertyAction',
|
||||
kind: 'default',
|
||||
weight: 1000,
|
||||
element: () => import('./property-action.element.js'),
|
||||
meta: {
|
||||
icon: 'icon-bug',
|
||||
label: '(Missing label in manifest)',
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,3 @@
|
||||
import { manifest as defaultKindManifest } from './default.action.kind.js';
|
||||
|
||||
export const manifests = [defaultKindManifest];
|
||||
@@ -0,0 +1,70 @@
|
||||
import type { UmbPropertyAction } from '../index.js';
|
||||
import { UmbActionExecutedEvent } from '@umbraco-cms/backoffice/event';
|
||||
import { html, customElement, property, state, ifDefined, nothing } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
|
||||
import type {
|
||||
ManifestPropertyActionDefaultKind,
|
||||
MetaPropertyActionDefaultKind,
|
||||
} from '@umbraco-cms/backoffice/extension-registry';
|
||||
import type { UUIMenuItemEvent } from '@umbraco-cms/backoffice/external/uui';
|
||||
|
||||
@customElement('umb-property-action')
|
||||
export class UmbPropertyActionElement<
|
||||
MetaType extends MetaPropertyActionDefaultKind = MetaPropertyActionDefaultKind,
|
||||
ApiType extends UmbPropertyAction<MetaType> = UmbPropertyAction<MetaType>,
|
||||
> extends UmbLitElement {
|
||||
#api?: ApiType;
|
||||
|
||||
@state()
|
||||
_href?: string;
|
||||
|
||||
@property({ attribute: false })
|
||||
public manifest?: ManifestPropertyActionDefaultKind<MetaType>;
|
||||
|
||||
@property({ attribute: false })
|
||||
public set api(api: ApiType | undefined) {
|
||||
this.#api = api;
|
||||
|
||||
// TODO: Fix so when we use a HREF it does not refresh the page?
|
||||
this.#api?.getHref?.().then((href) => {
|
||||
this._href = href;
|
||||
// TODO: Do we need to update the component here? [NL]
|
||||
});
|
||||
}
|
||||
|
||||
async #onClickLabel(event: UUIMenuItemEvent) {
|
||||
if (!this._href) {
|
||||
event.stopPropagation();
|
||||
await this.#api?.execute();
|
||||
}
|
||||
this.dispatchEvent(new UmbActionExecutedEvent());
|
||||
}
|
||||
|
||||
// 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)}
|
||||
href=${ifDefined(this._href)}
|
||||
@click-label=${this.#onClickLabel}
|
||||
@click=${this.#onClick}>
|
||||
${this.manifest?.meta.icon
|
||||
? html`<umb-icon slot="icon" name="${this.manifest?.meta.icon}"></umb-icon>`
|
||||
: nothing}
|
||||
</uui-menu-item>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
export default UmbPropertyActionElement;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'umb-property-action': UmbPropertyActionElement;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
import { manifests as defaultWorkspaceActionManifests } from './default/manifests.js';
|
||||
|
||||
export const manifests = [...defaultWorkspaceActionManifests];
|
||||
@@ -0,0 +1,35 @@
|
||||
import type { UmbPropertyActionArgs } from './types.js';
|
||||
import type { UmbPropertyAction } from './property-action.interface.js';
|
||||
import { UmbActionBase } from '@umbraco-cms/backoffice/action';
|
||||
|
||||
/**
|
||||
* Base class for an property action.
|
||||
* @export
|
||||
* @abstract
|
||||
* @class UmbPropertyActionBase
|
||||
* @extends {UmbActionBase}
|
||||
* @implements {UmbPropertyAction}
|
||||
*/
|
||||
export abstract class UmbPropertyActionBase<ArgsMetaType = never>
|
||||
extends UmbActionBase<UmbPropertyActionArgs<ArgsMetaType>>
|
||||
implements UmbPropertyAction<ArgsMetaType>
|
||||
{
|
||||
/**
|
||||
* By specifying the href, the action will act as a link.
|
||||
* The `execute` method will not be called.
|
||||
* @abstract
|
||||
* @returns {string | undefined}
|
||||
*/
|
||||
public getHref(): Promise<string | undefined> {
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
/**
|
||||
* By specifying the `execute` method, the action will act as a button.
|
||||
* @abstract
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
public execute(): Promise<void> {
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import type { UmbPropertyActionArgs } from './types.js';
|
||||
import type { UmbAction } from '@umbraco-cms/backoffice/action';
|
||||
|
||||
export interface UmbPropertyAction<ArgsMetaType = never> extends UmbAction<UmbPropertyActionArgs<ArgsMetaType>> {
|
||||
/**
|
||||
* The href location, the action will act as a link.
|
||||
* @returns {Promise<string | undefined>}
|
||||
*/
|
||||
getHref(): Promise<string | undefined>;
|
||||
|
||||
/**
|
||||
* The `execute` method, the action will act as a button.
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
execute(): Promise<void>;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export interface UmbPropertyActionArgs<MetaArgsType> {
|
||||
meta: MetaArgsType;
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
export * from './shared/index.js';
|
||||
export * from './components/index.js';
|
||||
|
||||
@@ -1,22 +1,31 @@
|
||||
import type { ManifestPropertyAction } from '@umbraco-cms/backoffice/extension-registry';
|
||||
import { manifests as defaultManifests } from './components/property-action/manifests.js';
|
||||
import type { ManifestPropertyActions } from '@umbraco-cms/backoffice/extension-registry';
|
||||
|
||||
export const manifests: Array<ManifestPropertyAction> = [
|
||||
export const propertyActionManifests: Array<ManifestPropertyActions> = [
|
||||
{
|
||||
type: 'propertyAction',
|
||||
kind: 'default',
|
||||
alias: 'Umb.PropertyAction.Copy',
|
||||
name: 'Copy Property Action',
|
||||
js: () => import('./common/copy/property-action-copy.element.js'),
|
||||
api: () => import('./common/copy/property-action-copy.controller.js'),
|
||||
forPropertyEditorUis: ['Umb.PropertyEditorUi.TextBox'],
|
||||
meta: {
|
||||
propertyEditors: ['Umb.PropertyEditorUi.TextBox'],
|
||||
icon: 'icon-paste-in',
|
||||
label: 'Copy',
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'propertyAction',
|
||||
kind: 'default',
|
||||
alias: 'Umb.PropertyAction.Clear',
|
||||
name: 'Clear Property Action',
|
||||
js: () => import('./common/clear/property-action-clear.element.js'),
|
||||
api: () => import('./common/clear/property-action-clear.controller.js'),
|
||||
forPropertyEditorUis: ['Umb.PropertyEditorUi.TextBox'],
|
||||
meta: {
|
||||
propertyEditors: ['Umb.PropertyEditorUi.TextBox'],
|
||||
icon: 'icon-trash',
|
||||
label: 'Clear',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
export const manifests = [...defaultManifests, ...propertyActionManifests];
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
export interface UmbPropertyAction extends HTMLElement {
|
||||
value?: unknown;
|
||||
}
|
||||
@@ -156,6 +156,9 @@ export class UmbPropertyContext<ValueType = any> extends UmbControllerBase {
|
||||
}
|
||||
|
||||
public resetValue(): void {
|
||||
this.setValue(undefined); // TODO: We should get the value from the server aka. the value from the persisted data.
|
||||
}
|
||||
public clearValue(): void {
|
||||
this.setValue(undefined); // TODO: We should get the default value from Property Editor maybe even later the DocumentType, as that would hold the default value for the property.
|
||||
}
|
||||
|
||||
|
||||
@@ -220,8 +220,7 @@ export class UmbPropertyElement extends UmbLitElement {
|
||||
? html`<umb-property-action-menu
|
||||
slot="action-menu"
|
||||
id="action-menu"
|
||||
.propertyEditorUiAlias=${this._propertyEditorUiAlias}
|
||||
.value=${this._value}></umb-property-action-menu>`
|
||||
.propertyEditorUiAlias=${this._propertyEditorUiAlias}></umb-property-action-menu>`
|
||||
: ''}`;
|
||||
}
|
||||
|
||||
@@ -238,6 +237,7 @@ export class UmbPropertyElement extends UmbLitElement {
|
||||
|
||||
#action-menu {
|
||||
opacity: 0;
|
||||
transition: opacity 90ms;
|
||||
}
|
||||
|
||||
#layout:focus-within #action-menu,
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { UmbBackofficeManifestKind } from '@umbraco-cms/backoffice/extensio
|
||||
|
||||
export const manifest: UmbBackofficeManifestKind = {
|
||||
type: 'kind',
|
||||
alias: 'Umb.Kind.WorkspaceAction.Default',
|
||||
alias: 'Umb.Kind.WorkspaceActionMenuItem.Default',
|
||||
matchKind: 'default',
|
||||
matchType: 'workspaceActionMenuItem',
|
||||
manifest: {
|
||||
|
||||
@@ -86,11 +86,6 @@ export class UmbWorkspaceActionMenuElement extends UmbLitElement {
|
||||
this._popoverOpen = event.newState === 'open';
|
||||
}
|
||||
|
||||
#onActionExecuted(event: MouseEvent) {
|
||||
// TODO: Explicit close the popover?
|
||||
// Should we stop the event as well?
|
||||
}
|
||||
|
||||
render() {
|
||||
return this._items && this._items.length > 0
|
||||
? html`
|
||||
@@ -105,7 +100,7 @@ export class UmbWorkspaceActionMenuElement extends UmbLitElement {
|
||||
</uui-button>
|
||||
<uui-popover-container
|
||||
id="workspace-action-popover"
|
||||
margin="5"
|
||||
margin="6"
|
||||
placement="top-end"
|
||||
@toggle=${this.#onPopoverToggle}>
|
||||
<umb-popover-layout>
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
export interface UmbWorkspaceActionArgs<MetaArgsType> {
|
||||
entityType: string;
|
||||
unique: string | null;
|
||||
meta: MetaArgsType;
|
||||
}
|
||||
|
||||
@@ -6,8 +6,11 @@ import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
|
||||
import type { UmbModalContext } from '@umbraco-cms/backoffice/modal';
|
||||
import { UMB_MODAL_CONTEXT } from '@umbraco-cms/backoffice/modal';
|
||||
import type { ManifestWorkspaceAction, MetaWorkspaceAction } from '@umbraco-cms/backoffice/extension-registry';
|
||||
import type { UmbWorkspaceActionArgs } from '@umbraco-cms/backoffice/workspace';
|
||||
|
||||
function ExtensionApiArgsMethod(manifest: ManifestWorkspaceAction<MetaWorkspaceAction>) {
|
||||
function ExtensionApiArgsMethod(
|
||||
manifest: ManifestWorkspaceAction<MetaWorkspaceAction>,
|
||||
): [UmbWorkspaceActionArgs<MetaWorkspaceAction>] {
|
||||
return [{ meta: manifest.meta }];
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user