Skip to content

Commit 3d84003

Browse files
authored
Feature: workspace action additional options ellipsis (#18299)
* adding types and default kind element * switch to use ?? for code consistency * add data-mark * move listener last * fix tsc * save action additionalOptions * hasAdditionalOptions for Save and Publish * remove unused import * type arg * rename to _retrieveWorkspaceContext
1 parent f906d28 commit 3d84003

File tree

18 files changed

+164
-93
lines changed

18 files changed

+164
-93
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export type * from './workspace-action/types.js';
2+
export type * from './workspace-action-menu-item/types.js';

src/Umbraco.Web.UI.Client/src/packages/core/workspace/components/workspace-action-menu-item/default/workspace-action-menu-item.element.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { UmbWorkspaceActionMenuItem } from '../index.js';
1+
import type { UmbWorkspaceActionMenuItem } from '../types.js';
22
import { UmbActionExecutedEvent } from '@umbraco-cms/backoffice/event';
33
import { html, customElement, property, state, ifDefined, nothing } from '@umbraco-cms/backoffice/external/lit';
44
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1 @@
11
export * from './workspace-action-menu-item-base.controller.js';
2-
export type * from './types.js';
3-
export type * from './workspace-action-menu-item.interface.js';
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
export type * from './workspace-action-menu-item.interface.js';
12
export interface UmbWorkspaceActionMenuItemArgs<MetaArgsType> {
23
meta: MetaArgsType;
34
}
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export * from './submit.action.js';
2+
export type * from './types.js';

src/Umbraco.Web.UI.Client/src/packages/core/workspace/components/workspace-action/common/submit/submit.action.ts

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,54 @@
1+
import type { MetaWorkspaceAction } from '../../../../types.js';
12
import { UMB_SUBMITTABLE_WORKSPACE_CONTEXT } from '../../../../contexts/tokens/index.js';
23
import type { UmbSubmittableWorkspaceContext } from '../../../../contexts/tokens/index.js';
3-
import type { UmbWorkspaceActionArgs } from '../../types.js';
44
import { UmbWorkspaceActionBase } from '../../workspace-action-base.controller.js';
5+
import type { UmbSubmitWorkspaceActionArgs } from './types.js';
56
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
67

7-
export class UmbSubmitWorkspaceAction extends UmbWorkspaceActionBase<UmbSubmittableWorkspaceContext> {
8-
#workspaceContext?: UmbSubmittableWorkspaceContext;
8+
export class UmbSubmitWorkspaceAction<
9+
ArgsMetaType extends MetaWorkspaceAction = MetaWorkspaceAction,
10+
WorkspaceContextType extends UmbSubmittableWorkspaceContext = UmbSubmittableWorkspaceContext,
11+
> extends UmbWorkspaceActionBase<ArgsMetaType> {
12+
protected _retrieveWorkspaceContext: Promise<unknown>;
13+
protected _workspaceContext?: WorkspaceContextType;
914

10-
constructor(host: UmbControllerHost, args: UmbWorkspaceActionArgs<UmbSubmittableWorkspaceContext>) {
15+
constructor(host: UmbControllerHost, args: UmbSubmitWorkspaceActionArgs<ArgsMetaType>) {
1116
super(host, args);
1217

13-
// TODO: Could we make change label depending on the state?
14-
this.consumeContext(UMB_SUBMITTABLE_WORKSPACE_CONTEXT, (context) => {
15-
this.#workspaceContext = context;
16-
this.#observeUnique();
17-
});
18+
// TODO: Could we make change label depending on the state? [NL]
19+
this._retrieveWorkspaceContext = this.consumeContext(
20+
args.workspaceContextToken ?? UMB_SUBMITTABLE_WORKSPACE_CONTEXT,
21+
(context) => {
22+
this._workspaceContext = context as WorkspaceContextType;
23+
this.#observeUnique();
24+
this._gotWorkspaceContext();
25+
},
26+
).asPromise();
1827
}
1928

2029
#observeUnique() {
2130
this.observe(
22-
this.#workspaceContext?.unique,
31+
this._workspaceContext?.unique,
2332
(unique) => {
2433
// We can't save if we don't have a unique
2534
if (unique === undefined) {
2635
this.disable();
2736
} else {
37+
// Dangerous, cause this could enable despite a class extension decided to disable it?. [NL]
2838
this.enable();
2939
}
3040
},
3141
'saveWorkspaceActionUniqueObserver',
3242
);
3343
}
3444

45+
protected _gotWorkspaceContext() {
46+
// Override in subclass
47+
}
48+
3549
override async execute() {
36-
const workspaceContext = await this.getContext(UMB_SUBMITTABLE_WORKSPACE_CONTEXT);
37-
return await workspaceContext.requestSubmit();
50+
await this._retrieveWorkspaceContext;
51+
return await this._workspaceContext!.requestSubmit();
3852
}
3953
}
4054

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import type { UmbWorkspaceActionArgs } from '../../types.js';
2+
import type { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
3+
import type { UmbSubmittableWorkspaceContext } from '@umbraco-cms/backoffice/workspace';
4+
5+
export interface UmbSubmitWorkspaceActionArgs<MetaArgsType> extends UmbWorkspaceActionArgs<MetaArgsType> {
6+
workspaceContextToken?: string | UmbContextToken<UmbSubmittableWorkspaceContext, UmbSubmittableWorkspaceContext>;
7+
}

src/Umbraco.Web.UI.Client/src/packages/core/workspace/components/workspace-action/default/default.action.kind.ts

Lines changed: 0 additions & 18 deletions
This file was deleted.
Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,19 @@
1-
import { manifest as defaultKindManifest } from './default.action.kind.js';
21
import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry';
32

4-
export const manifests: Array<UmbExtensionManifest | UmbExtensionManifestKind> = [defaultKindManifest];
3+
export const manifest: UmbExtensionManifestKind = {
4+
type: 'kind',
5+
alias: 'Umb.Kind.WorkspaceAction.Default',
6+
matchKind: 'default',
7+
matchType: 'workspaceAction',
8+
manifest: {
9+
type: 'workspaceAction',
10+
kind: 'default',
11+
weight: 1000,
12+
element: () => import('./workspace-action-default-kind.element.js'),
13+
meta: {
14+
label: '(Missing label in manifest)',
15+
},
16+
},
17+
};
18+
19+
export const manifests: Array<UmbExtensionManifest | UmbExtensionManifestKind> = [manifest];
Lines changed: 52 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import type { UmbWorkspaceAction } from '../workspace-action.interface.js';
21
import type {
32
ManifestWorkspaceAction,
43
ManifestWorkspaceActionMenuItem,
54
MetaWorkspaceActionDefaultKind,
5+
UmbWorkspaceActionDefaultKind,
66
} from '../../../types.js';
77
import { UmbActionExecutedEvent } from '@umbraco-cms/backoffice/event';
8-
import { html, customElement, property, state, ifDefined, when } from '@umbraco-cms/backoffice/external/lit';
8+
import { html, customElement, property, state, when } from '@umbraco-cms/backoffice/external/lit';
99
import type { UUIButtonState } from '@umbraco-cms/backoffice/external/uui';
1010
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
1111
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';
@@ -19,7 +19,7 @@ import '../../workspace-action-menu/index.js';
1919
@customElement('umb-workspace-action')
2020
export class UmbWorkspaceActionElement<
2121
MetaType extends MetaWorkspaceActionDefaultKind = MetaWorkspaceActionDefaultKind,
22-
ApiType extends UmbWorkspaceAction<MetaType> = UmbWorkspaceAction<MetaType>,
22+
ApiType extends UmbWorkspaceActionDefaultKind<MetaType> = UmbWorkspaceActionDefaultKind<MetaType>,
2323
> extends UmbLitElement {
2424
#manifest?: ManifestWorkspaceAction<MetaType>;
2525
#api?: ApiType;
@@ -29,21 +29,14 @@ export class UmbWorkspaceActionElement<
2929
ManifestWorkspaceActionMenuItem
3030
>;
3131

32-
@state()
33-
private _buttonState?: UUIButtonState;
34-
35-
@state()
36-
_href?: string;
37-
38-
@state()
39-
_isDisabled = false;
40-
4132
@property({ type: Object, attribute: false })
4233
public set manifest(value: ManifestWorkspaceAction<MetaType> | undefined) {
4334
if (!value) return;
4435
const oldValue = this.#manifest;
45-
this.#manifest = value;
46-
if (oldValue !== this.#manifest) {
36+
if (oldValue !== value) {
37+
this.#manifest = value;
38+
this._href = value?.meta.href;
39+
this._additionalOptions = value?.meta.additionalOptions;
4740
this.#createAliases();
4841
this.requestUpdate('manifest', oldValue);
4942
}
@@ -56,10 +49,12 @@ export class UmbWorkspaceActionElement<
5649
public set api(api: ApiType | undefined) {
5750
this.#api = api;
5851

59-
// TODO: Fix so when we use a HREF it does not refresh the page?
6052
this.#api?.getHref?.().then((href) => {
61-
this._href = href;
62-
// TODO: Do we need to update the component here? [NL]
53+
this._href = href ?? this.manifest?.meta.href;
54+
});
55+
56+
this.#api?.hasAdditionalOptions?.().then((additionalOptions) => {
57+
this._additionalOptions = additionalOptions ?? this.manifest?.meta.additionalOptions;
6358
});
6459

6560
this.#observeIsDisabled();
@@ -68,6 +63,18 @@ export class UmbWorkspaceActionElement<
6863
return this.#api;
6964
}
7065

66+
@state()
67+
private _buttonState?: UUIButtonState;
68+
69+
@state()
70+
private _additionalOptions?: boolean;
71+
72+
@state()
73+
private _href?: string;
74+
75+
@state()
76+
_isDisabled = false;
77+
7178
@state()
7279
private _items: Array<UmbExtensionElementAndApiInitializer<ManifestWorkspaceActionMenuItem>> = [];
7380

@@ -92,21 +99,28 @@ export class UmbWorkspaceActionElement<
9299
this.#observeExtensions(Array.from(aliases));
93100
}
94101

95-
private async _onClick(event: MouseEvent) {
102+
async #onClick(event: MouseEvent) {
96103
if (this._href) {
97104
event.stopPropagation();
98105
}
106+
// If its a link or has additional options, then we do not want to display state on the button. [NL]
107+
if (!this._href) {
108+
if (!this._additionalOptions) {
109+
this._buttonState = 'waiting';
110+
}
99111

100-
this._buttonState = 'waiting';
101-
102-
try {
103-
if (!this.#api) throw new Error('No api defined');
104-
await this.#api.execute();
105-
this._buttonState = 'success';
106-
} catch {
107-
this._buttonState = 'failed';
112+
try {
113+
if (!this.#api) throw new Error('No api defined');
114+
await this.#api.execute();
115+
if (!this._additionalOptions) {
116+
this._buttonState = 'success';
117+
}
118+
} catch {
119+
if (!this._additionalOptions) {
120+
this._buttonState = 'failed';
121+
}
122+
}
108123
}
109-
110124
this.dispatchEvent(new UmbActionExecutedEvent());
111125
}
112126

@@ -144,27 +158,28 @@ export class UmbWorkspaceActionElement<
144158
}
145159

146160
#renderButton() {
161+
const label = this.#manifest?.meta.label
162+
? this.localize.string(this.#manifest.meta.label)
163+
: (this.#manifest?.name ?? '');
147164
return html`
148165
<uui-button
149-
id="action-button"
166+
data-mark="workspace-action:${this.#manifest?.alias}"
150167
.href=${this._href}
151-
@click=${this._onClick}
152-
look=${this.#manifest?.meta.look || 'default'}
153-
color=${this.#manifest?.meta.color || 'default'}
154-
label=${ifDefined(
155-
this.#manifest?.meta.label ? this.localize.string(this.#manifest.meta.label) : this.#manifest?.name,
156-
)}
168+
look=${this.#manifest?.meta.look ?? 'default'}
169+
color=${this.#manifest?.meta.color ?? 'default'}
170+
label=${this._additionalOptions ? label + '…' : label}
157171
.disabled=${this._isDisabled}
158-
.state=${this._buttonState}></uui-button>
172+
.state=${this._buttonState}
173+
@click=${this.#onClick}></uui-button>
159174
`;
160175
}
161176

162177
#renderActionMenu() {
163178
return html`
164179
<umb-workspace-action-menu
165180
.items=${this._items}
166-
color="${this.#manifest?.meta.color || 'default'}"
167-
look="${this.#manifest?.meta.look || 'default'}"></umb-workspace-action-menu>
181+
color="${this.#manifest?.meta.color ?? 'default'}"
182+
look="${this.#manifest?.meta.look ?? 'default'}"></umb-workspace-action-menu>
168183
`;
169184
}
170185

0 commit comments

Comments
 (0)