Merge branch 'feature/entity-action-kind' of https://github.com/umbraco/Umbraco.CMS.Backoffice into feature/entity-action-kind

This commit is contained in:
Mads Rasmussen
2024-03-03 19:57:25 +01:00
5 changed files with 58 additions and 88 deletions

View File

@@ -1,3 +1,4 @@
import type { UmbEntityActionArgs } from './types.js';
import { html, customElement, property, state, css } from '@umbraco-cms/backoffice/external/lit';
import type { ManifestEntityAction } from '@umbraco-cms/backoffice/extension-registry';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
@@ -5,32 +6,42 @@ import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
@customElement('umb-entity-action-list')
export class UmbEntityActionListElement extends UmbLitElement {
@property({ type: String, attribute: 'entity-type' })
public get entityType(): string {
return this._entityType;
public get entityType(): string | undefined {
return this._props.entityType;
}
public set entityType(value: string) {
if (value === this._entityType) return;
this._entityType = value;
public set entityType(value: string | undefined) {
if (value === undefined || value === this._props.entityType) return;
this._props.entityType = value;
const oldValue = this._filter;
this._filter = (extension: ManifestEntityAction) => extension.meta.entityTypes.includes(this.entityType);
this._filter = (extension: ManifestEntityAction<unknown>) => extension.meta.entityTypes.includes(value);
this.requestUpdate('_filter', oldValue);
this.requestUpdate('_props');
}
private _entityType: string = '';
@state()
_filter?: (extension: ManifestEntityAction) => boolean;
_filter?: (extension: ManifestEntityAction<unknown>) => boolean;
@property({ type: String })
public unique?: string | null;
public get unique(): string | null | undefined {
return this._props.unique;
}
public set unique(value: string | null | undefined) {
this._props.unique = value;
this.requestUpdate('_props');
}
@state()
_props: Partial<UmbEntityActionArgs<unknown>> = {};
render() {
return this._filter
? html`
<umb-extension-slot
<umb-extension-with-api-slot
type="entityAction"
default-element="umb-entity-action"
.filter=${this._filter}
.props=${{ unique: this.unique, entityType: this.entityType }}></umb-extension-slot>
.props=${this._props}
.apiArgs=${[this._props]}></umb-extension-with-api-slot>
`
: '';
}

View File

@@ -1,86 +1,44 @@
import type { UmbEntityAction } from './entity-action.interface.js';
import { UmbActionExecutedEvent } from '@umbraco-cms/backoffice/event';
import { html, nothing, ifDefined, customElement, property, state } from '@umbraco-cms/backoffice/external/lit';
import type { UUIMenuItemEvent } from '@umbraco-cms/backoffice/external/uui';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import type { ManifestEntityAction } from '@umbraco-cms/backoffice/extension-registry';
import { createExtensionApi } from '@umbraco-cms/backoffice/extension-api';
@customElement('umb-entity-action')
export class UmbEntityActionElement extends UmbLitElement {
#entityType?: string | null;
export class UmbEntityActionElement<
ArgsMetaType extends object = object,
ApiType extends UmbEntityAction<ArgsMetaType> = UmbEntityAction<ArgsMetaType>,
> extends UmbLitElement {
#api?: ApiType;
@property({ type: String })
public set entityType(value: string | undefined | null) {
const oldValue = this.#entityType;
this.#entityType = value;
if (oldValue !== this.#entityType) {
this.#createApi();
this.requestUpdate('entityType', oldValue);
}
}
public get entityType() {
return this.#entityType;
}
#unique?: string | null;
entityType?: string | null;
@property({ type: String })
public set unique(value: string | undefined | null) {
const oldValue = this.#unique;
this.#unique = value;
if (oldValue !== this.#unique) {
this.#createApi();
this.requestUpdate('unique', oldValue);
}
}
public get unique() {
return this.#unique;
}
public unique?: string | null;
#manifest?: ManifestEntityAction;
@property({ attribute: false })
public manifest?: ManifestEntityAction<ArgsMetaType>;
@property({ type: Object, attribute: false })
public set manifest(value: ManifestEntityAction | undefined) {
if (!value) return;
const oldValue = this.#manifest;
this.#manifest = value;
if (oldValue !== this.#manifest) {
this.#createApi();
this.requestUpdate('manifest', oldValue);
}
}
public get manifest() {
return this.#manifest;
}
async #createApi() {
// only create the api if we have all the required properties
if (!this.#manifest) return;
if (this.#unique === undefined) return;
if (!this.#entityType) return;
this.#api = await createExtensionApi(this.#manifest, [
this,
{
entityType: this.#entityType,
unique: this.#unique,
meta: this.#manifest.meta,
},
]);
@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._href = await this.#api.getHref?.();
this.#api?.getHref?.().then((href) => {
this._href = href;
// TODO: Do we need to update the component here? [NL]
});
}
#api: any;
@state()
_href?: string;
async #onClickLabel(event: UUIMenuItemEvent) {
if (!this._href) {
event.stopPropagation();
await this.#api.execute();
await this.#api?.execute();
}
this.dispatchEvent(new UmbActionExecutedEvent());
}

View File

@@ -9,9 +9,9 @@ import type { UmbAction } from '@umbraco-cms/backoffice/action';
export interface UmbEntityAction<ArgsMetaType> extends UmbAction<UmbEntityActionArgs<ArgsMetaType>> {
/**
* The href location, the action will act as a link.
* @returns {Promise<string | null | undefined>}
* @returns {Promise<string | undefined>}
*/
getHref(): Promise<string | null | undefined>;
getHref(): Promise<string | undefined>;
/**
* The `execute` method, the action will act as a button.

View File

@@ -1,6 +1,7 @@
export * from './common/index.js';
export * from './entity-action-base.js';
export * from './entity-action-list.element.js';
export * from './entity-action.element.js';
export * from './entity-action-base.js';
export * from './common/index.js';
export * from './entity-action.event.js';
export * from './entity-action.interface.js';
export * from './types.js';

View File

@@ -1,3 +1,5 @@
import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
import type { UmbEntityAction } from '@umbraco-cms/backoffice/entity-action';
import type { ManifestElementAndApi, ManifestWithDynamicConditions } from '@umbraco-cms/backoffice/extension-api';
/**
@@ -5,9 +7,11 @@ import type { ManifestElementAndApi, ManifestWithDynamicConditions } from '@umbr
* For example for content you may wish to create a new document etc
*/
// TODO: create interface for API
export interface ManifestEntityAction extends ManifestElementAndApi, ManifestWithDynamicConditions {
export interface ManifestEntityAction<MetaType extends MetaEntityAction>
extends ManifestElementAndApi<UmbControllerHostElement, UmbEntityAction<MetaType>>,
ManifestWithDynamicConditions {
type: 'entityAction';
meta: MetaEntityAction;
meta: MetaType;
}
export interface MetaEntityAction {
@@ -35,10 +39,9 @@ export interface MetaEntityAction {
}
// DELETE
export interface ManifestEntityActionDeleteKind extends ManifestEntityAction {
export interface ManifestEntityActionDeleteKind extends ManifestEntityAction<MetaEntityActionDeleteKind> {
type: 'entityAction';
kind: 'delete';
meta: MetaEntityActionDeleteKind;
}
export interface MetaEntityActionDeleteKind extends MetaEntityAction {
@@ -47,10 +50,9 @@ export interface MetaEntityActionDeleteKind extends MetaEntityAction {
}
// RENAME
export interface ManifestEntityActionRenameKind extends ManifestEntityAction {
export interface ManifestEntityActionRenameKind extends ManifestEntityAction<MetaEntityActionRenameKind> {
type: 'entityAction';
kind: 'rename';
meta: MetaEntityActionRenameKind;
}
export interface MetaEntityActionRenameKind extends MetaEntityAction {
@@ -59,19 +61,18 @@ export interface MetaEntityActionRenameKind extends MetaEntityAction {
}
// RELOAD TREE ITEM CHILDREN
export interface ManifestEntityActionReloadTreeItemChildrenKind extends ManifestEntityAction {
export interface ManifestEntityActionReloadTreeItemChildrenKind
extends ManifestEntityAction<MetaEntityActionRenameKind> {
type: 'entityAction';
kind: 'reloadTreeItemChildren';
meta: MetaEntityActionRenameKind;
}
export interface MetaEntityActionReloadTreeItemChildrenKind extends MetaEntityAction {}
// DUPLICATE
export interface ManifestEntityActionDuplicateKind extends ManifestEntityAction {
export interface ManifestEntityActionDuplicateKind extends ManifestEntityAction<MetaEntityActionDuplicateKind> {
type: 'entityAction';
kind: 'duplicate';
meta: MetaEntityActionDuplicateKind;
}
export interface MetaEntityActionDuplicateKind extends MetaEntityAction {
@@ -82,14 +83,13 @@ export interface MetaEntityActionDuplicateKind extends MetaEntityAction {
// MOVE
export interface ManifestEntityActionMoveKind extends ManifestEntityAction {
export interface ManifestEntityActionMoveKind extends ManifestEntityAction<MetaEntityActionMoveKind> {
type: 'entityAction';
kind: 'move';
meta: MetaEntityActionMoveKind;
}
export interface MetaEntityActionMoveKind extends MetaEntityAction {
itemRepositoryAlias: string;
moveRepositoryAlias: string;
itemRepositoryAlias: string;
pickerModalAlias: string;
}