Skip to content

Commit ee05e5d

Browse files
Removes collection action state (#18212)
* remove collection action state * clean up * Update collection-action-button.element.ts * use ellipsis character * JSDocs * TODO note * add more options * TODO * additionalOptions for Collection Actions --------- Co-authored-by: Niels Lyngsø <[email protected]>
1 parent 8ea58c1 commit ee05e5d

File tree

8 files changed

+92
-49
lines changed

8 files changed

+92
-49
lines changed

src/Umbraco.Web.UI.Client/src/libs/localization-api/localization.controller.ts

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ export class UmbLocalizationController<LocalizationSetType extends UmbLocalizati
8383
/**
8484
* Gets the host element's directionality as determined by the `dir` attribute. The return value is transformed to
8585
* lowercase.
86+
* @returns {string} - the directionality.
8687
*/
8788
dir() {
8889
return `${this.#hostEl?.dir || umbLocalizationManager.documentDirection}`.toLowerCase();
@@ -91,6 +92,7 @@ export class UmbLocalizationController<LocalizationSetType extends UmbLocalizati
9192
/**
9293
* Gets the host element's language as determined by the `lang` attribute. The return value is transformed to
9394
* lowercase.
95+
* @returns {string} - the language code.
9496
*/
9597
lang() {
9698
return `${this.#hostEl?.lang || umbLocalizationManager.documentLanguage}`.toLowerCase();
@@ -158,8 +160,9 @@ export class UmbLocalizationController<LocalizationSetType extends UmbLocalizati
158160

159161
/**
160162
* Outputs a localized date in the specified format.
161-
* @param dateToFormat
162-
* @param options
163+
* @param {Date} dateToFormat - the date to format.
164+
* @param {Intl.DateTimeFormatOptions} options - the options to use when formatting the date.
165+
* @returns {string}
163166
*/
164167
date(dateToFormat: Date | string, options?: Intl.DateTimeFormatOptions): string {
165168
dateToFormat = new Date(dateToFormat);
@@ -168,8 +171,9 @@ export class UmbLocalizationController<LocalizationSetType extends UmbLocalizati
168171

169172
/**
170173
* Outputs a localized number in the specified format.
171-
* @param numberToFormat
172-
* @param options
174+
* @param {number | string} numberToFormat - the number or string to format.
175+
* @param {Intl.NumberFormatOptions} options - the options to use when formatting the number.
176+
* @returns {string} - the formatted number.
173177
*/
174178
number(numberToFormat: number | string, options?: Intl.NumberFormatOptions): string {
175179
numberToFormat = Number(numberToFormat);
@@ -178,14 +182,16 @@ export class UmbLocalizationController<LocalizationSetType extends UmbLocalizati
178182

179183
/**
180184
* Outputs a localized time in relative format.
181-
* @param value
182-
* @param unit
183-
* @param options
185+
* @param {number} value - the value to format.
186+
* @param {Intl.RelativeTimeFormatUnit} unit - the unit of time to format.
187+
* @param {Intl.RelativeTimeFormatOptions} options - the options to use when formatting the time.
188+
* @returns {string} - the formatted time.
184189
*/
185190
relativeTime(value: number, unit: Intl.RelativeTimeFormatUnit, options?: Intl.RelativeTimeFormatOptions): string {
186191
return new Intl.RelativeTimeFormat(this.lang(), options).format(value, unit);
187192
}
188193

194+
// TODO: for V.16 we should set type to be string | undefined. [NL]
189195
/**
190196
* Translates a string containing one or more terms. The terms should be prefixed with a `#` character.
191197
* If the term is found in the localization set, it will be replaced with the localized term.

src/Umbraco.Web.UI.Client/src/packages/core/collection/action/collection-action-base.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,22 @@ import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
22
import type { UmbApi } from '@umbraco-cms/backoffice/extension-api';
33

44
export interface UmbCollectionAction extends UmbApi {
5+
/**
6+
* The href location, the action will act as a link.
7+
* @returns {undefined | Promise<string | undefined>}
8+
*/
9+
getHref?: () => Promise<string | undefined>;
10+
11+
/**
12+
* Determine if the UI should indicate that more options will appear when interacting with this.
13+
* @returns {undefined | Promise<boolean | undefined>}
14+
*/
15+
hasAddionalOptions?: () => Promise<boolean | undefined>;
16+
17+
/**
18+
* The `execute` method, the action will act as a button.
19+
* @returns {Promise<void>}
20+
*/
521
execute(): Promise<void>;
622
}
723

src/Umbraco.Web.UI.Client/src/packages/core/collection/action/collection-action-button.element.ts

Lines changed: 42 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,82 @@
11
import type { UmbCollectionAction } from './collection-action-base.js';
22
import { UmbActionExecutedEvent } from '@umbraco-cms/backoffice/event';
3-
import { html, customElement, property, state, ifDefined } from '@umbraco-cms/backoffice/external/lit';
4-
import type { UUIButtonState } from '@umbraco-cms/backoffice/external/uui';
3+
import { html, customElement, property, state } from '@umbraco-cms/backoffice/external/lit';
54
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
6-
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';
7-
import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry';
85
import type { ManifestCollectionAction } from '@umbraco-cms/backoffice/collection';
96
import { createExtensionApi } from '@umbraco-cms/backoffice/extension-api';
10-
11-
const manifest: UmbExtensionManifestKind = {
12-
type: 'kind',
13-
alias: 'Umb.Kind.CollectionAction.Button',
14-
matchKind: 'button',
15-
matchType: 'collectionAction',
16-
manifest: {
17-
type: 'collectionAction',
18-
kind: 'button',
19-
elementName: 'umb-collection-action-button',
20-
},
21-
};
22-
umbExtensionsRegistry.register(manifest);
7+
import type { UUIButtonState } from '@umbraco-cms/backoffice/external/uui';
238

249
@customElement('umb-collection-action-button')
2510
export class UmbCollectionActionButtonElement extends UmbLitElement {
26-
@state()
27-
private _buttonState?: UUIButtonState;
11+
#api?: UmbCollectionAction;
2812

29-
private _manifest?: ManifestCollectionAction;
3013
@property({ type: Object, attribute: false })
3114
public get manifest() {
3215
return this._manifest;
3316
}
3417
public set manifest(value: ManifestCollectionAction | undefined) {
35-
if (!value) return;
3618
const oldValue = this._manifest;
37-
this._manifest = value;
38-
if (oldValue !== this._manifest) {
19+
if (oldValue !== value) {
20+
this._manifest = value;
21+
this._href = this.manifest?.meta.href;
22+
this._additionalOptions = this.manifest?.meta.additionalOptions;
3923
this.#createApi();
4024
this.requestUpdate('manifest', oldValue);
4125
}
4226
}
27+
private _manifest?: ManifestCollectionAction;
4328

4429
async #createApi() {
4530
if (!this._manifest) throw new Error('No manifest defined');
4631
if (!this._manifest.api) return;
47-
this.#api = (await createExtensionApi(this, this._manifest)) as unknown as UmbCollectionAction;
32+
this.#api = await createExtensionApi<UmbCollectionAction>(this, this._manifest);
33+
34+
this._href = (await this.#api?.getHref?.()) ?? this.manifest?.meta.href;
35+
this._additionalOptions = (await this.#api?.hasAddionalOptions?.()) ?? this.manifest?.meta.additionalOptions;
4836
}
4937

50-
#api?: UmbCollectionAction;
38+
@state()
39+
private _buttonState?: UUIButtonState;
5140

52-
private async _onClick() {
53-
if (!this.#api) return;
41+
@state()
42+
private _additionalOptions?: boolean;
5443

55-
this._buttonState = 'waiting';
44+
@state()
45+
private _href?: string;
5646

57-
try {
58-
if (!this.#api) throw new Error('No api defined');
59-
await this.#api.execute();
60-
this._buttonState = 'success';
61-
} catch {
62-
this._buttonState = 'failed';
63-
}
47+
private async _onClick() {
48+
// If its a link or has additional options, then we do not want to display state on the button. [NL]
49+
if (!this._href) {
50+
if (!this._additionalOptions) {
51+
this._buttonState = 'waiting';
52+
}
6453

54+
try {
55+
if (!this.#api) throw new Error('No api defined');
56+
await this.#api.execute();
57+
if (!this._additionalOptions) {
58+
this._buttonState = 'success';
59+
}
60+
} catch {
61+
if (!this._additionalOptions) {
62+
this._buttonState = 'failed';
63+
}
64+
}
65+
}
6566
this.dispatchEvent(new UmbActionExecutedEvent());
6667
}
6768

6869
override render() {
69-
const label = this.manifest?.meta.label ? this.localize.string(this.manifest.meta.label) : this.manifest?.name;
70+
const label = this.manifest?.meta.label
71+
? this.localize.string(this.manifest.meta.label)
72+
: (this.manifest?.name ?? '');
7073
return html`
7174
<uui-button
72-
id="action-button"
75+
data-mark="collection-action:${this.manifest?.alias}"
7376
color="default"
7477
look="outline"
75-
label=${ifDefined(label)}
76-
href=${ifDefined(this.manifest?.meta.href)}
78+
.label=${this._additionalOptions ? label + '…' : label}
79+
.href=${this._href}
7780
.state=${this._buttonState}
7881
@click=${this._onClick}></uui-button>
7982
`;
Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,17 @@
1+
import UmbCollectionActionButtonElement from './collection-action-button.element.js';
12
import { manifests as createManifests } from './create/manifests.js';
23
import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry';
34

4-
export const manifests: Array<UmbExtensionManifest | UmbExtensionManifestKind> = [...createManifests];
5+
const manifest: UmbExtensionManifestKind = {
6+
type: 'kind',
7+
alias: 'Umb.Kind.CollectionAction.Button',
8+
matchKind: 'button',
9+
matchType: 'collectionAction',
10+
manifest: {
11+
type: 'collectionAction',
12+
kind: 'button',
13+
element: UmbCollectionActionButtonElement,
14+
},
15+
};
16+
17+
export const manifests: Array<UmbExtensionManifest | UmbExtensionManifestKind> = [manifest, ...createManifests];

src/Umbraco.Web.UI.Client/src/packages/core/collection/extensions/collection-action.extension.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import type { UmbCollectionAction } from '../action/collection-action-base.js';
2+
import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
13
import type { ManifestElementAndApi, ManifestWithDynamicConditions } from '@umbraco-cms/backoffice/extension-api';
24

35
/**
@@ -6,7 +8,7 @@ import type { ManifestElementAndApi, ManifestWithDynamicConditions } from '@umbr
68
*/
79
// TODO: create interface for API
810
export interface ManifestCollectionAction
9-
extends ManifestElementAndApi,
11+
extends ManifestElementAndApi<UmbControllerHostElement, UmbCollectionAction>,
1012
ManifestWithDynamicConditions<UmbExtensionConditionConfig> {
1113
type: 'collectionAction';
1214
meta: MetaCollectionAction;
@@ -15,6 +17,7 @@ export interface ManifestCollectionAction
1517
export interface MetaCollectionAction {
1618
label: string;
1719
href?: string;
20+
additionalOptions?: boolean;
1821
}
1922

2023
declare global {

src/Umbraco.Web.UI.Client/src/packages/core/entity-action/default/entity-action.element.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ export class UmbEntityActionDefaultElement<
6565

6666
return html`
6767
<uui-menu-item
68-
label=${ifDefined(this.manifest?.meta.additionalOptions ? label + '...' : label)}
68+
label=${ifDefined(this.manifest?.meta.additionalOptions ? label + '' : label)}
6969
href=${ifDefined(this._href)}
7070
@click-label=${this.#onClickLabel}
7171
@click=${this.#onClick}>

src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/action/create-document-collection-action.element.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ export class UmbCreateDocumentCollectionActionElement extends UmbLitElement {
9494
if (this._allowedDocumentTypes.length !== 1) return;
9595

9696
const item = this._allowedDocumentTypes[0];
97+
// TODO: Stop appending values to labels, instead we need to parse the name as a argument to the label. [NL]
9798
const label =
9899
(this.manifest?.meta.label
99100
? this.localize.string(this.manifest?.meta.label)

src/Umbraco.Web.UI.Client/src/packages/user/user/invite/collection-action/manifests.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export const manifests: Array<UmbExtensionManifest> = [
1010
weight: 100,
1111
meta: {
1212
label: '#user_invite',
13+
additionalOptions: true,
1314
},
1415
conditions: [
1516
{

0 commit comments

Comments
 (0)