From 3ba0b6d5ab836c519a3fb86ac78eeb2894f8dd93 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Wed, 7 Feb 2024 15:24:43 +0100 Subject: [PATCH 01/25] export manifest alias --- .../src/packages/documents/documents/workspace/manifests.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/manifests.ts index 0bab8a6794..feac5dd026 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/manifests.ts @@ -10,9 +10,11 @@ import type { ManifestWorkspaceViewCollection, } from '@umbraco-cms/backoffice/extension-registry'; +export const UMB_DOCUMENT_WORKSPACE_ALIAS = 'Umb.Workspace.Document'; + const workspace: ManifestWorkspace = { type: 'workspace', - alias: 'Umb.Workspace.Document', + alias: UMB_DOCUMENT_WORKSPACE_ALIAS, name: 'Document Workspace', element: () => import('./document-workspace.element.js'), api: () => import('./document-workspace.context.js'), From a8324bedc576362b7da21b12f13d6b0ebbbf6365 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Wed, 7 Feb 2024 15:28:52 +0100 Subject: [PATCH 02/25] save, publish, unpublish only selected variants --- .../workspace/document-workspace.context.ts | 88 ++++++++++--------- 1 file changed, 45 insertions(+), 43 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts index 4bc86ab5a0..bf7fc88852 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts @@ -4,6 +4,7 @@ import { UMB_DOCUMENT_ENTITY_TYPE } from '../entity.js'; import { UmbDocumentDetailRepository } from '../repository/index.js'; import type { UmbDocumentDetailModel } from '../types.js'; import { UmbDocumentPublishingRepository } from '../repository/publishing/index.js'; +import { UMB_DOCUMENT_WORKSPACE_ALIAS } from './manifests.js'; import { UmbVariantId } from '@umbraco-cms/backoffice/variant'; import { UmbContentTypePropertyStructureManager } from '@umbraco-cms/backoffice/content-type'; import { @@ -45,7 +46,7 @@ export class UmbDocumentWorkspaceContext constructor(host: UmbControllerHost) { // TODO: Get Workspace Alias via Manifest. - super(host, 'Umb.Workspace.Document'); + super(host, UMB_DOCUMENT_WORKSPACE_ALIAS); this.observe(this.contentTypeUnique, (unique) => this.structure.loadType(unique)); @@ -140,7 +141,7 @@ export class UmbDocumentWorkspaceContext * @returns The value or undefined if not set or found. */ getPropertyValue(alias: string, variantId?: UmbVariantId) { - const currentData = this.#currentData.value; + const currentData = this.getData(); if (currentData) { const newDataSet = currentData.values?.find( (x) => x.alias === alias && (variantId ? variantId.compare(x) : true), @@ -157,7 +158,7 @@ export class UmbDocumentWorkspaceContext if (!variantId) throw new Error('VariantId is missing'); const entry = { ...variantId.toObject(), alias, value }; - const currentData = this.#currentData.value; + const currentData = this.getData(); if (currentData) { const values = appendToFrozenArray( currentData.values || [], @@ -168,18 +169,36 @@ export class UmbDocumentWorkspaceContext } } - async #createOrSave() { - if (!this.#currentData.value?.unique) throw new Error('Unique is missing'); + async #selectVariants(): Promise { + const currentData = this.getData(); + if (!currentData) throw new Error('Data is missing'); + + // TODO: Let user select variants. + return currentData.variants.map((x) => UmbVariantId.Create(x)); + } + + async #createOrSave(): Promise { + const data = this.getData(); + if (!data) throw new Error('Data is missing'); + if (!data.unique) throw new Error('Unique is missing'); + + const selectedVariants = await this.#selectVariants(); + + // TODO: Use selected variants + console.log( + 'Saving', + selectedVariants.map((x) => x.culture), + ); if (this.getIsNew()) { - const value = this.#currentData.value; - - if ((await this.repository.create(value)).data !== undefined) { + if ((await this.repository.create(data)).data !== undefined) { this.setIsNew(false); } } else { - await this.repository.save(this.#currentData.value); + await this.repository.save(data); } + + return selectedVariants; } async save() { @@ -189,47 +208,30 @@ export class UmbDocumentWorkspaceContext this.saveComplete(data); } - async delete() { - const id = this.getEntityId(); - if (id) { - await this.repository.delete(id); + public async publish() { + const variantIds = await this.#createOrSave(); + const unique = this.getEntityId(); + if (variantIds.length && unique) { + await this.publishingRepository.publish(unique, variantIds); } } public async saveAndPublish() { - await this.#createOrSave(); - // TODO: This might be right to publish all, but we need a method that just saves and publishes a declared range of variants. - const currentData = this.#currentData.value; - if (currentData) { - const variantIds = currentData.variants?.map((x) => UmbVariantId.Create(x)); - const unique = currentData.unique; - if (variantIds && unique) { - await this.publishingRepository.publish(unique, variantIds); - } - } - } - - public async publish() { - // TODO: This might be right to publish all, but we need a method that just publishes a declared range of variants. - const currentData = this.#currentData.value; - if (currentData) { - const variantIds = currentData.variants?.map((x) => UmbVariantId.Create(x)); - const unique = this.getEntityId(); - if (variantIds && unique) { - await this.publishingRepository.publish(unique, variantIds); - } - } + await this.publish(); } public async unpublish() { - // TODO: This might be right to unpublish all, but we need a method that just publishes a declared range of variants. - const currentData = this.#currentData.value; - if (currentData) { - const variantIds = currentData.variants?.map((x) => UmbVariantId.Create(x)); - const unique = this.getEntityId(); - if (variantIds && unique) { - await this.publishingRepository.unpublish(unique, variantIds); - } + const variantIds = await this.#selectVariants(); + const unique = this.getEntityId(); + if (variantIds && unique) { + await this.publishingRepository.unpublish(unique, variantIds); + } + } + + async delete() { + const id = this.getEntityId(); + if (id) { + await this.repository.delete(id); } } From 90e7613c53bbfc1a4cd6d02f7755a005af0d2cec Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Wed, 7 Feb 2024 15:49:25 +0100 Subject: [PATCH 03/25] remove todo --- .../documents/workspace/document-workspace-editor.element.ts | 1 + .../documents/documents/workspace/document-workspace.context.ts | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace-editor.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace-editor.element.ts index 6dcf38a5e4..db0963c4ee 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace-editor.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace-editor.element.ts @@ -7,6 +7,7 @@ import { UmbVariantId } from '@umbraco-cms/backoffice/variant'; import type { UmbRoute, UmbRouterSlotInitEvent } from '@umbraco-cms/backoffice/router'; import type { ActiveVariant } from '@umbraco-cms/backoffice/workspace'; import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; + @customElement('umb-document-workspace-editor') export class UmbDocumentWorkspaceEditorElement extends UmbLitElement { //private _defaultVariant?: VariantViewModelBaseModel; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts index bf7fc88852..66ff979782 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts @@ -45,7 +45,6 @@ export class UmbDocumentWorkspaceContext readonly splitView = new UmbWorkspaceSplitViewManager(); constructor(host: UmbControllerHost) { - // TODO: Get Workspace Alias via Manifest. super(host, UMB_DOCUMENT_WORKSPACE_ALIAS); this.observe(this.contentTypeUnique, (unique) => this.structure.loadType(unique)); From 0959504124eaf7ec066001b81dae4717aaf2cc1b Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Wed, 7 Feb 2024 16:37:02 +0100 Subject: [PATCH 04/25] add new modal to pick items --- .../listitem-picker-modal.element.ts | 71 +++++++++++++++++++ .../listitem-picker-modal.stories.ts | 41 +++++++++++ .../packages/core/modal/common/manifests.ts | 6 ++ .../src/packages/core/modal/token/index.ts | 1 + .../token/listitem-picker-modal.token.ts | 24 +++++++ 5 files changed, 143 insertions(+) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/modal/common/listitem-picker/listitem-picker-modal.element.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/modal/common/listitem-picker/listitem-picker-modal.stories.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/modal/token/listitem-picker-modal.token.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/listitem-picker/listitem-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/listitem-picker/listitem-picker-modal.element.ts new file mode 100644 index 0000000000..1049a71ee2 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/listitem-picker/listitem-picker-modal.element.ts @@ -0,0 +1,71 @@ +import type { + UmbListitemPickerModalData, + UmbListitemPickerModalValue, +} from '../../token/listitem-picker-modal.token.js'; +import type { UmbModalContext } from '../../modal.context.js'; +import { html, customElement, property, ifDefined, repeat } from '@umbraco-cms/backoffice/external/lit'; +import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; + +@customElement('umb-listitem-picker-modal') +export class UmbListitemPickerModalElement extends UmbLitElement { + @property({ attribute: false }) + modalContext?: UmbModalContext; + + @property({ type: Object, attribute: false }) + data?: UmbListitemPickerModalData; + + private _handleSubmit(e: SubmitEvent) { + e.preventDefault(); + debugger; + //this.modalContext?.submit(); + } + + private _handleCancel() { + this.modalContext?.reject(); + } + + #renderItems() { + return html` + ${repeat( + this.data?.items || [], + (item) => item.key, + (item) => { + return html``; + }, + )} + `; + } + + render() { + return html` + + +
+ ${this.#renderItems()} + + +
+
+
+ `; + } + + static styles = [UmbTextStyles]; +} + +export default UmbListitemPickerModalElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-listitem-picker-modal': UmbListitemPickerModalElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/listitem-picker/listitem-picker-modal.stories.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/listitem-picker/listitem-picker-modal.stories.ts new file mode 100644 index 0000000000..19ee4f924b --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/listitem-picker/listitem-picker-modal.stories.ts @@ -0,0 +1,41 @@ +import './listitem-picker-modal.element.js'; + +import type { Meta, Story } from '@storybook/web-components'; +import type { UmbConfirmModalElement } from './listitem-picker-modal.element.js'; +import { html } from '@umbraco-cms/backoffice/external/lit'; + +import type { UmbConfirmModalData } from '@umbraco-cms/backoffice/modal'; + +export default { + title: 'API/Modals/Layouts/Confirm', + component: 'umb-confirm-modal', + id: 'umb-confirm-modal', +} as Meta; + +const positiveData: UmbConfirmModalData = { + headline: 'Publish with descendants', + content: html`Publish This example and all content items underneath and thereby making their content publicly + available.`, + confirmLabel: 'Publish', +}; + +export const Positive: Story = () => html` + + +`; + +const dangerData: UmbConfirmModalData = { + color: 'danger', + headline: 'Delete', + content: html`Delete This example and all items underneath.`, + confirmLabel: 'Delete', +}; + +export const Danger: Story = () => html` + + +`; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/manifests.ts index 3728ed4d0d..4176c78d02 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/manifests.ts @@ -49,6 +49,12 @@ const modals: Array = [ name: 'Tree Picker Modal', js: () => import('./tree-picker/tree-picker-modal.element.js'), }, + { + type: 'modal', + alias: 'Umb.Modal.ListitemPicker', + name: 'Listitem Picker Modal', + js: () => import('./listitem-picker/listitem-picker-modal.element.js'), + }, ]; export const manifests = [...modals]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/index.ts index 7e03e7451b..bd7bec00ee 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/index.ts @@ -14,6 +14,7 @@ export * from './entity-user-permission-settings-modal.token.js'; export * from './examine-fields-settings-modal.token.js'; export * from './icon-picker-modal.token.js'; export * from './link-picker-modal.token.js'; +export * from './listitem-picker-modal.token.js'; export * from './media-tree-picker-modal.token.js'; export * from './media-type-picker-modal.token.js'; export * from './modal-token.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/listitem-picker-modal.token.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/listitem-picker-modal.token.ts new file mode 100644 index 0000000000..28818474bb --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/listitem-picker-modal.token.ts @@ -0,0 +1,24 @@ +import { UmbModalToken } from './modal-token.js'; + +export interface UmbListitemPickerItem { + key: string; + name: string; + selected?: boolean; +} + +export interface UmbListitemPickerModalData { + headline: string; + items: UmbListitemPickerItem[]; + confirmLabel?: string; +} + +export type UmbListitemPickerModalValue = UmbListitemPickerItem['key'][] | undefined; + +export const UMB_LISTITEM_PICKER_MODAL = new UmbModalToken( + 'Umb.Modal.ListitemPicker', + { + modal: { + type: 'dialog', + }, + }, +); From 52880d20512adcb6a1542a9357935133bb76f452 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Wed, 7 Feb 2024 16:37:09 +0100 Subject: [PATCH 05/25] update modal docs --- .../storybook/stories/modal/modal.mdx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/storybook/stories/modal/modal.mdx b/src/Umbraco.Web.UI.Client/storybook/stories/modal/modal.mdx index 9ab2a75e24..ecf03d572b 100644 --- a/src/Umbraco.Web.UI.Client/storybook/stories/modal/modal.mdx +++ b/src/Umbraco.Web.UI.Client/storybook/stories/modal/modal.mdx @@ -174,14 +174,14 @@ A modal can be opened by calling the open method on the UmbModalManagerContext. ```ts import { html, LitElement } from '@umbraco-cms/backoffice/external/lit'; -import { UmbElementMixin } from '@umbraco-cms/element'; -import { UmbModalManagerContext, UMB_MODAL_CONTEXT_ALIAS } from '@umbraco-cms/modal'; +import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api'; +import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal'; class MyElement extends UmbElementMixin(LitElement) { - #modalManagerContext?: UmbmodalManagerContext; + #modalManagerContext?: typeof UMB_MODAL_MANAGER_CONTEXT.TYPE; constructor() { super(); - this.consumeContext(UMB_MODAL_CONTEXT, (instance) => { + this.consumeContext(UMB_MODAL_MANAGER_CONTEXT, (instance) => { this.#modalManagerContext = instance; // modalManagerContext is now ready to be used }); @@ -190,7 +190,7 @@ class MyElement extends UmbElementMixin(LitElement) { #onClick() { const data = {'data goes here'}; const value = {'initial value go here'}; - const modalContext = this.#modalManagerContext?.open(MY_MODAL_TOKEN), {data: data, value: value}); + const modalContext = this.#modalManagerContext?.open(MY_MODAL_TOKEN, {data: data, value: value}); modalContext?.onSubmit().then((value) => { // if modal submitted, then data is supplied here. From ac39b265b6fe4ef7cd6ca00173219201dca6c4eb Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Wed, 7 Feb 2024 16:39:03 +0100 Subject: [PATCH 06/25] preliminary use of listitem-picker modal --- .../workspace/document-workspace.context.ts | 52 +++++++++++++++---- 1 file changed, 43 insertions(+), 9 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts index 66ff979782..06b840a470 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts @@ -15,6 +15,11 @@ import { } from '@umbraco-cms/backoffice/workspace'; import { appendToFrozenArray, partialUpdateFrozenArray, UmbObjectState } from '@umbraco-cms/backoffice/observable-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import { + UMB_LISTITEM_PICKER_MODAL, + UMB_MODAL_MANAGER_CONTEXT, + type UmbListitemPickerModalData, +} from '@umbraco-cms/backoffice/modal'; type EntityType = UmbDocumentDetailModel; export class UmbDocumentWorkspaceContext @@ -44,9 +49,15 @@ export class UmbDocumentWorkspaceContext readonly structure = new UmbContentTypePropertyStructureManager(this, new UmbDocumentTypeDetailRepository(this)); readonly splitView = new UmbWorkspaceSplitViewManager(); + #modalManagerContext?: typeof UMB_MODAL_MANAGER_CONTEXT.TYPE; + constructor(host: UmbControllerHost) { super(host, UMB_DOCUMENT_WORKSPACE_ALIAS); + this.consumeContext(UMB_MODAL_MANAGER_CONTEXT, (instance) => { + this.#modalManagerContext = instance; + }); + this.observe(this.contentTypeUnique, (unique) => this.structure.loadType(unique)); /* @@ -168,26 +179,49 @@ export class UmbDocumentWorkspaceContext } } - async #selectVariants(): Promise { + async #selectVariants(): Promise { const currentData = this.getData(); if (!currentData) throw new Error('Data is missing'); - // TODO: Let user select variants. - return currentData.variants.map((x) => UmbVariantId.Create(x)); + // TODO: Use the available cultures + const availableVariants = currentData.variants; + + // If there is only one variant, we don't need to select anything. + if (availableVariants.length === 1) { + // TODO: Apply this when we have a way to get cultures + //return [UmbVariantId.Create(availableVariants[0])]; + } + + if (!this.#modalManagerContext) throw new Error('Modal manager context is missing'); + + const modalData: UmbListitemPickerModalData = { + headline: 'Select variants', + // TODO: Match the available variants to the available cultures. + items: availableVariants.map((x) => ({ key: x.culture!, name: x.name })), + }; + + const modalContext = this.#modalManagerContext.open(UMB_LISTITEM_PICKER_MODAL, { data: modalData }); + + const result = await modalContext.onSubmit().catch(() => undefined); + + if (!result) return null; + + // Match the result to the available variants. + return availableVariants.filter((x) => result.includes(x.culture!)).map((x) => UmbVariantId.Create(x)); } - async #createOrSave(): Promise { + async #createOrSave(): Promise { const data = this.getData(); if (!data) throw new Error('Data is missing'); if (!data.unique) throw new Error('Unique is missing'); const selectedVariants = await this.#selectVariants(); + // If no variants are selected, we don't save anything. + if (selectedVariants === null) return null; + // TODO: Use selected variants - console.log( - 'Saving', - selectedVariants.map((x) => x.culture), - ); + console.log('Saving', selectedVariants?.map((x) => x.culture)); if (this.getIsNew()) { if ((await this.repository.create(data)).data !== undefined) { @@ -210,7 +244,7 @@ export class UmbDocumentWorkspaceContext public async publish() { const variantIds = await this.#createOrSave(); const unique = this.getEntityId(); - if (variantIds.length && unique) { + if (variantIds?.length && unique) { await this.publishingRepository.publish(unique, variantIds); } } From cebb2b6aac92237c8c55ef84cf06a6d5f7056d4e Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Thu, 8 Feb 2024 11:23:22 +0100 Subject: [PATCH 07/25] set data before submitting --- .../listitem-picker-modal.element.ts | 24 +++++++++---------- .../token/listitem-picker-modal.token.ts | 4 +++- .../workspace/document-workspace.context.ts | 18 ++++++++------ 3 files changed, 26 insertions(+), 20 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/listitem-picker/listitem-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/listitem-picker/listitem-picker-modal.element.ts index 1049a71ee2..bcad2321cf 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/listitem-picker/listitem-picker-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/listitem-picker/listitem-picker-modal.element.ts @@ -2,23 +2,22 @@ import type { UmbListitemPickerModalData, UmbListitemPickerModalValue, } from '../../token/listitem-picker-modal.token.js'; -import type { UmbModalContext } from '../../modal.context.js'; -import { html, customElement, property, ifDefined, repeat } from '@umbraco-cms/backoffice/external/lit'; +import { UmbModalBaseElement } from '../../modal-element.element.js'; +import { html, customElement, ifDefined, repeat } from '@umbraco-cms/backoffice/external/lit'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; -import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-listitem-picker-modal') -export class UmbListitemPickerModalElement extends UmbLitElement { - @property({ attribute: false }) - modalContext?: UmbModalContext; - - @property({ type: Object, attribute: false }) - data?: UmbListitemPickerModalData; - +export class UmbListitemPickerModalElement extends UmbModalBaseElement< + UmbListitemPickerModalData, + UmbListitemPickerModalValue +> { private _handleSubmit(e: SubmitEvent) { e.preventDefault(); - debugger; - //this.modalContext?.submit(); + const form = e.target as HTMLFormElement; + const formData = new FormData(form); + const selectedItems = formData.getAll('listitem').map((item) => item.toString()); + this.modalContext?.setValue({ selection: selectedItems }); + this.modalContext?.submit(); } private _handleCancel() { @@ -34,6 +33,7 @@ export class UmbListitemPickerModalElement extends UmbLitElement { return html``; }, )} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/listitem-picker-modal.token.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/listitem-picker-modal.token.ts index 28818474bb..de8494ea23 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/listitem-picker-modal.token.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/listitem-picker-modal.token.ts @@ -12,7 +12,9 @@ export interface UmbListitemPickerModalData { confirmLabel?: string; } -export type UmbListitemPickerModalValue = UmbListitemPickerItem['key'][] | undefined; +export type UmbListitemPickerModalValue = { + selection: UmbListitemPickerItem['key'][]; +}; export const UMB_LISTITEM_PICKER_MODAL = new UmbModalToken( 'Umb.Modal.ListitemPicker', diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts index 06b840a470..6094707fa3 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts @@ -179,7 +179,7 @@ export class UmbDocumentWorkspaceContext } } - async #selectVariants(): Promise { + async #selectVariants(): Promise { const currentData = this.getData(); if (!currentData) throw new Error('Data is missing'); @@ -203,14 +203,18 @@ export class UmbDocumentWorkspaceContext const modalContext = this.#modalManagerContext.open(UMB_LISTITEM_PICKER_MODAL, { data: modalData }); const result = await modalContext.onSubmit().catch(() => undefined); + debugger; - if (!result) return null; + if (!result) return []; // Match the result to the available variants. - return availableVariants.filter((x) => result.includes(x.culture!)).map((x) => UmbVariantId.Create(x)); + const variantIds = availableVariants + .filter((x) => result.selection.includes(x.culture!)) + .map((x) => UmbVariantId.Create(x)); + return variantIds; } - async #createOrSave(): Promise { + async #createOrSave(): Promise { const data = this.getData(); if (!data) throw new Error('Data is missing'); if (!data.unique) throw new Error('Unique is missing'); @@ -218,7 +222,7 @@ export class UmbDocumentWorkspaceContext const selectedVariants = await this.#selectVariants(); // If no variants are selected, we don't save anything. - if (selectedVariants === null) return null; + if (!selectedVariants.length) return []; // TODO: Use selected variants console.log('Saving', selectedVariants?.map((x) => x.culture)); @@ -244,7 +248,7 @@ export class UmbDocumentWorkspaceContext public async publish() { const variantIds = await this.#createOrSave(); const unique = this.getEntityId(); - if (variantIds?.length && unique) { + if (variantIds.length && unique) { await this.publishingRepository.publish(unique, variantIds); } } @@ -256,7 +260,7 @@ export class UmbDocumentWorkspaceContext public async unpublish() { const variantIds = await this.#selectVariants(); const unique = this.getEntityId(); - if (variantIds && unique) { + if (variantIds.length && unique) { await this.publishingRepository.unpublish(unique, variantIds); } } From ff6076d68bc9a164d82fd250591dbb2cafddaa3f Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Thu, 8 Feb 2024 12:09:16 +0100 Subject: [PATCH 08/25] add new document language picker modal --- .../packages/documents/documents/manifests.ts | 2 + .../documents/documents/modals/index.ts | 2 + .../documents/modals/language-picker/index.ts | 1 + .../language-picker-modal.element.ts | 90 +++++++++++++++++++ .../language-picker-modal.token.ts | 23 +++++ .../documents/documents/modals/manifests.ts | 14 +++ .../workspace/document-workspace.context.ts | 21 ++--- 7 files changed, 141 insertions(+), 12 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/index.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/language-picker/index.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/language-picker/language-picker-modal.element.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/language-picker/language-picker-modal.token.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/manifests.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/manifests.ts index ba7ad261ff..dbd160f8a9 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/manifests.ts @@ -9,6 +9,7 @@ import { manifests as propertyEditorManifests } from './property-editors/manifes import { manifests as userPermissionManifests } from './user-permissions/manifests.js'; import { manifests as recycleBinManifests } from './recycle-bin/manifests.js'; import { manifests as trackedReferenceManifests } from './tracked-reference/manifests.js'; +import { manifests as modalManifests } from './modals/manifests.js'; export const manifests = [ ...collectionManifests, @@ -22,4 +23,5 @@ export const manifests = [ ...userPermissionManifests, ...recycleBinManifests, ...trackedReferenceManifests, + ...modalManifests, ]; 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 new file mode 100644 index 0000000000..10b774e558 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/index.ts @@ -0,0 +1,2 @@ +export * from './manifests.js'; +export * from './language-picker/index.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/language-picker/index.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/language-picker/index.ts new file mode 100644 index 0000000000..21ea4cf9a8 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/language-picker/index.ts @@ -0,0 +1 @@ +export * from './language-picker-modal.token.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/language-picker/language-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/language-picker/language-picker-modal.element.ts new file mode 100644 index 0000000000..fafe3c4449 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/language-picker/language-picker-modal.element.ts @@ -0,0 +1,90 @@ +import type { + UmbDocumentLanguagePickerModalValue, + UmbDocumentLanguagePickerModalData, +} from './language-picker-modal.token.js'; +import { UmbLanguageCollectionRepository } from '@umbraco-cms/backoffice/language'; +import type { UmbLanguageItemModel } from '@umbraco-cms/backoffice/language'; +import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; +import { css, html, customElement, state, repeat, ifDefined } from '@umbraco-cms/backoffice/external/lit'; +import { UmbSelectionManager } from '@umbraco-cms/backoffice/utils'; +import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal'; + +@customElement('umb-document-language-picker-modal') +export class UmbDocumentLanguagePickerModalElement extends UmbModalBaseElement< + UmbDocumentLanguagePickerModalData, + UmbDocumentLanguagePickerModalValue +> { + @state() + private _languages: Array = []; + + #collectionRepository = new UmbLanguageCollectionRepository(this); + #selectionManager = new UmbSelectionManager(this); + + connectedCallback(): void { + super.connectedCallback(); + this.#selectionManager.setSelectable(true); + this.#selectionManager.setMultiple(true); + this.#selectionManager.setSelection(this.value?.selection ?? []); + } + + async firstUpdated() { + const { data } = await this.#collectionRepository.requestCollection({ skip: 0, take: 1000 }); + this._languages = data?.items ?? []; + } + + get #filteredLanguages() { + if (this.data?.filter) { + return this._languages.filter(this.data.filter); + } else { + return this._languages; + } + } + + #submit() { + this.value = { selection: this.#selectionManager.getSelection() }; + this.modalContext?.submit(); + } + + #close() { + this.modalContext?.reject(); + } + + render() { + return html` + + ${repeat( + this.#filteredLanguages, + (item) => item.unique, + (item) => html` + this.#selectionManager.select(item.unique)} + @deselected=${() => this.#selectionManager.deselect(item.unique)} + ?selected=${this.#selectionManager.isSelected(item.unique)}> + + + `, + )} + +
+ + +
+
`; + } + + static styles = [UmbTextStyles, css``]; +} + +export default UmbDocumentLanguagePickerModalElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-document-language-picker-modal': UmbDocumentLanguagePickerModalElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/language-picker/language-picker-modal.token.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/language-picker/language-picker-modal.token.ts new file mode 100644 index 0000000000..eae7570126 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/language-picker/language-picker-modal.token.ts @@ -0,0 +1,23 @@ +import { UMB_DOCUMENT_LANGUAGE_PICKER_MODAL_ALIAS } from '../manifests.js'; +import type { UmbLanguageItemModel } from '@umbraco-cms/backoffice/language'; +import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; + +export interface UmbDocumentLanguagePickerModalData { + filter?: (language: UmbLanguageItemModel) => boolean; + headline: string; + confirmLabel?: string; +} + +export interface UmbDocumentLanguagePickerModalValue { + selection: Array; +} + +export const UMB_LANGUAGE_PICKER_MODAL = new UmbModalToken< + UmbDocumentLanguagePickerModalData, + UmbDocumentLanguagePickerModalValue +>(UMB_DOCUMENT_LANGUAGE_PICKER_MODAL_ALIAS, { + modal: { + type: 'dialog', + size: 'small', + }, +}); 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 new file mode 100644 index 0000000000..df2e265c23 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/manifests.ts @@ -0,0 +1,14 @@ +import type { ManifestModal } from '@umbraco-cms/backoffice/extension-registry'; + +export const UMB_DOCUMENT_LANGUAGE_PICKER_MODAL_ALIAS = 'Umb.Modal.DocumentLanguagePicker'; + +const modals: Array = [ + { + type: 'modal', + alias: UMB_DOCUMENT_LANGUAGE_PICKER_MODAL_ALIAS, + name: 'Document Language Picker Modal', + js: () => import('./language-picker/language-picker-modal.element.js'), + }, +]; + +export const manifests = [...modals]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts index 6094707fa3..8b5e00b9ba 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts @@ -3,6 +3,11 @@ import { UmbDocumentPropertyDataContext } from '../property-dataset-context/docu import { UMB_DOCUMENT_ENTITY_TYPE } from '../entity.js'; import { UmbDocumentDetailRepository } from '../repository/index.js'; import type { UmbDocumentDetailModel } from '../types.js'; +import { + type UmbDocumentLanguagePickerModalData, + UMB_DOCUMENT_LANGUAGE_PICKER_MODAL_ALIAS, + UMB_LANGUAGE_PICKER_MODAL, +} from '../modals/index.js'; import { UmbDocumentPublishingRepository } from '../repository/publishing/index.js'; import { UMB_DOCUMENT_WORKSPACE_ALIAS } from './manifests.js'; import { UmbVariantId } from '@umbraco-cms/backoffice/variant'; @@ -15,11 +20,7 @@ import { } from '@umbraco-cms/backoffice/workspace'; import { appendToFrozenArray, partialUpdateFrozenArray, UmbObjectState } from '@umbraco-cms/backoffice/observable-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; -import { - UMB_LISTITEM_PICKER_MODAL, - UMB_MODAL_MANAGER_CONTEXT, - type UmbListitemPickerModalData, -} from '@umbraco-cms/backoffice/modal'; +import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal'; type EntityType = UmbDocumentDetailModel; export class UmbDocumentWorkspaceContext @@ -183,27 +184,23 @@ export class UmbDocumentWorkspaceContext const currentData = this.getData(); if (!currentData) throw new Error('Data is missing'); - // TODO: Use the available cultures const availableVariants = currentData.variants; // If there is only one variant, we don't need to select anything. if (availableVariants.length === 1) { - // TODO: Apply this when we have a way to get cultures + // TODO: Apply this when the server returns all variants //return [UmbVariantId.Create(availableVariants[0])]; } if (!this.#modalManagerContext) throw new Error('Modal manager context is missing'); - const modalData: UmbListitemPickerModalData = { + const modalData: UmbDocumentLanguagePickerModalData = { headline: 'Select variants', - // TODO: Match the available variants to the available cultures. - items: availableVariants.map((x) => ({ key: x.culture!, name: x.name })), }; - const modalContext = this.#modalManagerContext.open(UMB_LISTITEM_PICKER_MODAL, { data: modalData }); + const modalContext = this.#modalManagerContext.open(UMB_LANGUAGE_PICKER_MODAL, { data: modalData }); const result = await modalContext.onSubmit().catch(() => undefined); - debugger; if (!result) return []; From 55ff84d63f4afa9231a08c974717b743e4aaa63e Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Thu, 8 Feb 2024 12:38:18 +0100 Subject: [PATCH 09/25] update modal --- ...document-language-picker-modal.element.ts} | 89 ++++++++++++++----- ...> document-language-picker-modal.token.ts} | 5 +- .../documents/modals/language-picker/index.ts | 2 +- .../documents/documents/modals/manifests.ts | 2 +- .../workspace/document-workspace.context.ts | 22 ++--- 5 files changed, 80 insertions(+), 40 deletions(-) rename src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/language-picker/{language-picker-modal.element.ts => document-language-picker-modal.element.ts} (50%) rename src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/language-picker/{language-picker-modal.token.ts => document-language-picker-modal.token.ts} (82%) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/language-picker/language-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/language-picker/document-language-picker-modal.element.ts similarity index 50% rename from src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/language-picker/language-picker-modal.element.ts rename to src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/language-picker/document-language-picker-modal.element.ts index fafe3c4449..3f21e56d4c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/language-picker/language-picker-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/language-picker/document-language-picker-modal.element.ts @@ -1,11 +1,11 @@ import type { UmbDocumentLanguagePickerModalValue, UmbDocumentLanguagePickerModalData, -} from './language-picker-modal.token.js'; +} from './document-language-picker-modal.token.js'; import { UmbLanguageCollectionRepository } from '@umbraco-cms/backoffice/language'; import type { UmbLanguageItemModel } from '@umbraco-cms/backoffice/language'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; -import { css, html, customElement, state, repeat, ifDefined } from '@umbraco-cms/backoffice/external/lit'; +import { css, html, customElement, state, repeat } from '@umbraco-cms/backoffice/external/lit'; import { UmbSelectionManager } from '@umbraco-cms/backoffice/utils'; import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal'; @@ -40,6 +40,45 @@ export class UmbDocumentLanguagePickerModalElement extends UmbModalBaseElement< } } + get #headline(): string { + switch (this.data?.type) { + case 'publish': + return 'content_readyToPublish'; + case 'unpublish': + return 'content_unpublish'; + case 'schedule': + return 'content_readyToPublish'; + default: + return 'content_readyToSave'; + } + } + + get #subtitle(): string { + switch (this.data?.type) { + case 'publish': + return 'content_variantsToPublish'; + case 'unpublish': + return 'content_languagesToUnpublish'; + case 'schedule': + return 'content_languagesToSchedule'; + default: + return 'content_variantsToSave'; + } + } + + get #confirmLabel(): string { + switch (this.data?.type) { + case 'publish': + return 'buttons_saveAndPublish'; + case 'unpublish': + return 'actions_unpublish'; + case 'schedule': + return 'buttons_schedulePublish'; + default: + return 'buttons_saveAndClose'; + } + } + #submit() { this.value = { selection: this.#selectionManager.getSelection() }; this.modalContext?.submit(); @@ -50,27 +89,26 @@ export class UmbDocumentLanguagePickerModalElement extends UmbModalBaseElement< } render() { - return html` - - ${repeat( - this.#filteredLanguages, - (item) => item.unique, - (item) => html` - this.#selectionManager.select(item.unique)} - @deselected=${() => this.#selectionManager.deselect(item.unique)} - ?selected=${this.#selectionManager.isSelected(item.unique)}> - - - `, - )} - + return html` +

${this.localize.term(this.#subtitle)}

+ ${repeat( + this.#filteredLanguages, + (item) => item.unique, + (item) => html` + this.#selectionManager.select(item.unique)} + @deselected=${() => this.#selectionManager.deselect(item.unique)} + ?selected=${this.#selectionManager.isSelected(item.unique)}> + + + `, + )}
- + @@ -78,7 +116,14 @@ export class UmbDocumentLanguagePickerModalElement extends UmbModalBaseElement< `; } - static styles = [UmbTextStyles, css``]; + static styles = [ + UmbTextStyles, + css` + #subtitle { + margin-top: 0; + } + `, + ]; } export default UmbDocumentLanguagePickerModalElement; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/language-picker/language-picker-modal.token.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/language-picker/document-language-picker-modal.token.ts similarity index 82% rename from src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/language-picker/language-picker-modal.token.ts rename to src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/language-picker/document-language-picker-modal.token.ts index eae7570126..b47b8e1e90 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/language-picker/language-picker-modal.token.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/language-picker/document-language-picker-modal.token.ts @@ -4,15 +4,14 @@ import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; export interface UmbDocumentLanguagePickerModalData { filter?: (language: UmbLanguageItemModel) => boolean; - headline: string; - confirmLabel?: string; + type: 'save' | 'publish' | 'schedule' | 'unpublish'; } export interface UmbDocumentLanguagePickerModalValue { selection: Array; } -export const UMB_LANGUAGE_PICKER_MODAL = new UmbModalToken< +export const UMB_DOCUMENT_LANGUAGE_PICKER_MODAL = new UmbModalToken< UmbDocumentLanguagePickerModalData, UmbDocumentLanguagePickerModalValue >(UMB_DOCUMENT_LANGUAGE_PICKER_MODAL_ALIAS, { diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/language-picker/index.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/language-picker/index.ts index 21ea4cf9a8..452e8ee73e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/language-picker/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/language-picker/index.ts @@ -1 +1 @@ -export * from './language-picker-modal.token.js'; +export * from './document-language-picker-modal.token.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 df2e265c23..121e704d7b 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 @@ -7,7 +7,7 @@ const modals: Array = [ type: 'modal', alias: UMB_DOCUMENT_LANGUAGE_PICKER_MODAL_ALIAS, name: 'Document Language Picker Modal', - js: () => import('./language-picker/language-picker-modal.element.js'), + js: () => import('./language-picker/document-language-picker-modal.element.js'), }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts index 8b5e00b9ba..487502874e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts @@ -3,11 +3,7 @@ import { UmbDocumentPropertyDataContext } from '../property-dataset-context/docu import { UMB_DOCUMENT_ENTITY_TYPE } from '../entity.js'; import { UmbDocumentDetailRepository } from '../repository/index.js'; import type { UmbDocumentDetailModel } from '../types.js'; -import { - type UmbDocumentLanguagePickerModalData, - UMB_DOCUMENT_LANGUAGE_PICKER_MODAL_ALIAS, - UMB_LANGUAGE_PICKER_MODAL, -} from '../modals/index.js'; +import { type UmbDocumentLanguagePickerModalData, UMB_DOCUMENT_LANGUAGE_PICKER_MODAL } from '../modals/index.js'; import { UmbDocumentPublishingRepository } from '../repository/publishing/index.js'; import { UMB_DOCUMENT_WORKSPACE_ALIAS } from './manifests.js'; import { UmbVariantId } from '@umbraco-cms/backoffice/variant'; @@ -180,7 +176,7 @@ export class UmbDocumentWorkspaceContext } } - async #selectVariants(): Promise { + async #selectVariants(type: UmbDocumentLanguagePickerModalData['type']): Promise { const currentData = this.getData(); if (!currentData) throw new Error('Data is missing'); @@ -195,10 +191,10 @@ export class UmbDocumentWorkspaceContext if (!this.#modalManagerContext) throw new Error('Modal manager context is missing'); const modalData: UmbDocumentLanguagePickerModalData = { - headline: 'Select variants', + type, }; - const modalContext = this.#modalManagerContext.open(UMB_LANGUAGE_PICKER_MODAL, { data: modalData }); + const modalContext = this.#modalManagerContext.open(UMB_DOCUMENT_LANGUAGE_PICKER_MODAL, { data: modalData }); const result = await modalContext.onSubmit().catch(() => undefined); @@ -211,12 +207,12 @@ export class UmbDocumentWorkspaceContext return variantIds; } - async #createOrSave(): Promise { + async #createOrSave(type: UmbDocumentLanguagePickerModalData['type']): Promise { const data = this.getData(); if (!data) throw new Error('Data is missing'); if (!data.unique) throw new Error('Unique is missing'); - const selectedVariants = await this.#selectVariants(); + const selectedVariants = await this.#selectVariants(type); // If no variants are selected, we don't save anything. if (!selectedVariants.length) return []; @@ -238,12 +234,12 @@ export class UmbDocumentWorkspaceContext async save() { const data = this.getData(); if (!data) throw new Error('Data is missing'); - await this.#createOrSave(); + await this.#createOrSave('save'); this.saveComplete(data); } public async publish() { - const variantIds = await this.#createOrSave(); + const variantIds = await this.#createOrSave('publish'); const unique = this.getEntityId(); if (variantIds.length && unique) { await this.publishingRepository.publish(unique, variantIds); @@ -255,7 +251,7 @@ export class UmbDocumentWorkspaceContext } public async unpublish() { - const variantIds = await this.#selectVariants(); + const variantIds = await this.#selectVariants('unpublish'); const unique = this.getEntityId(); if (variantIds.length && unique) { await this.publishingRepository.unpublish(unique, variantIds); From 348a629964dd71fcabb662511df5202a13e20c9e Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Thu, 8 Feb 2024 12:41:28 +0100 Subject: [PATCH 10/25] compare with lowercase --- .../documents/workspace/document-workspace.context.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts index 487502874e..1d9b41bb9e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts @@ -198,11 +198,13 @@ export class UmbDocumentWorkspaceContext const result = await modalContext.onSubmit().catch(() => undefined); - if (!result) return []; + if (!result?.selection.length) return []; + + const selectedVariants = result.selection.map((x) => x?.toLowerCase() ?? ''); // Match the result to the available variants. const variantIds = availableVariants - .filter((x) => result.selection.includes(x.culture!)) + .filter((x) => selectedVariants.includes(x.culture!)) .map((x) => UmbVariantId.Create(x)); return variantIds; } From c262588b54bfb4129e2307870da4ab036c6c9715 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Thu, 8 Feb 2024 14:07:13 +0100 Subject: [PATCH 11/25] select the active variant --- .../documents/workspace/document-workspace.context.ts | 10 ++++++---- .../language-collection.server.data-source.ts | 4 ++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts index 1d9b41bb9e..1e95488557 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts @@ -194,7 +194,12 @@ export class UmbDocumentWorkspaceContext type, }; - const modalContext = this.#modalManagerContext.open(UMB_DOCUMENT_LANGUAGE_PICKER_MODAL, { data: modalData }); + const activeVariants = this.splitView.getActiveVariants(); + const activeVariant = activeVariants[activeVariants.length - 1]; + const modalContext = this.#modalManagerContext.open(UMB_DOCUMENT_LANGUAGE_PICKER_MODAL, { + data: modalData, + value: { selection: activeVariant ? [activeVariant.culture] : [] }, + }); const result = await modalContext.onSubmit().catch(() => undefined); @@ -219,9 +224,6 @@ export class UmbDocumentWorkspaceContext // If no variants are selected, we don't save anything. if (!selectedVariants.length) return []; - // TODO: Use selected variants - console.log('Saving', selectedVariants?.map((x) => x.culture)); - if (this.getIsNew()) { if ((await this.repository.create(data)).data !== undefined) { this.setIsNew(false); diff --git a/src/Umbraco.Web.UI.Client/src/packages/language/collection/repository/language-collection.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/language/collection/repository/language-collection.server.data-source.ts index c7501b8b24..02f4591ec0 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/language/collection/repository/language-collection.server.data-source.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/language/collection/repository/language-collection.server.data-source.ts @@ -36,12 +36,12 @@ export class UmbLanguageCollectionServerDataSource implements UmbCollectionDataS if (data) { const items = data.items.map((item) => { const model: UmbLanguageDetailModel = { - unique: item.isoCode, + unique: item.isoCode.toLowerCase(), name: item.name, entityType: UMB_LANGUAGE_ENTITY_TYPE, isDefault: item.isDefault, isMandatory: item.isMandatory, - fallbackIsoCode: item.fallbackIsoCode || null, + fallbackIsoCode: item.fallbackIsoCode?.toLowerCase() || null, }; return model; From 60390a5668d56528dd2f0102539640a6d503a90f Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Thu, 8 Feb 2024 14:27:50 +0100 Subject: [PATCH 12/25] add published variants --- .../document-language-picker-modal.element.ts | 15 +++++++++++++++ .../document-language-picker-modal.token.ts | 1 + .../workspace/document-workspace.context.ts | 4 ++++ 3 files changed, 20 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/language-picker/document-language-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/language-picker/document-language-picker-modal.element.ts index 3f21e56d4c..15f22ad226 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/language-picker/document-language-picker-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/language-picker/document-language-picker-modal.element.ts @@ -102,6 +102,14 @@ export class UmbDocumentLanguagePickerModalElement extends UmbModalBaseElement< @deselected=${() => this.#selectionManager.deselect(item.unique)} ?selected=${this.#selectionManager.isSelected(item.unique)}> +
+ ${item.name} +
+ ${this.localize.term( + this.data?.publishedVariants.includes(item.unique) ? 'content_published' : 'content_unpublished', + )} +
+
`, )} @@ -122,6 +130,13 @@ export class UmbDocumentLanguagePickerModalElement extends UmbModalBaseElement< #subtitle { margin-top: 0; } + .label { + padding: 0.5rem 0; + } + .label-status { + font-size: 0.8rem; + color: rgba(var(--uui-color-text), 0.6); + } `, ]; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/language-picker/document-language-picker-modal.token.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/language-picker/document-language-picker-modal.token.ts index b47b8e1e90..3d646a8f33 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/language-picker/document-language-picker-modal.token.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/language-picker/document-language-picker-modal.token.ts @@ -5,6 +5,7 @@ import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; export interface UmbDocumentLanguagePickerModalData { filter?: (language: UmbLanguageItemModel) => boolean; type: 'save' | 'publish' | 'schedule' | 'unpublish'; + publishedVariants: Array; } export interface UmbDocumentLanguagePickerModalValue { diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts index 1e95488557..7d935ed6af 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts @@ -17,6 +17,7 @@ import { import { appendToFrozenArray, partialUpdateFrozenArray, UmbObjectState } from '@umbraco-cms/backoffice/observable-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal'; +import { DocumentVariantStateModel } from '@umbraco-cms/backoffice/backend-api'; type EntityType = UmbDocumentDetailModel; export class UmbDocumentWorkspaceContext @@ -192,6 +193,9 @@ export class UmbDocumentWorkspaceContext const modalData: UmbDocumentLanguagePickerModalData = { type, + publishedVariants: availableVariants + .filter((x) => x.state === DocumentVariantStateModel.PUBLISHED) + .map((x) => x.culture?.toLowerCase() ?? ''), }; const activeVariants = this.splitView.getActiveVariants(); From fe37d7b53bc621f35e4211b3b2abdcf7e45343d9 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Tue, 20 Feb 2024 10:57:26 +0100 Subject: [PATCH 13/25] fix merge conflict with duplicate export of 'manifests' --- .../documents/user-permissions/constants.ts | 16 +++++++++ .../documents/user-permissions/index.ts | 2 +- .../documents/user-permissions/manifests.ts | 35 ++++++++++--------- 3 files changed, 35 insertions(+), 18 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/documents/documents/user-permissions/constants.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/user-permissions/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/user-permissions/constants.ts new file mode 100644 index 0000000000..7dd4b77160 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/user-permissions/constants.ts @@ -0,0 +1,16 @@ +export const UMB_USER_PERMISSION_DOCUMENT_CREATE = 'Umb.UserPermission.Document.Create'; +export const UMB_USER_PERMISSION_DOCUMENT_READ = 'Umb.UserPermission.Document.Read'; +export const UMB_USER_PERMISSION_DOCUMENT_UPDATE = 'Umb.UserPermission.Document.Update'; +export const UMB_USER_PERMISSION_DOCUMENT_DELETE = 'Umb.UserPermission.Document.Delete'; +export const UMB_USER_PERMISSION_DOCUMENT_CREATE_BLUEPRINT = 'Umb.UserPermission.Document.CreateBlueprint'; +export const UMB_USER_PERMISSION_DOCUMENT_NOTIFICATIONS = 'Umb.UserPermission.Document.Notifications'; +export const UMB_USER_PERMISSION_DOCUMENT_PUBLISH = 'Umb.UserPermission.Document.Publish'; +export const UMB_USER_PERMISSION_DOCUMENT_PERMISSIONS = 'Umb.UserPermission.Document.Permissions'; +export const UMB_USER_PERMISSION_DOCUMENT_SEND_FOR_APPROVAL = 'Umb.UserPermission.Document.SendForApproval'; +export const UMB_USER_PERMISSION_DOCUMENT_UNPUBLISH = 'Umb.UserPermission.Document.Unpublish'; +export const UMB_USER_PERMISSION_DOCUMENT_COPY = 'Umb.UserPermission.Document.Copy'; +export const UMB_USER_PERMISSION_DOCUMENT_MOVE = 'Umb.UserPermission.Document.Move'; +export const UMB_USER_PERMISSION_DOCUMENT_SORT = 'Umb.UserPermission.Document.Sort'; +export const UMB_USER_PERMISSION_DOCUMENT_CULTURE_AND_HOSTNAMES = 'Umb.UserPermission.Document.CultureAndHostnames'; +export const UMB_USER_PERMISSION_DOCUMENT_PUBLIC_ACCESS = 'Umb.UserPermission.Document.PublicAccess'; +export const UMB_USER_PERMISSION_DOCUMENT_ROLLBACK = 'Umb.UserPermission.Document.Rollback'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/user-permissions/index.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/user-permissions/index.ts index 78c94f0582..4991633288 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/user-permissions/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/user-permissions/index.ts @@ -1,2 +1,2 @@ -export * from './manifests.js'; export * from './repository/index.js'; +export * from './constants.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/user-permissions/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/user-permissions/manifests.ts index 6269ef72e6..a52ddc411c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/user-permissions/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/user-permissions/manifests.ts @@ -1,26 +1,27 @@ +import { + UMB_USER_PERMISSION_DOCUMENT_READ, + UMB_USER_PERMISSION_DOCUMENT_CREATE_BLUEPRINT, + UMB_USER_PERMISSION_DOCUMENT_DELETE, + UMB_USER_PERMISSION_DOCUMENT_CREATE, + UMB_USER_PERMISSION_DOCUMENT_NOTIFICATIONS, + UMB_USER_PERMISSION_DOCUMENT_PUBLISH, + UMB_USER_PERMISSION_DOCUMENT_PERMISSIONS, + UMB_USER_PERMISSION_DOCUMENT_SEND_FOR_APPROVAL, + UMB_USER_PERMISSION_DOCUMENT_UNPUBLISH, + UMB_USER_PERMISSION_DOCUMENT_UPDATE, + UMB_USER_PERMISSION_DOCUMENT_COPY, + UMB_USER_PERMISSION_DOCUMENT_MOVE, + UMB_USER_PERMISSION_DOCUMENT_SORT, + UMB_USER_PERMISSION_DOCUMENT_CULTURE_AND_HOSTNAMES, + UMB_USER_PERMISSION_DOCUMENT_PUBLIC_ACCESS, + UMB_USER_PERMISSION_DOCUMENT_ROLLBACK, +} from './constants.js'; import { manifests as repositoryManifests } from './repository/manifests.js'; import type { ManifestUserGranularPermission, ManifestUserPermission, } from '@umbraco-cms/backoffice/extension-registry'; -export const UMB_USER_PERMISSION_DOCUMENT_CREATE = 'Umb.UserPermission.Document.Create'; -export const UMB_USER_PERMISSION_DOCUMENT_READ = 'Umb.UserPermission.Document.Read'; -export const UMB_USER_PERMISSION_DOCUMENT_UPDATE = 'Umb.UserPermission.Document.Update'; -export const UMB_USER_PERMISSION_DOCUMENT_DELETE = 'Umb.UserPermission.Document.Delete'; -export const UMB_USER_PERMISSION_DOCUMENT_CREATE_BLUEPRINT = 'Umb.UserPermission.Document.CreateBlueprint'; -export const UMB_USER_PERMISSION_DOCUMENT_NOTIFICATIONS = 'Umb.UserPermission.Document.Notifications'; -export const UMB_USER_PERMISSION_DOCUMENT_PUBLISH = 'Umb.UserPermission.Document.Publish'; -export const UMB_USER_PERMISSION_DOCUMENT_PERMISSIONS = 'Umb.UserPermission.Document.Permissions'; -export const UMB_USER_PERMISSION_DOCUMENT_SEND_FOR_APPROVAL = 'Umb.UserPermission.Document.SendForApproval'; -export const UMB_USER_PERMISSION_DOCUMENT_UNPUBLISH = 'Umb.UserPermission.Document.Unpublish'; -export const UMB_USER_PERMISSION_DOCUMENT_COPY = 'Umb.UserPermission.Document.Copy'; -export const UMB_USER_PERMISSION_DOCUMENT_MOVE = 'Umb.UserPermission.Document.Move'; -export const UMB_USER_PERMISSION_DOCUMENT_SORT = 'Umb.UserPermission.Document.Sort'; -export const UMB_USER_PERMISSION_DOCUMENT_CULTURE_AND_HOSTNAMES = 'Umb.UserPermission.Document.CultureAndHostnames'; -export const UMB_USER_PERMISSION_DOCUMENT_PUBLIC_ACCESS = 'Umb.UserPermission.Document.PublicAccess'; -export const UMB_USER_PERMISSION_DOCUMENT_ROLLBACK = 'Umb.UserPermission.Document.Rollback'; - const permissions: Array = [ { type: 'userPermission', From 648cf4ec8b7d4a5cd1dce4a89edfd41dbd20c3a7 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Tue, 20 Feb 2024 11:01:06 +0100 Subject: [PATCH 14/25] rename to variant picker and display variant information --- .../src/packages/documents/documents/index.ts | 1 + .../documents/documents/modals/index.ts | 3 +- .../documents/modals/language-picker/index.ts | 1 - .../documents/documents/modals/manifests.ts | 8 ++--- .../document-variant-picker-modal.element.ts} | 29 ++++++++++--------- .../document-variant-picker-modal.token.ts} | 15 +++++----- .../documents/modals/variant-picker/index.ts | 1 + .../src/packages/documents/documents/types.ts | 5 ++-- .../workspace/document-workspace.context.ts | 24 +++++++-------- 9 files changed, 43 insertions(+), 44 deletions(-) delete mode 100644 src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/language-picker/index.ts rename src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/{language-picker/document-language-picker-modal.element.ts => variant-picker/document-variant-picker-modal.element.ts} (80%) rename src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/{language-picker/document-language-picker-modal.token.ts => variant-picker/document-variant-picker-modal.token.ts} (50%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/index.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/index.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/index.ts index 500b000e79..80990995f5 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/index.ts @@ -9,6 +9,7 @@ export * from './components/index.js'; export * from './entity.js'; export * from './entity-actions/index.js'; export * from './conditions/index.js'; +export * from './modals/index.js'; export { UMB_DOCUMENT_TREE_ALIAS } from './tree/index.js'; export { UMB_CONTENT_MENU_ALIAS } from './menu.manifests.js'; 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 10b774e558..6db24e7b9a 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,2 +1 @@ -export * from './manifests.js'; -export * from './language-picker/index.js'; +export * from './variant-picker/index.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/language-picker/index.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/language-picker/index.ts deleted file mode 100644 index 452e8ee73e..0000000000 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/language-picker/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './document-language-picker-modal.token.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 121e704d7b..758fbc4314 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,13 +1,13 @@ import type { ManifestModal } from '@umbraco-cms/backoffice/extension-registry'; -export const UMB_DOCUMENT_LANGUAGE_PICKER_MODAL_ALIAS = 'Umb.Modal.DocumentLanguagePicker'; +export const UMB_DOCUMENT_VARIANT_PICKER_MODAL_ALIAS = 'Umb.Modal.DocumentVariantPicker'; const modals: Array = [ { type: 'modal', - alias: UMB_DOCUMENT_LANGUAGE_PICKER_MODAL_ALIAS, - name: 'Document Language Picker Modal', - js: () => import('./language-picker/document-language-picker-modal.element.js'), + alias: UMB_DOCUMENT_VARIANT_PICKER_MODAL_ALIAS, + name: 'Document Variant Picker Modal', + js: () => import('./variant-picker/document-variant-picker-modal.element.js'), }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/language-picker/document-language-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.element.ts similarity index 80% rename from src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/language-picker/document-language-picker-modal.element.ts rename to src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.element.ts index 15f22ad226..0ff930e242 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/language-picker/document-language-picker-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.element.ts @@ -1,7 +1,8 @@ +import { UmbDocumentVariantState } from '../../types.js'; import type { - UmbDocumentLanguagePickerModalValue, - UmbDocumentLanguagePickerModalData, -} from './document-language-picker-modal.token.js'; + UmbDocumentVariantPickerModalValue, + UmbDocumentVariantPickerModalData, +} from './document-variant-picker-modal.token.js'; import { UmbLanguageCollectionRepository } from '@umbraco-cms/backoffice/language'; import type { UmbLanguageItemModel } from '@umbraco-cms/backoffice/language'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; @@ -10,9 +11,9 @@ import { UmbSelectionManager } from '@umbraco-cms/backoffice/utils'; import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal'; @customElement('umb-document-language-picker-modal') -export class UmbDocumentLanguagePickerModalElement extends UmbModalBaseElement< - UmbDocumentLanguagePickerModalData, - UmbDocumentLanguagePickerModalValue +export class UmbDocumentVariantPickerModalElement extends UmbModalBaseElement< + UmbDocumentVariantPickerModalData, + UmbDocumentVariantPickerModalValue > { @state() private _languages: Array = []; @@ -92,21 +93,21 @@ export class UmbDocumentLanguagePickerModalElement extends UmbModalBaseElement< return html`

${this.localize.term(this.#subtitle)}

${repeat( - this.#filteredLanguages, - (item) => item.unique, + this.data?.variants ?? [], + (item) => item.culture, (item) => html` this.#selectionManager.select(item.unique)} - @deselected=${() => this.#selectionManager.deselect(item.unique)} - ?selected=${this.#selectionManager.isSelected(item.unique)}> + @selected=${() => this.#selectionManager.select(item.culture)} + @deselected=${() => this.#selectionManager.deselect(item.culture)} + ?selected=${this.#selectionManager.isSelected(item.culture)}>
${item.name}
${this.localize.term( - this.data?.publishedVariants.includes(item.unique) ? 'content_published' : 'content_unpublished', + item.state === UmbDocumentVariantState.PUBLISHED ? 'content_published' : 'content_unpublished', )}
@@ -141,10 +142,10 @@ export class UmbDocumentLanguagePickerModalElement extends UmbModalBaseElement< ]; } -export default UmbDocumentLanguagePickerModalElement; +export default UmbDocumentVariantPickerModalElement; declare global { interface HTMLElementTagNameMap { - 'umb-document-language-picker-modal': UmbDocumentLanguagePickerModalElement; + 'umb-document-language-picker-modal': UmbDocumentVariantPickerModalElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/language-picker/document-language-picker-modal.token.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.token.ts similarity index 50% rename from src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/language-picker/document-language-picker-modal.token.ts rename to src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.token.ts index 3d646a8f33..ca51c9da11 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/language-picker/document-language-picker-modal.token.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.token.ts @@ -1,21 +1,22 @@ -import { UMB_DOCUMENT_LANGUAGE_PICKER_MODAL_ALIAS } from '../manifests.js'; +import { UMB_DOCUMENT_VARIANT_PICKER_MODAL_ALIAS } from '../manifests.js'; +import type { UmbDocumentVariantModel } from '../../types.js'; import type { UmbLanguageItemModel } from '@umbraco-cms/backoffice/language'; import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; -export interface UmbDocumentLanguagePickerModalData { +export interface UmbDocumentVariantPickerModalData { filter?: (language: UmbLanguageItemModel) => boolean; type: 'save' | 'publish' | 'schedule' | 'unpublish'; - publishedVariants: Array; + variants: Array; } -export interface UmbDocumentLanguagePickerModalValue { +export interface UmbDocumentVariantPickerModalValue { selection: Array; } export const UMB_DOCUMENT_LANGUAGE_PICKER_MODAL = new UmbModalToken< - UmbDocumentLanguagePickerModalData, - UmbDocumentLanguagePickerModalValue ->(UMB_DOCUMENT_LANGUAGE_PICKER_MODAL_ALIAS, { + UmbDocumentVariantPickerModalData, + UmbDocumentVariantPickerModalValue +>(UMB_DOCUMENT_VARIANT_PICKER_MODAL_ALIAS, { modal: { type: 'dialog', size: 'small', diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/index.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/index.ts new file mode 100644 index 0000000000..1c69ee726c --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/index.ts @@ -0,0 +1 @@ +export * from './document-variant-picker-modal.token.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/types.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/types.ts index 04fb86e3e8..b9a34927e6 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/types.ts @@ -1,6 +1,7 @@ import type { UmbDocumentEntityType } from './entity.js'; import type { UmbVariantModel } from '@umbraco-cms/backoffice/variant'; -import type { DocumentVariantStateModel } from '@umbraco-cms/backoffice/external/backend-api'; +import { DocumentVariantStateModel as UmbDocumentVariantState } from '@umbraco-cms/backoffice/external/backend-api'; +export { UmbDocumentVariantState }; export interface UmbDocumentDetailModel { documentType: { @@ -18,7 +19,7 @@ export interface UmbDocumentDetailModel { } export interface UmbDocumentVariantModel extends UmbVariantModel { - state: DocumentVariantStateModel | null; + state: UmbDocumentVariantState | null; publishDate: string | null; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts index aa014dca2a..8f28d274f5 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts @@ -3,7 +3,7 @@ import { UmbDocumentPropertyDataContext } from '../property-dataset-context/docu import { UMB_DOCUMENT_ENTITY_TYPE } from '../entity.js'; import { UmbDocumentDetailRepository } from '../repository/index.js'; import type { UmbDocumentDetailModel } from '../types.js'; -import { type UmbDocumentLanguagePickerModalData, UMB_DOCUMENT_LANGUAGE_PICKER_MODAL } from '../modals/index.js'; +import { type UmbDocumentVariantPickerModalData, UMB_DOCUMENT_LANGUAGE_PICKER_MODAL } from '../modals/index.js'; import { UmbDocumentPublishingRepository } from '../repository/publishing/index.js'; import { UMB_DOCUMENT_WORKSPACE_ALIAS } from './manifests.js'; import { UmbVariantId } from '@umbraco-cms/backoffice/variant'; @@ -186,25 +186,22 @@ export class UmbDocumentWorkspaceContext } } - async #selectVariants(type: UmbDocumentLanguagePickerModalData['type']): Promise { + async #selectVariants(type: UmbDocumentVariantPickerModalData['type']): Promise { const currentData = this.getData(); if (!currentData) throw new Error('Data is missing'); - const availableVariants = currentData.variants; + const variants = currentData.variants; // If there is only one variant, we don't need to select anything. - if (availableVariants.length === 1) { - // TODO: Apply this when the server returns all variants - //return [UmbVariantId.Create(availableVariants[0])]; + if (variants.length === 1) { + return [UmbVariantId.Create(variants[0])]; } if (!this.#modalManagerContext) throw new Error('Modal manager context is missing'); - const modalData: UmbDocumentLanguagePickerModalData = { + const modalData: UmbDocumentVariantPickerModalData = { type, - publishedVariants: availableVariants - .filter((x) => x.state === DocumentVariantStateModel.PUBLISHED) - .map((x) => x.culture?.toLowerCase() ?? ''), + variants, // TODO: Filter out variants that do not have any changes unless it is the current variant. }; const activeVariants = this.splitView.getActiveVariants(); @@ -221,13 +218,12 @@ export class UmbDocumentWorkspaceContext const selectedVariants = result.selection.map((x) => x?.toLowerCase() ?? ''); // Match the result to the available variants. - const variantIds = availableVariants - .filter((x) => selectedVariants.includes(x.culture!)) - .map((x) => UmbVariantId.Create(x)); + const variantIds = variants.filter((x) => selectedVariants.includes(x.culture!)).map((x) => UmbVariantId.Create(x)); + return variantIds; } - async #createOrSave(type: UmbDocumentLanguagePickerModalData['type']): Promise { + async #createOrSave(type: UmbDocumentVariantPickerModalData['type']): Promise { const data = this.getData(); if (!data) throw new Error('Data is missing'); if (!data.unique) throw new Error('Unique is missing'); From 6a642f54089aeae1a58dd2f249d9fe5ebd028ade Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Tue, 20 Feb 2024 11:07:54 +0100 Subject: [PATCH 15/25] add variant status --- .../document-variant-picker-modal.element.ts | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.element.ts index 0ff930e242..b90eb54e1f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.element.ts @@ -1,4 +1,4 @@ -import { UmbDocumentVariantState } from '../../types.js'; +import { type UmbDocumentVariantModel, UmbDocumentVariantState } from '../../types.js'; import type { UmbDocumentVariantPickerModalValue, UmbDocumentVariantPickerModalData, @@ -97,7 +97,7 @@ export class UmbDocumentVariantPickerModalElement extends UmbModalBaseElement< (item) => item.culture, (item) => html` this.#selectionManager.select(item.culture)} @deselected=${() => this.#selectionManager.deselect(item.culture)} @@ -105,11 +105,7 @@ export class UmbDocumentVariantPickerModalElement extends UmbModalBaseElement<
${item.name} -
- ${this.localize.term( - item.state === UmbDocumentVariantState.PUBLISHED ? 'content_published' : 'content_unpublished', - )} -
+
${this.#renderVariantStatus(item)}
`, @@ -125,6 +121,19 @@ export class UmbDocumentVariantPickerModalElement extends UmbModalBaseElement<
`; } + #renderVariantStatus(variant: UmbDocumentVariantModel) { + switch (variant.state) { + case UmbDocumentVariantState.PUBLISHED: + return this.localize.term('content_published'); + case UmbDocumentVariantState.PUBLISHED_PENDING_CHANGES: + return this.localize.term('content_publishedPendingChanges'); + case UmbDocumentVariantState.NOT_CREATED: + case UmbDocumentVariantState.DRAFT: + default: + return this.localize.term('content_unpublished'); + } + } + static styles = [ UmbTextStyles, css` From 33e1b7151d2b864cc9b343028424e41a47fa6dda Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Tue, 20 Feb 2024 11:17:36 +0100 Subject: [PATCH 16/25] remove languages --- .../document-variant-picker-modal.element.ts | 21 +------------------ .../document-variant-picker-modal.token.ts | 2 -- 2 files changed, 1 insertion(+), 22 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.element.ts index b90eb54e1f..3c627d924e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.element.ts @@ -3,10 +3,8 @@ import type { UmbDocumentVariantPickerModalValue, UmbDocumentVariantPickerModalData, } from './document-variant-picker-modal.token.js'; -import { UmbLanguageCollectionRepository } from '@umbraco-cms/backoffice/language'; -import type { UmbLanguageItemModel } from '@umbraco-cms/backoffice/language'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; -import { css, html, customElement, state, repeat } from '@umbraco-cms/backoffice/external/lit'; +import { css, html, customElement, repeat } from '@umbraco-cms/backoffice/external/lit'; import { UmbSelectionManager } from '@umbraco-cms/backoffice/utils'; import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal'; @@ -15,10 +13,6 @@ export class UmbDocumentVariantPickerModalElement extends UmbModalBaseElement< UmbDocumentVariantPickerModalData, UmbDocumentVariantPickerModalValue > { - @state() - private _languages: Array = []; - - #collectionRepository = new UmbLanguageCollectionRepository(this); #selectionManager = new UmbSelectionManager(this); connectedCallback(): void { @@ -28,19 +22,6 @@ export class UmbDocumentVariantPickerModalElement extends UmbModalBaseElement< this.#selectionManager.setSelection(this.value?.selection ?? []); } - async firstUpdated() { - const { data } = await this.#collectionRepository.requestCollection({ skip: 0, take: 1000 }); - this._languages = data?.items ?? []; - } - - get #filteredLanguages() { - if (this.data?.filter) { - return this._languages.filter(this.data.filter); - } else { - return this._languages; - } - } - get #headline(): string { switch (this.data?.type) { case 'publish': diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.token.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.token.ts index ca51c9da11..58229254d9 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.token.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.token.ts @@ -1,10 +1,8 @@ import { UMB_DOCUMENT_VARIANT_PICKER_MODAL_ALIAS } from '../manifests.js'; import type { UmbDocumentVariantModel } from '../../types.js'; -import type { UmbLanguageItemModel } from '@umbraco-cms/backoffice/language'; import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; export interface UmbDocumentVariantPickerModalData { - filter?: (language: UmbLanguageItemModel) => boolean; type: 'save' | 'publish' | 'schedule' | 'unpublish'; variants: Array; } From 6b34e3e3fc046a9ef801bd21dc76a3f637bc9f70 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Tue, 20 Feb 2024 11:19:13 +0100 Subject: [PATCH 17/25] remove color --- .../variant-picker/document-variant-picker-modal.element.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.element.ts index 3c627d924e..7d7b5a79f3 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.element.ts @@ -126,7 +126,6 @@ export class UmbDocumentVariantPickerModalElement extends UmbModalBaseElement< } .label-status { font-size: 0.8rem; - color: rgba(var(--uui-color-text), 0.6); } `, ]; From 6a0d738926e03074d361e4ae63cbe5db65572020 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Tue, 20 Feb 2024 11:45:17 +0100 Subject: [PATCH 18/25] export correct name --- .../variant-picker/document-variant-picker-modal.element.ts | 4 ++-- .../documents/workspace/document-workspace.context.ts | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.element.ts index 7d7b5a79f3..5f669c2714 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.element.ts @@ -8,7 +8,7 @@ import { css, html, customElement, repeat } from '@umbraco-cms/backoffice/extern import { UmbSelectionManager } from '@umbraco-cms/backoffice/utils'; import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal'; -@customElement('umb-document-language-picker-modal') +@customElement('umb-document-variant-picker-modal') export class UmbDocumentVariantPickerModalElement extends UmbModalBaseElement< UmbDocumentVariantPickerModalData, UmbDocumentVariantPickerModalValue @@ -135,6 +135,6 @@ export default UmbDocumentVariantPickerModalElement; declare global { interface HTMLElementTagNameMap { - 'umb-document-language-picker-modal': UmbDocumentVariantPickerModalElement; + 'umb-document-variant-picker-modal': UmbDocumentVariantPickerModalElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts index 8f28d274f5..4eb95ca4e6 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts @@ -17,7 +17,6 @@ import { import { appendToFrozenArray, partialUpdateFrozenArray, UmbObjectState } from '@umbraco-cms/backoffice/observable-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal'; -import { DocumentVariantStateModel } from '@umbraco-cms/backoffice/external/backend-api'; type EntityType = UmbDocumentDetailModel; export class UmbDocumentWorkspaceContext From 6a4d23f3840d188c58652f42892cd1eef052e89d Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Tue, 20 Feb 2024 11:45:23 +0100 Subject: [PATCH 19/25] add story --- .../document-variant-picker-modal.stories.ts | 109 ++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.stories.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.stories.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.stories.ts new file mode 100644 index 0000000000..06071db1cc --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.stories.ts @@ -0,0 +1,109 @@ +import '../../../../core/components/body-layout/body-layout.element.js'; +import './document-variant-picker-modal.element.js'; + +import type { Meta, StoryObj } from '@storybook/web-components'; +import { UmbDocumentVariantState } from '../../types.js'; +import type { UmbDocumentVariantPickerModalElement } from './document-variant-picker-modal.element.js'; +import type { + UmbDocumentVariantPickerModalData, + UmbDocumentVariantPickerModalValue, +} from './document-variant-picker-modal.token.js'; +import { html } from '@umbraco-cms/backoffice/external/lit'; + +const modalData: UmbDocumentVariantPickerModalData = { + type: 'save', + variants: [ + { + name: 'English', + culture: 'en-us', + state: UmbDocumentVariantState.PUBLISHED, + createDate: '2021-08-25T14:00:00Z', + publishDate: '2021-08-25T14:00:00Z', + updateDate: null, + segment: null, + }, + { + name: 'Danish', + culture: 'da-dk', + state: UmbDocumentVariantState.NOT_CREATED, + createDate: null, + publishDate: null, + updateDate: null, + segment: null, + }, + ], +}; + +const modalValue: UmbDocumentVariantPickerModalValue = { + selection: ['en-us'], +}; + +const meta: Meta = { + title: 'Workspaces/Document/Modals/Variant Picker', + component: 'umb-document-variant-picker-modal', + id: 'umb-document-variant-picker-modal', + args: { + data: modalData, + value: modalValue, + }, + decorators: [(Story) => html`
${Story()}
`], + parameters: { + layout: 'centered', + docs: { + source: { + code: ` +import { UMB_DOCUMENT_LANGUAGE_PICKER_MODAL, UmbDocumentVariantState } from '@umbraco-cms/backoffice/document'; +import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal'; + +this.consumeContext(UMB_MODAL_MANAGER_CONTEXT, (modalManager) => { + modalManager.open(UMB_DOCUMENT_LANGUAGE_PICKER_MODAL, { + data: { + type: 'save', + variants: [ + { + name: 'English', + culture: 'en-us', + state: UmbDocumentVariantState.PUBLISHED, + createDate: '2021-08-25T14:00:00Z', + publishDate: '2021-08-25T14:00:00Z', + updateDate: null, + segment: null, + }, + { + name: 'Danish', + culture: 'da-dk', + state: UmbDocumentVariantState.NOT_CREATED, + createDate: null, + publishDate: null, + updateDate: null, + segment: null, + }, + ], + } + } +}); + `, + }, + }, + }, +}; + +export default meta; +type Story = StoryObj; + +export const Save: Story = {}; +export const Publish: Story = { + args: { + data: { ...modalData, type: 'publish' }, + }, +}; +export const Schedule: Story = { + args: { + data: { ...modalData, type: 'schedule' }, + }, +}; +export const Unpublish: Story = { + args: { + data: { ...modalData, type: 'unpublish' }, + }, +}; From d56837f45d4df5b098f99648c316a705f0da004e Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Tue, 20 Feb 2024 11:51:09 +0100 Subject: [PATCH 20/25] adjust story height --- .../variant-picker/document-variant-picker-modal.stories.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.stories.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.stories.ts index 06071db1cc..5c9ed23889 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.stories.ts @@ -46,7 +46,7 @@ const meta: Meta = { data: modalData, value: modalValue, }, - decorators: [(Story) => html`
${Story()}
`], + decorators: [(Story) => html`
${Story()}
`], parameters: { layout: 'centered', docs: { From 83287d7959a1da69b5564396144d79f39cc71aba Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Tue, 20 Feb 2024 11:51:16 +0100 Subject: [PATCH 21/25] add text for publishing --- .../variant-picker/document-variant-picker-modal.element.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.element.ts index 5f669c2714..04ee8f665d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.element.ts @@ -91,6 +91,8 @@ export class UmbDocumentVariantPickerModalElement extends UmbModalBaseElement< `, )} + ${this.data?.type === 'publish' ? html`

${this.localize.term('content_variantsWillBeSaved')}

` : ''} +
Date: Tue, 20 Feb 2024 12:11:23 +0100 Subject: [PATCH 22/25] add mandatory variant --- .../document-variant-picker-modal.element.ts | 28 +++++++++++++++---- .../document-variant-picker-modal.stories.ts | 26 ++++++++++++++++- .../document-detail.server.data-source.ts | 2 ++ .../src/packages/documents/documents/types.ts | 1 + 4 files changed, 50 insertions(+), 7 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.element.ts index 04ee8f665d..3c6a00bebb 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.element.ts @@ -19,7 +19,14 @@ export class UmbDocumentVariantPickerModalElement extends UmbModalBaseElement< super.connectedCallback(); this.#selectionManager.setSelectable(true); this.#selectionManager.setMultiple(true); + + // Make sure all mandatory variants are selected this.#selectionManager.setSelection(this.value?.selection ?? []); + this.data?.variants.forEach((variant) => { + if (variant.isMandatory) { + this.#selectionManager.select(variant.culture); + } + }); } get #headline(): string { @@ -79,15 +86,12 @@ export class UmbDocumentVariantPickerModalElement extends UmbModalBaseElement< (item) => html` this.#selectionManager.select(item.culture)} @deselected=${() => this.#selectionManager.deselect(item.culture)} - ?selected=${this.#selectionManager.isSelected(item.culture)}> + ?selected=${this.#selectionManager.isSelected(item.culture)} + ?selectable=${!item.isMandatory}> -
- ${item.name} -
${this.#renderVariantStatus(item)}
-
+ ${this.#renderLabel(item)}
`, )} @@ -104,6 +108,18 @@ export class UmbDocumentVariantPickerModalElement extends UmbModalBaseElement< `; } + #renderLabel(variant: UmbDocumentVariantModel) { + return html`
+ ${variant.segment ? variant.segment + ' - ' : ''}${variant.name} +
${this.#renderVariantStatus(variant)}
+ ${variant.isMandatory && variant.state !== UmbDocumentVariantState.PUBLISHED + ? html`
+ Mandatory language +
` + : ''} +
`; + } + #renderVariantStatus(variant: UmbDocumentVariantModel) { switch (variant.state) { case UmbDocumentVariantState.PUBLISHED: diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.stories.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.stories.ts index 5c9ed23889..19d38ffac6 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.stories.ts @@ -18,9 +18,20 @@ const modalData: UmbDocumentVariantPickerModalData = { culture: 'en-us', state: UmbDocumentVariantState.PUBLISHED, createDate: '2021-08-25T14:00:00Z', - publishDate: '2021-08-25T14:00:00Z', + publishDate: null, updateDate: null, segment: null, + isMandatory: true, + }, + { + name: 'English', + culture: 'en-us', + state: UmbDocumentVariantState.DRAFT, + createDate: '2021-08-25T14:00:00Z', + publishDate: null, + updateDate: null, + segment: 'GTM', + isMandatory: true, }, { name: 'Danish', @@ -30,6 +41,7 @@ const modalData: UmbDocumentVariantPickerModalData = { publishDate: null, updateDate: null, segment: null, + isMandatory: false, }, ], }; @@ -68,6 +80,17 @@ this.consumeContext(UMB_MODAL_MANAGER_CONTEXT, (modalManager) => { publishDate: '2021-08-25T14:00:00Z', updateDate: null, segment: null, + isMandatory: true, + }, + { + name: 'English', + culture: 'en-us', + state: UmbDocumentVariantState.PUBLISHED, + createDate: '2021-08-25T14:00:00Z', + publishDate: '2021-08-25T14:00:00Z', + updateDate: null, + segment: 'GTM', + isMandatory: false, }, { name: 'Danish', @@ -77,6 +100,7 @@ this.consumeContext(UMB_MODAL_MANAGER_CONTEXT, (modalManager) => { publishDate: null, updateDate: null, segment: null, + isMandatory: false, }, ], } diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/detail/document-detail.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/detail/document-detail.server.data-source.ts index 78014bf306..041ba660a5 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/detail/document-detail.server.data-source.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/detail/document-detail.server.data-source.ts @@ -56,6 +56,7 @@ export class UmbDocumentServerDataSource implements UmbDetailDataSource { diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/types.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/types.ts index b9a34927e6..41a3c03d44 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/types.ts @@ -21,6 +21,7 @@ export interface UmbDocumentDetailModel { export interface UmbDocumentVariantModel extends UmbVariantModel { state: UmbDocumentVariantState | null; publishDate: string | null; + isMandatory: boolean; } export interface UmbDocumentUrlInfoModel { From 8cfa33999cba65bb33492ca7c40b230f57024543 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Tue, 20 Feb 2024 12:15:47 +0100 Subject: [PATCH 23/25] select mandatory variants --- .../document-variant-picker-modal.element.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.element.ts index 3c6a00bebb..c0c633ed86 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/variant-picker/document-variant-picker-modal.element.ts @@ -20,8 +20,14 @@ export class UmbDocumentVariantPickerModalElement extends UmbModalBaseElement< this.#selectionManager.setSelectable(true); this.#selectionManager.setMultiple(true); - // Make sure all mandatory variants are selected + // Make sure all mandatory variants are selected when not in unpublish mode this.#selectionManager.setSelection(this.value?.selection ?? []); + if (this.data?.type !== 'unpublish') { + this.#selectMandatoryVariants(); + } + } + + #selectMandatoryVariants() { this.data?.variants.forEach((variant) => { if (variant.isMandatory) { this.#selectionManager.select(variant.culture); @@ -85,11 +91,11 @@ export class UmbDocumentVariantPickerModalElement extends UmbModalBaseElement< (item) => item.culture, (item) => html` this.#selectionManager.select(item.culture)} @deselected=${() => this.#selectionManager.deselect(item.culture)} - ?selected=${this.#selectionManager.isSelected(item.culture)} - ?selectable=${!item.isMandatory}> + ?selected=${this.#selectionManager.isSelected(item.culture)}> ${this.#renderLabel(item)} From 80613225a423ded272549c785398997531c1e639 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Tue, 20 Feb 2024 14:11:48 +0100 Subject: [PATCH 24/25] update server models --- .../src/external/backend-api/src/index.ts | 2 ++ .../src/models/CultureAndScheduleRequestModel.ts | 12 ++++++++++++ .../src/models/MemberItemResponseModel.ts | 4 ++-- .../src/models/PublishDocumentRequestModel.ts | 4 +++- ...PublishDocumentWithDescendantsRequestModel.ts | 7 +++---- .../src/models/ScheduleRequestModel.ts | 10 ++++++++++ .../backend-api/src/services/DocumentResource.ts | 2 +- .../data/document/document-publishing.manager.ts | 2 +- .../src/mocks/data/member/member.data.ts | 3 +++ .../src/mocks/data/member/member.db.ts | 3 +++ .../packages/core/variant/variant-id.class.ts | 8 +++++++- .../document-publishing.server.data-source.ts | 16 ++++++++++++---- 12 files changed, 59 insertions(+), 14 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/CultureAndScheduleRequestModel.ts create mode 100644 src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/ScheduleRequestModel.ts diff --git a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/index.ts b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/index.ts index 17285517c5..f4c30d1496 100644 --- a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/index.ts +++ b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/index.ts @@ -76,6 +76,7 @@ export type { CreateTemplateRequestModel } from './models/CreateTemplateRequestM export type { CreateUserGroupRequestModel } from './models/CreateUserGroupRequestModel'; export type { CreateUserRequestModel } from './models/CreateUserRequestModel'; export type { CreateUserResponseModel } from './models/CreateUserResponseModel'; +export type { CultureAndScheduleRequestModel } from './models/CultureAndScheduleRequestModel'; export type { CultureReponseModel } from './models/CultureReponseModel'; export type { CurrentUserResponseModel } from './models/CurrentUserResponseModel'; export type { CurrenUserConfigurationResponseModel } from './models/CurrenUserConfigurationResponseModel'; @@ -320,6 +321,7 @@ export { RuntimeModeModel } from './models/RuntimeModeModel'; export type { SavedLogSearchPresenationBaseModel } from './models/SavedLogSearchPresenationBaseModel'; export type { SavedLogSearchRequestModel } from './models/SavedLogSearchRequestModel'; export type { SavedLogSearchResponseModel } from './models/SavedLogSearchResponseModel'; +export type { ScheduleRequestModel } from './models/ScheduleRequestModel'; export type { ScriptFolderResponseModel } from './models/ScriptFolderResponseModel'; export type { ScriptItemResponseModel } from './models/ScriptItemResponseModel'; export type { ScriptResponseModel } from './models/ScriptResponseModel'; diff --git a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/CultureAndScheduleRequestModel.ts b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/CultureAndScheduleRequestModel.ts new file mode 100644 index 0000000000..8ebf39abe3 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/CultureAndScheduleRequestModel.ts @@ -0,0 +1,12 @@ +/* generated using openapi-typescript-codegen -- do no edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { ScheduleRequestModel } from './ScheduleRequestModel'; + +export type CultureAndScheduleRequestModel = { + culture?: string | null; + schedule?: ScheduleRequestModel | null; +}; + diff --git a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/MemberItemResponseModel.ts b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/MemberItemResponseModel.ts index 4fec6f420a..09fd635f8a 100644 --- a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/MemberItemResponseModel.ts +++ b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/MemberItemResponseModel.ts @@ -3,11 +3,11 @@ /* tslint:disable */ /* eslint-disable */ -import type { ItemResponseModelBaseModel } from './ItemResponseModelBaseModel'; import type { MemberTypeReferenceResponseModel } from './MemberTypeReferenceResponseModel'; +import type { NamedItemResponseModelBaseModel } from './NamedItemResponseModelBaseModel'; import type { VariantItemResponseModel } from './VariantItemResponseModel'; -export type MemberItemResponseModel = (ItemResponseModelBaseModel & { +export type MemberItemResponseModel = (NamedItemResponseModelBaseModel & { memberType: MemberTypeReferenceResponseModel; variants: Array; }); diff --git a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/PublishDocumentRequestModel.ts b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/PublishDocumentRequestModel.ts index 18355d089b..4c08971560 100644 --- a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/PublishDocumentRequestModel.ts +++ b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/PublishDocumentRequestModel.ts @@ -3,7 +3,9 @@ /* tslint:disable */ /* eslint-disable */ +import type { CultureAndScheduleRequestModel } from './CultureAndScheduleRequestModel'; + export type PublishDocumentRequestModel = { - cultures: Array; + publishSchedules: Array; }; diff --git a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/PublishDocumentWithDescendantsRequestModel.ts b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/PublishDocumentWithDescendantsRequestModel.ts index 270f4d9c43..9796f30e5a 100644 --- a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/PublishDocumentWithDescendantsRequestModel.ts +++ b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/PublishDocumentWithDescendantsRequestModel.ts @@ -3,9 +3,8 @@ /* tslint:disable */ /* eslint-disable */ -import type { PublishDocumentRequestModel } from './PublishDocumentRequestModel'; - -export type PublishDocumentWithDescendantsRequestModel = (PublishDocumentRequestModel & { +export type PublishDocumentWithDescendantsRequestModel = { includeUnpublishedDescendants: boolean; -}); + cultures: Array; +}; diff --git a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/ScheduleRequestModel.ts b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/ScheduleRequestModel.ts new file mode 100644 index 0000000000..59b83b94a6 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/ScheduleRequestModel.ts @@ -0,0 +1,10 @@ +/* generated using openapi-typescript-codegen -- do no edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export type ScheduleRequestModel = { + publishTime?: string | null; + unpublishTime?: string | null; +}; + diff --git a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/services/DocumentResource.ts b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/services/DocumentResource.ts index dab44ef423..1453062de2 100644 --- a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/services/DocumentResource.ts +++ b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/services/DocumentResource.ts @@ -459,7 +459,7 @@ export class DocumentResource { requestBody, }: { id: string, - requestBody?: (PublishDocumentRequestModel | PublishDocumentWithDescendantsRequestModel), + requestBody?: PublishDocumentRequestModel, }): CancelablePromise { return __request(OpenAPI, { method: 'PUT', diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/document/document-publishing.manager.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/document/document-publishing.manager.ts index 15b7d9c6fe..2cdc4b7e86 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/document/document-publishing.manager.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/document/document-publishing.manager.ts @@ -17,7 +17,7 @@ export class UmbMockDocumentPublishingManager { const document: UmbMockDocumentModel = this.#documentDb.detail.read(id); document?.variants?.forEach((variant) => { - const hasCulture = variant.culture && data.cultures?.includes(variant.culture); + const hasCulture = variant.culture && data.publishSchedules.find((x) => x.culture === variant.culture); if (hasCulture) { variant.state = DocumentVariantStateModel.PUBLISHED; diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/member/member.data.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/member/member.data.ts index 36f8dd3244..5e4806b90a 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/member/member.data.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/member/member.data.ts @@ -5,6 +5,7 @@ export type UmbMockMemberModel = MemberResponseModel & MemberItemResponseModel; export const data: Array = [ { email: 'member1@member.com', + name: 'Member 1', failedPasswordAttempts: 0, groups: [], id: '6ff6f75a-c14e-4172-a80b-d3ffcbc37979', @@ -29,6 +30,7 @@ export const data: Array = [ }, { email: 'member2@member.com', + name: 'Member 2', failedPasswordAttempts: 0, groups: [], id: '6ff6f75a-c14e-4172-a80b-d3ffcbc37979', @@ -53,6 +55,7 @@ export const data: Array = [ }, { email: 'member3@member.com', + name: 'Member 3', failedPasswordAttempts: 0, groups: [], id: '6ff6f75a-c14e-4172-a80b-d3ffcbc37979', diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/member/member.db.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/member/member.db.ts index e03bc668f1..db0be6a571 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/member/member.db.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/member/member.db.ts @@ -30,6 +30,7 @@ const createDetailMockMapper = (request: CreateMemberRequestModel): UmbMockMembe return { email: request.email, + name: '', failedPasswordAttempts: 0, groups: request.groups ? request.groups : [], id: request.id ? request.id : UmbId.new(), @@ -80,6 +81,7 @@ const detailResponseMapper = (item: UmbMockMemberModel): MemberResponseModel => const itemResponseMapper = (item: UmbMockMemberModel): MemberItemResponseModel => { return { id: item.id, + name: item.username, memberType: item.memberType, variants: item.variants, }; @@ -88,6 +90,7 @@ const itemResponseMapper = (item: UmbMockMemberModel): MemberItemResponseModel = const collectionItemResponseMapper = (item: UmbMockMemberModel): any => { return { id: item.id, + name: item.name, email: item.email, variants: item.variants, }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/variant/variant-id.class.ts b/src/Umbraco.Web.UI.Client/src/packages/core/variant/variant-id.class.ts index 01a495ea97..39a8b85b12 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/variant/variant-id.class.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/variant/variant-id.class.ts @@ -1,4 +1,8 @@ -export type variantObject = { culture: string | null; segment: string | null }; +export type variantObject = { + culture: string | null; + segment: string | null; + schedule?: { publishTime?: string | null; unpublishTime?: string | null }; +}; export const UMB_INVARIANT_CULTURE = 'invariant'; @@ -13,10 +17,12 @@ export class UmbVariantId { public readonly culture: string | null = null; public readonly segment: string | null = null; + public readonly schedule: { publishTime?: string | null; unpublishTime?: string | null } | null = null; constructor(variantData: variantObject) { this.culture = (variantData.culture === UMB_INVARIANT_CULTURE ? null : variantData.culture) ?? null; this.segment = variantData.segment ?? null; + this.schedule = variantData.schedule ?? null; } public compare(obj: variantObject): boolean { diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/publishing/document-publishing.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/publishing/document-publishing.server.data-source.ts index d04414c784..9abc1b8274 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/publishing/document-publishing.server.data-source.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/publishing/document-publishing.server.data-source.ts @@ -1,4 +1,5 @@ import type { + CultureAndScheduleRequestModel, PublishDocumentRequestModel, UnpublishDocumentRequestModel, } from '@umbraco-cms/backoffice/external/backend-api'; @@ -35,11 +36,18 @@ export class UmbDocumentPublishingServerDataSource { async publish(unique: string, variantIds: Array) { if (!unique) throw new Error('Id is missing'); + const publishSchedules: CultureAndScheduleRequestModel[] = variantIds.map( + (variant) => { + return { + culture: variant.isCultureInvariant() ? null : variant.toCultureString(), + schedule: variant.schedule, + }; + }, + ); + // TODO: THIS DOES NOT TAKE SEGMENTS INTO ACCOUNT!!!!!! const requestBody: PublishDocumentRequestModel = { - cultures: variantIds - .map((variant) => (variant.isCultureInvariant() ? null : variant.toCultureString())) - .filter((x) => x !== null) as Array, + publishSchedules, }; return tryExecuteAndNotify(this.#host, DocumentResource.putDocumentByIdPublish({ id: unique, requestBody })); @@ -57,7 +65,7 @@ export class UmbDocumentPublishingServerDataSource { // TODO: THIS DOES NOT TAKE SEGMENTS INTO ACCOUNT!!!!!! const requestBody: UnpublishDocumentRequestModel = { - culture: variantIds.map((variant) => variant.toCultureString())[0], + culture: variantIds.map((variant) => (variant.isCultureInvariant() ? null : variant.toCultureString()))[0], }; return tryExecuteAndNotify(this.#host, DocumentResource.putDocumentByIdUnpublish({ id: unique, requestBody })); From c6b17c25ba594ea7b9d1dff20027055fda77a38b Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Tue, 20 Feb 2024 15:07:43 +0100 Subject: [PATCH 25/25] update models --- .../src/external/backend-api/src/index.ts | 1 + .../src/models/MemberItemResponseModel.ts | 4 +- .../src/models/PagedMemberResponseModel.ts | 12 ++++++ .../src/services/MemberResource.ts | 40 +++++++++++++++++++ .../backend-api/src/services/UserResource.ts | 6 ++- .../src/mocks/data/member/member.data.ts | 3 -- .../src/mocks/data/member/member.db.ts | 3 -- .../user-collection.server.data-source.ts | 4 ++ 8 files changed, 63 insertions(+), 10 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/PagedMemberResponseModel.ts diff --git a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/index.ts b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/index.ts index f4c30d1496..16a1bd5bf9 100644 --- a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/index.ts +++ b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/index.ts @@ -265,6 +265,7 @@ export type { PagedMediaCollectionResponseModel } from './models/PagedMediaColle export type { PagedMediaRecycleBinItemResponseModel } from './models/PagedMediaRecycleBinItemResponseModel'; export type { PagedMediaTreeItemResponseModel } from './models/PagedMediaTreeItemResponseModel'; export type { PagedMediaTypeTreeItemResponseModel } from './models/PagedMediaTypeTreeItemResponseModel'; +export type { PagedMemberResponseModel } from './models/PagedMemberResponseModel'; export type { PagedNamedEntityTreeItemResponseModel } from './models/PagedNamedEntityTreeItemResponseModel'; export type { PagedObjectTypeResponseModel } from './models/PagedObjectTypeResponseModel'; export type { PagedPackageDefinitionResponseModel } from './models/PagedPackageDefinitionResponseModel'; diff --git a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/MemberItemResponseModel.ts b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/MemberItemResponseModel.ts index 09fd635f8a..4fec6f420a 100644 --- a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/MemberItemResponseModel.ts +++ b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/MemberItemResponseModel.ts @@ -3,11 +3,11 @@ /* tslint:disable */ /* eslint-disable */ +import type { ItemResponseModelBaseModel } from './ItemResponseModelBaseModel'; import type { MemberTypeReferenceResponseModel } from './MemberTypeReferenceResponseModel'; -import type { NamedItemResponseModelBaseModel } from './NamedItemResponseModelBaseModel'; import type { VariantItemResponseModel } from './VariantItemResponseModel'; -export type MemberItemResponseModel = (NamedItemResponseModelBaseModel & { +export type MemberItemResponseModel = (ItemResponseModelBaseModel & { memberType: MemberTypeReferenceResponseModel; variants: Array; }); diff --git a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/PagedMemberResponseModel.ts b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/PagedMemberResponseModel.ts new file mode 100644 index 0000000000..06cea577ab --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/PagedMemberResponseModel.ts @@ -0,0 +1,12 @@ +/* generated using openapi-typescript-codegen -- do no edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { MemberResponseModel } from './MemberResponseModel'; + +export type PagedMemberResponseModel = { + total: number; + items: Array; +}; + diff --git a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/services/MemberResource.ts b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/services/MemberResource.ts index d432800b20..b739bae4c0 100644 --- a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/services/MemberResource.ts +++ b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/services/MemberResource.ts @@ -3,8 +3,10 @@ /* tslint:disable */ /* eslint-disable */ import type { CreateMemberRequestModel } from '../models/CreateMemberRequestModel'; +import type { DirectionModel } from '../models/DirectionModel'; import type { MemberItemResponseModel } from '../models/MemberItemResponseModel'; import type { MemberResponseModel } from '../models/MemberResponseModel'; +import type { PagedMemberResponseModel } from '../models/PagedMemberResponseModel'; import type { UpdateMemberRequestModel } from '../models/UpdateMemberRequestModel'; import type { CancelablePromise } from '../core/CancelablePromise'; @@ -156,6 +158,44 @@ export class MemberResource { }); } + /** + * @returns PagedMemberResponseModel Success + * @throws ApiError + */ + public static getMemberFilter({ + memberTypeId, + orderBy = 'username', + orderDirection, + filter, + skip, + take = 100, + }: { + memberTypeId?: string, + orderBy?: string, + orderDirection?: DirectionModel, + filter?: string, + skip?: number, + take?: number, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/umbraco/management/api/v1/member/filter', + query: { + 'memberTypeId': memberTypeId, + 'orderBy': orderBy, + 'orderDirection': orderDirection, + 'filter': filter, + 'skip': skip, + 'take': take, + }, + errors: { + 400: `Bad Request`, + 401: `The resource is protected and requires an authentication token`, + 404: `Not Found`, + }, + }); + } + /** * @returns any Success * @throws ApiError diff --git a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/services/UserResource.ts b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/services/UserResource.ts index d8dd9e1ebe..9a714f6675 100644 --- a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/services/UserResource.ts +++ b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/services/UserResource.ts @@ -617,7 +617,7 @@ export class UserResource { } /** - * @returns any Success + * @returns PagedUserResponseModel Success * @throws ApiError */ public static getUserFilter({ @@ -636,7 +636,7 @@ export class UserResource { userGroupIds?: Array, userStates?: Array, filter?: string, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/user/filter', @@ -650,7 +650,9 @@ export class UserResource { 'filter': filter, }, errors: { + 400: `Bad Request`, 401: `The resource is protected and requires an authentication token`, + 404: `Not Found`, }, }); } diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/member/member.data.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/member/member.data.ts index 5e4806b90a..36f8dd3244 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/member/member.data.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/member/member.data.ts @@ -5,7 +5,6 @@ export type UmbMockMemberModel = MemberResponseModel & MemberItemResponseModel; export const data: Array = [ { email: 'member1@member.com', - name: 'Member 1', failedPasswordAttempts: 0, groups: [], id: '6ff6f75a-c14e-4172-a80b-d3ffcbc37979', @@ -30,7 +29,6 @@ export const data: Array = [ }, { email: 'member2@member.com', - name: 'Member 2', failedPasswordAttempts: 0, groups: [], id: '6ff6f75a-c14e-4172-a80b-d3ffcbc37979', @@ -55,7 +53,6 @@ export const data: Array = [ }, { email: 'member3@member.com', - name: 'Member 3', failedPasswordAttempts: 0, groups: [], id: '6ff6f75a-c14e-4172-a80b-d3ffcbc37979', diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/member/member.db.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/member/member.db.ts index db0be6a571..e03bc668f1 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/member/member.db.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/member/member.db.ts @@ -30,7 +30,6 @@ const createDetailMockMapper = (request: CreateMemberRequestModel): UmbMockMembe return { email: request.email, - name: '', failedPasswordAttempts: 0, groups: request.groups ? request.groups : [], id: request.id ? request.id : UmbId.new(), @@ -81,7 +80,6 @@ const detailResponseMapper = (item: UmbMockMemberModel): MemberResponseModel => const itemResponseMapper = (item: UmbMockMemberModel): MemberItemResponseModel => { return { id: item.id, - name: item.username, memberType: item.memberType, variants: item.variants, }; @@ -90,7 +88,6 @@ const itemResponseMapper = (item: UmbMockMemberModel): MemberItemResponseModel = const collectionItemResponseMapper = (item: UmbMockMemberModel): any => { return { id: item.id, - name: item.name, email: item.email, variants: item.variants, }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user/collection/repository/user-collection.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user/collection/repository/user-collection.server.data-source.ts index cd1a111ca7..c4c7b9f421 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/user/collection/repository/user-collection.server.data-source.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user/collection/repository/user-collection.server.data-source.ts @@ -38,6 +38,10 @@ export class UmbUserCollectionServerDataSource implements UmbCollectionDataSourc return { error }; } + if (!data) { + return { data: { items: [], total: 0 } }; + } + const { items, total } = data; const mappedItems: Array = items.map((item: UserResponseModel) => {