From cb2c0433ea3675b75be3ea01104f012622edb3f9 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Wed, 13 Mar 2024 11:32:35 +0100 Subject: [PATCH] add new schedule modal --- .../documents/documents/modals/index.ts | 1 + .../documents/documents/modals/manifests.ts | 7 ++ .../document-schedule-modal.element.ts | 111 ++++++++++++++++++ .../document-schedule-modal.stories.ts | 96 +++++++++++++++ .../document-schedule-modal.token.ts | 19 +++ .../documents/modals/schedule-modal/index.ts | 1 + 6 files changed, 235 insertions(+) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/schedule-modal/document-schedule-modal.element.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/schedule-modal/document-schedule-modal.stories.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/schedule-modal/document-schedule-modal.token.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/schedule-modal/index.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/index.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/index.ts index c11dcf1900..2c42f5dfd3 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/index.ts @@ -1,4 +1,5 @@ export * from './publish-modal/index.js'; +export * from './schedule-modal/index.js'; export * from './shared/index.js'; export * from './document-picker-modal.token.js'; export type * from './types.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/manifests.ts index a1b80e5e85..f711323740 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/manifests.ts @@ -1,6 +1,7 @@ import type { ManifestModal } from '@umbraco-cms/backoffice/extension-registry'; export const UMB_DOCUMENT_PUBLISH_MODAL_ALIAS = 'Umb.Modal.DocumentPublish'; +export const UMB_DOCUMENT_SCHEDULE_MODAL_ALIAS = 'Umb.Modal.DocumentSchedule'; const modals: Array = [ { @@ -9,6 +10,12 @@ const modals: Array = [ name: 'Document Publish Modal', js: () => import('./publish-modal/document-publish-modal.element.js'), }, + { + type: 'modal', + alias: UMB_DOCUMENT_SCHEDULE_MODAL_ALIAS, + name: 'Document Schedule Modal', + js: () => import('./schedule-modal/document-schedule-modal.element.js'), + }, ]; export const manifests = [...modals]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/schedule-modal/document-schedule-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/schedule-modal/document-schedule-modal.element.ts new file mode 100644 index 0000000000..a5c7ac6baf --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/schedule-modal/document-schedule-modal.element.ts @@ -0,0 +1,111 @@ +import { UmbDocumentVariantState, type UmbDocumentVariantOptionModel } from '../../types.js'; +import type { UmbDocumentScheduleModalData, UmbDocumentScheduleModalValue } from './document-schedule-modal.token.js'; +import { css, customElement, html, state } from '@umbraco-cms/backoffice/external/lit'; +import { UMB_APP_LANGUAGE_CONTEXT } from '@umbraco-cms/backoffice/language'; +import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal'; +import { appendToFrozenArray } from '@umbraco-cms/backoffice/observable-api'; +import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; +import { UmbSelectionManager } from '@umbraco-cms/backoffice/utils'; +import { UmbVariantId } from '@umbraco-cms/backoffice/variant'; +import type { ScheduleRequestModel } from '@umbraco-cms/backoffice/external/backend-api'; + +import '../shared/document-variant-language-picker.element.js'; + +@customElement('umb-document-schedule-modal') +export class UmbDocumentScheduleModalElement extends UmbModalBaseElement< + UmbDocumentScheduleModalData, + UmbDocumentScheduleModalValue +> { + #selectionManager = new UmbSelectionManager(this); + #schedule?: ScheduleRequestModel; + + @state() + _options: Array = []; + + firstUpdated() { + this.#configureSelectionManager(); + } + + async #configureSelectionManager() { + this.#selectionManager.setMultiple(true); + this.#selectionManager.setSelectable(true); + + // Only display variants that are relevant to pick from, i.e. variants that are draft or published with pending changes: + this._options = + this.data?.options.filter( + (option) => option.variant && option.variant.state !== UmbDocumentVariantState.NOT_CREATED, + ) ?? []; + + let selected = this.value?.selection ?? []; + + // Filter selection based on options: + selected = selected.filter((s) => this._options.some((o) => o.unique === s)); + + // If no selections were provided, select the app language by default: + if (selected.length === 0) { + const context = await this.getContext(UMB_APP_LANGUAGE_CONTEXT); + const appCulture = context.getAppCulture(); + // If the app language is one of the options, select it by default: + if (appCulture && this._options.some((o) => o.language.unique === appCulture)) { + selected = appendToFrozenArray(selected, new UmbVariantId(appCulture, null).toString()); + } + } + + this.#selectionManager.setSelection(selected); + + // Additionally select mandatory languages: + this._options.forEach((variant) => { + if (variant.language?.isMandatory) { + this.#selectionManager.select(variant.unique); + } + }); + } + + #submit() { + this.value = { selection: this.#selectionManager.getSelection(), schedule: this.#schedule }; + this.modalContext?.submit(); + } + + #close() { + this.modalContext?.reject(); + } + + render() { + return html` +

+ Which languages would you like to schedule? +

+ + +
+ + +
+
`; + } + + static styles = [ + UmbTextStyles, + css` + :host { + display: block; + width: 400px; + max-width: 90vw; + } + `, + ]; +} + +export default UmbDocumentScheduleModalElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-document-schedule-modal': UmbDocumentScheduleModalElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/schedule-modal/document-schedule-modal.stories.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/schedule-modal/document-schedule-modal.stories.ts new file mode 100644 index 0000000000..64a9f88a55 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/schedule-modal/document-schedule-modal.stories.ts @@ -0,0 +1,96 @@ +import './document-schedule-modal.element.js'; + +import type { Meta, StoryObj } from '@storybook/web-components'; +import { UmbDocumentVariantState } from '../../types.js'; +import type { UmbDocumentScheduleModalData, UmbDocumentScheduleModalValue } from './document-schedule-modal.token.js'; +import type { UmbDocumentScheduleModalElement } from './document-schedule-modal.element.js'; +import { html } from '@umbraco-cms/backoffice/external/lit'; + +const modalData: UmbDocumentScheduleModalData = { + options: [ + { + unique: 'en-us', + culture: 'en-us', + segment: null, + variant: { + name: 'English variant name', + culture: 'en-us', + state: UmbDocumentVariantState.PUBLISHED, + createDate: '2021-08-25T14:00:00Z', + publishDate: null, + updateDate: null, + segment: null, + }, + language: { + entityType: 'language', + name: 'English', + unique: 'en-us', + isDefault: true, + isMandatory: true, + fallbackIsoCode: null, + }, + }, + ], +}; + +const modalValue: UmbDocumentScheduleModalValue = { + selection: ['en-us'], +}; + +const meta: Meta = { + title: 'Workspaces/Document/Modals/Schedule', + component: 'umb-document-schedule-modal', + id: 'umb-document-schedule-modal', + args: { + data: modalData, + value: modalValue, + }, + decorators: [(Story) => html`
${Story()}
`], + parameters: { + layout: 'centered', + docs: { + source: { + code: ` +import { UMB_DOCUMENT_SCHEDULE_MODAL, UmbDocumentVariantState } from '@umbraco-cms/backoffice/document'; +import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal'; + +this.consumeContext(UMB_MODAL_MANAGER_CONTEXT, (modalManager) => { + const result = await modalManager.open(this, UMB_DOCUMENT_SCHEDULE_MODAL, { + data: { + options: [ + { + unique: 'en-us', + culture: 'en-us', + segment: null, + variant: { + name: 'English variant name', + culture: 'en-us', + state: UmbDocumentVariantState.PUBLISHED, + createDate: '2021-08-25T14:00:00Z', + publishDate: null, + updateDate: null, + segment: null, + }, + language: { + entityType: 'language', + name: 'English', + unique: 'en-us', + isDefault: true, + isMandatory: true, + fallbackIsoCode: null, + }, + }, + ], + } + }).onSubmit().catch(() => undefined); +}); + `, + }, + }, + }, +}; + +export default meta; +type Story = StoryObj; + +export const Overview: Story = {}; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/schedule-modal/document-schedule-modal.token.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/schedule-modal/document-schedule-modal.token.ts new file mode 100644 index 0000000000..0007d4d7e6 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/schedule-modal/document-schedule-modal.token.ts @@ -0,0 +1,19 @@ +import type { UmbDocumentVariantPickerData, UmbDocumentVariantPickerValue } from '../types.js'; +import { UMB_DOCUMENT_SCHEDULE_MODAL_ALIAS } from '../manifests.js'; +import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; +import type { ScheduleRequestModel } from '@umbraco-cms/backoffice/external/backend-api'; + +export interface UmbDocumentScheduleModalData extends UmbDocumentVariantPickerData {} + +export interface UmbDocumentScheduleModalValue extends UmbDocumentVariantPickerValue { + schedule?: ScheduleRequestModel; +} + +export const UMB_DOCUMENT_SCHEDULE_MODAL = new UmbModalToken< + UmbDocumentScheduleModalData, + UmbDocumentScheduleModalValue +>(UMB_DOCUMENT_SCHEDULE_MODAL_ALIAS, { + modal: { + type: 'dialog', + }, +}); diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/schedule-modal/index.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/schedule-modal/index.ts new file mode 100644 index 0000000000..0307e54b17 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/schedule-modal/index.ts @@ -0,0 +1 @@ +export * from './document-schedule-modal.token.js';