Skip to content

Commit f45cdcc

Browse files
leekelleheriOvergaard
authored andcommitted
Relocated "Save and Preview" workspace action
reworked using the "default" `previewOption` kind.
1 parent e073433 commit f45cdcc

File tree

6 files changed

+197
-33
lines changed

6 files changed

+197
-33
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import { manifests as previewOptionManifests } from './preview-option/manifests.js';
2+
import { manifests as workspaceActionManifests } from './workspace-action/manifests.js';
23
import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry';
4+
35
export const manifests: Array<UmbExtensionManifest | UmbExtensionManifestKind> = [
46
...previewOptionManifests,
7+
...workspaceActionManifests,
58
];
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
import { manifest as defaultKind } from './default.preview-option.kind.js';
22
import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry';
3+
4+
const previewOption: UmbExtensionManifest = {
5+
type: 'previewOption',
6+
kind: 'default',
7+
alias: 'Umb.PreviewOption.Document.SaveAndPreview',
8+
name: 'Save And Preview Document Preview Option',
9+
weight: 200,
10+
meta: {
11+
label: '#buttons_saveAndPreview',
12+
},
13+
};
14+
315
export const manifests: Array<UmbExtensionManifest | UmbExtensionManifestKind> = [
16+
previewOption,
417
defaultKind,
518
];
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { UMB_DOCUMENT_WORKSPACE_ALIAS } from '../../constants.js';
2+
import { UMB_ENTITY_IS_NOT_TRASHED_CONDITION_ALIAS } from '@umbraco-cms/backoffice/recycle-bin';
3+
import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace';
4+
5+
const workspaceAction: UmbExtensionManifest = {
6+
type: 'workspaceAction',
7+
kind: 'default',
8+
alias: 'Umb.WorkspaceAction.Document.SaveAndPreview',
9+
name: 'Save And Preview Document Workspace Action',
10+
weight: 90,
11+
api: () => import('./save-and-preview.action.js'),
12+
element: () => import('./save-and-preview-workspace-action.element.js'),
13+
meta: {
14+
label: '#buttons_saveAndPreview',
15+
},
16+
conditions: [
17+
{
18+
alias: UMB_WORKSPACE_CONDITION_ALIAS,
19+
match: UMB_DOCUMENT_WORKSPACE_ALIAS,
20+
},
21+
{
22+
alias: UMB_ENTITY_IS_NOT_TRASHED_CONDITION_ALIAS,
23+
},
24+
],
25+
};
26+
27+
export const manifests: Array<UmbExtensionManifest> = [workspaceAction];
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
import type { ManifestPreviewOption } from '../preview-option/preview-option.extension.js';
2+
import { customElement, html, property, state, when } from '@umbraco-cms/backoffice/external/lit';
3+
import { UmbActionExecutedEvent } from '@umbraco-cms/backoffice/event';
4+
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';
5+
import { UmbExtensionsElementAndApiInitializer } from '@umbraco-cms/backoffice/extension-api';
6+
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
7+
import type { UmbWorkspaceAction } from '@umbraco-cms/backoffice/workspace';
8+
import type { UmbExtensionElementAndApiInitializer } from '@umbraco-cms/backoffice/extension-api';
9+
import type { UUIButtonState } from '@umbraco-cms/backoffice/external/uui';
10+
11+
@customElement('umb-save-and-preview-workspace-action')
12+
export class UmbSaveAndPreviewWorkspaceActionElement extends UmbLitElement {
13+
#buttonStateResetTimeoutId: number | null = null;
14+
15+
#extensionsController?: UmbExtensionsElementAndApiInitializer<
16+
ManifestPreviewOption,
17+
'previewOption',
18+
ManifestPreviewOption
19+
>;
20+
21+
@property({ type: Object, attribute: false })
22+
public set manifest(value: ManifestPreviewOption | undefined) {
23+
if (!value) return;
24+
const oldValue = this.#manifest;
25+
if (oldValue !== value) {
26+
this.#manifest = value;
27+
this.#observeExtensions();
28+
}
29+
}
30+
public get manifest() {
31+
return this.#manifest;
32+
}
33+
#manifest?: ManifestPreviewOption;
34+
35+
@property({ attribute: false })
36+
public set api(api: UmbWorkspaceAction | undefined) {
37+
this.#api = api;
38+
this.#observeIsDisabled();
39+
}
40+
public get api(): UmbWorkspaceAction | undefined {
41+
return this.#api;
42+
}
43+
#api?: UmbWorkspaceAction;
44+
45+
@state()
46+
private _buttonState?: UUIButtonState;
47+
48+
@state()
49+
private _isDisabled = false;
50+
51+
@state()
52+
private _actions: Array<UmbExtensionElementAndApiInitializer<ManifestPreviewOption>> = [];
53+
54+
private _primaryAction?: UmbExtensionElementAndApiInitializer<ManifestPreviewOption>;
55+
56+
async #onClick() {
57+
this._buttonState = 'waiting';
58+
59+
try {
60+
if (!this._primaryAction?.api) throw new Error('No api defined');
61+
await this._primaryAction.api.execute().catch(() => {});
62+
this._buttonState = 'success';
63+
} catch (reason) {
64+
if (reason) {
65+
console.warn(reason);
66+
}
67+
this._buttonState = 'failed';
68+
}
69+
70+
this.#initButtonStateReset();
71+
this.dispatchEvent(new UmbActionExecutedEvent());
72+
}
73+
74+
#observeIsDisabled() {
75+
this.observe(
76+
this.#api?.isDisabled,
77+
(isDisabled) => {
78+
this._isDisabled = isDisabled || false;
79+
},
80+
'isDisabledObserver',
81+
);
82+
}
83+
84+
#initButtonStateReset() {
85+
this.#clearButtonStateResetTimeout();
86+
this.#buttonStateResetTimeoutId = window.setTimeout(() => {
87+
this._buttonState = undefined;
88+
}, 2000);
89+
}
90+
91+
#clearButtonStateResetTimeout() {
92+
if (this.#buttonStateResetTimeoutId !== null) {
93+
clearTimeout(this.#buttonStateResetTimeoutId);
94+
this.#buttonStateResetTimeoutId = null;
95+
}
96+
}
97+
98+
#observeExtensions(): void {
99+
this.#extensionsController?.destroy();
100+
this.#extensionsController = new UmbExtensionsElementAndApiInitializer<
101+
ManifestPreviewOption,
102+
'previewOption',
103+
ManifestPreviewOption
104+
>(this, umbExtensionsRegistry, 'previewOption', [], undefined, (extensionControllers) => {
105+
this._primaryAction = extensionControllers.shift();
106+
this._actions = extensionControllers;
107+
});
108+
}
109+
110+
#renderButton() {
111+
const label = this._primaryAction?.manifest?.meta.label || this.#manifest?.meta.label || this.#manifest?.name;
112+
return html`
113+
<uui-button
114+
data-mark="workspace-action:${this.#manifest?.alias}"
115+
color=${this.#manifest?.meta.color ?? 'default'}
116+
look=${this.#manifest?.meta.look ?? 'default'}
117+
label=${this.localize.string(label)}
118+
.disabled=${this._isDisabled}
119+
.state=${this._buttonState}
120+
@click=${this.#onClick}></uui-button>
121+
`;
122+
}
123+
124+
#renderActionMenu() {
125+
// TODO: [LK] FIXME: The `any` type casting here needs to be resolved with a proper type.
126+
return html`
127+
<umb-workspace-action-menu
128+
color=${this.#manifest?.meta.color ?? 'default'}
129+
look=${this.#manifest?.meta.look ?? 'default'}
130+
.items=${this._actions as any}></umb-workspace-action-menu>
131+
`;
132+
}
133+
134+
override render() {
135+
return when(
136+
this._actions.length,
137+
() => html`<uui-button-group>${this.#renderButton()}${this.#renderActionMenu()}</uui-button-group>`,
138+
() => this.#renderButton(),
139+
);
140+
}
141+
142+
override disconnectedCallback() {
143+
super.disconnectedCallback();
144+
this.#clearButtonStateResetTimeout();
145+
}
146+
}
147+
148+
export default UmbSaveAndPreviewWorkspaceActionElement;
149+
150+
declare global {
151+
interface HTMLElementTagNameMap {
152+
'umb-save-and-preview-workspace-action': UmbSaveAndPreviewWorkspaceActionElement;
153+
}
154+
}

src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/actions/save-and-preview.action.ts renamed to src/Umbraco.Web.UI.Client/src/packages/documents/documents/preview/workspace-action/save-and-preview.action.ts

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,8 @@
11
import { UmbDocumentUserPermissionCondition } from '../../user-permissions/document/conditions/document-user-permission.condition.js';
2-
import { UMB_DOCUMENT_WORKSPACE_CONTEXT } from '../document-workspace.context-token.js';
32
import { UMB_USER_PERMISSION_DOCUMENT_UPDATE } from '../../user-permissions/document/constants.js';
43
import { UmbWorkspaceActionBase } from '@umbraco-cms/backoffice/workspace';
54
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
65

7-
// TODO: Investigate how additional preview environments can be supported. [LK:2024-05-16]
8-
// https://docs.umbraco.com/umbraco-cms/reference/content-delivery-api/additional-preview-environments-support
9-
// In v13, they are registered on the server using `SendingContentNotification`, which is no longer available in v14.
10-
116
export class UmbDocumentSaveAndPreviewWorkspaceAction extends UmbWorkspaceActionBase {
127
constructor(host: UmbControllerHost, args: any) {
138
super(host, args);
@@ -31,14 +26,6 @@ export class UmbDocumentSaveAndPreviewWorkspaceAction extends UmbWorkspaceAction
3126
},
3227
});
3328
}
34-
35-
override async execute() {
36-
const workspaceContext = await this.getContext(UMB_DOCUMENT_WORKSPACE_CONTEXT);
37-
if (!workspaceContext) {
38-
throw new Error('Document workspace context not found');
39-
}
40-
workspaceContext.saveAndPreview();
41-
}
4229
}
4330

4431
export { UmbDocumentSaveAndPreviewWorkspaceAction as api };

src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/actions/manifests.ts

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,24 +25,4 @@ export const manifests: Array<UmbExtensionManifest> = [
2525
},
2626
],
2727
},
28-
{
29-
type: 'workspaceAction',
30-
kind: 'default',
31-
alias: 'Umb.WorkspaceAction.Document.SaveAndPreview',
32-
name: 'Save And Preview Document Workspace Action',
33-
weight: 90,
34-
api: () => import('./save-and-preview.action.js'),
35-
meta: {
36-
label: '#buttons_saveAndPreview',
37-
},
38-
conditions: [
39-
{
40-
alias: UMB_WORKSPACE_CONDITION_ALIAS,
41-
match: UMB_DOCUMENT_WORKSPACE_ALIAS,
42-
},
43-
{
44-
alias: UMB_ENTITY_IS_NOT_TRASHED_CONDITION_ALIAS,
45-
},
46-
],
47-
},
4828
];

0 commit comments

Comments
 (0)