diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/publish-with-descendants-modal/document-publish-with-descendants-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/publish-with-descendants-modal/document-publish-with-descendants-modal.element.ts index dec8e73b80..23a38bf906 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/publish-with-descendants-modal/document-publish-with-descendants-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/publish-with-descendants-modal/document-publish-with-descendants-modal.element.ts @@ -16,6 +16,7 @@ export class UmbDocumentPublishWithDescendantsModalElement extends UmbModalBaseE UmbDocumentPublishWithDescendantsModalValue > { #selectionManager = new UmbSelectionManager(this); + #includeUnpublishedDescendants = false; @state() _options: Array = []; @@ -50,7 +51,10 @@ export class UmbDocumentPublishWithDescendantsModalElement extends UmbModalBaseE } #submit() { - this.value = { ...this.value, selection: this.#selectionManager.getSelection() }; + this.value = { + selection: this.#selectionManager.getSelection(), + includeUnpublishedDescendants: this.#includeUnpublishedDescendants, + }; this.modalContext?.submit(); } @@ -85,8 +89,7 @@ export class UmbDocumentPublishWithDescendantsModalElement extends UmbModalBaseE id="includeUnpublishedDescendants" label=${this.localize.term('content_includeUnpublished')} ?checked=${this.value?.includeUnpublishedDescendants} - @change=${() => - (this.value.includeUnpublishedDescendants = !this.value.includeUnpublishedDescendants)}> + @change=${() => (this.#includeUnpublishedDescendants = !this.#includeUnpublishedDescendants)}>
diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/publishing/document-publishing.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/publishing/document-publishing.repository.ts index d72e0d1ead..2c62c85dac 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/publishing/document-publishing.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/publishing/document-publishing.repository.ts @@ -65,4 +65,27 @@ export class UmbDocumentPublishingRepository extends UmbRepositoryBase { return { error }; } + + /** + * Publish variants of a document including its descendants + * @memberof UmbDocumentPublishingRepository + */ + async publishWithDescendants(id: string, variantIds: Array, includeUnpublishedDescendants: boolean) { + if (!id) throw new Error('id is missing'); + if (!variantIds) throw new Error('variant IDs are missing'); + await this.#init; + + const { error } = await this.#publishingDataSource.publishWithDescendants( + id, + variantIds, + includeUnpublishedDescendants, + ); + + if (!error) { + const notification = { data: { message: `Document published with descendants` } }; + this.#notificationContext?.peek('positive', notification); + } + + return { error }; + } } 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 eb3efdf3f2..20cc82657a 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 @@ -2,6 +2,7 @@ import type { UmbDocumentVariantPublishModel } from '../../types.js'; import type { CultureAndScheduleRequestModel, PublishDocumentRequestModel, + PublishDocumentWithDescendantsRequestModel, UnpublishDocumentRequestModel, } from '@umbraco-cms/backoffice/external/backend-api'; import { DocumentResource } from '@umbraco-cms/backoffice/external/backend-api'; @@ -32,7 +33,7 @@ export class UmbDocumentPublishingServerDataSource { * @param {string} unique * @param {Array} variantIds * @return {*} - * @memberof UmbDocumentServerDataSource + * @memberof UmbDocumentPublishingServerDataSource */ async publish(unique: string, variants: Array) { if (!unique) throw new Error('Id is missing'); @@ -59,7 +60,7 @@ export class UmbDocumentPublishingServerDataSource { * @param {string} unique * @param {Array} variantIds * @return {*} - * @memberof UmbDocumentServerDataSource + * @memberof UmbDocumentPublishingServerDataSource */ async unpublish(unique: string, variantIds: Array) { if (!unique) throw new Error('Id is missing'); @@ -83,4 +84,26 @@ export class UmbDocumentPublishingServerDataSource { return tryExecuteAndNotify(this.#host, DocumentResource.putDocumentByIdUnpublish({ id: unique, requestBody })); } + + /** + * Publish variants of a document and all its descendants + * @memberof UmbDocumentPublishingServerDataSource + */ + async publishWithDescendants( + unique: string, + variantIds: Array, + includeUnpublishedDescendants: boolean, + ) { + if (!unique) throw new Error('Id is missing'); + + const requestBody: PublishDocumentWithDescendantsRequestModel = { + cultures: variantIds.map((variant) => variant.toCultureString()), + includeUnpublishedDescendants, + }; + + return tryExecuteAndNotify( + this.#host, + DocumentResource.putDocumentByIdPublishWithDescendants({ id: unique, requestBody }), + ); + } } 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 8ca1755dc5..134348bcf6 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 @@ -9,7 +9,12 @@ import type { UmbDocumentVariantModel, UmbDocumentVariantOptionModel, } from '../types.js'; -import { UMB_DOCUMENT_PUBLISH_MODAL, UMB_DOCUMENT_SCHEDULE_MODAL } from '../modals/index.js'; +import { + UMB_DOCUMENT_PUBLISH_MODAL, + UMB_DOCUMENT_PUBLISH_WITH_DESCENDANTS_MODAL, + UMB_DOCUMENT_SCHEDULE_MODAL, + UMB_DOCUMENT_SAVE_MODAL, +} from '../modals/index.js'; import { UmbDocumentPublishingRepository } from '../repository/publishing/index.js'; import { UmbUnpublishDocumentEntityAction } from '../entity-actions/unpublish.action.js'; import { UMB_DOCUMENT_WORKSPACE_ALIAS } from './manifests.js'; @@ -36,7 +41,6 @@ import { UmbReloadTreeItemChildrenRequestEntityActionEvent } from '@umbraco-cms/ import { UmbRequestReloadStructureForEntityEvent } from '@umbraco-cms/backoffice/event'; import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal'; import type { UmbDocumentTypeDetailModel } from '@umbraco-cms/backoffice/document-type'; -import { UMB_DOCUMENT_SAVE_MODAL } from '../modals/save-modal/document-save-modal.token.js'; type EntityType = UmbDocumentDetailModel; export class UmbDocumentWorkspaceContext @@ -626,7 +630,41 @@ export class UmbDocumentWorkspaceContext } public async publishWithDescendants() { - throw new Error('Method not implemented.'); + const { options, selected } = await this.#determineVariantOptions(); + + const modalManagerContext = await this.getContext(UMB_MODAL_MANAGER_CONTEXT); + const result = await modalManagerContext + .open(this, UMB_DOCUMENT_PUBLISH_WITH_DESCENDANTS_MODAL, { + data: { + options, + }, + value: { selection: selected }, + }) + .onSubmit() + .catch(() => undefined); + + if (!result?.selection.length) return; + + // Map to variantIds + const variantIds = result?.selection.map((x) => UmbVariantId.FromString(x)) ?? []; + + if (!variantIds.length) return; + + const unique = this.getUnique(); + if (!unique) throw new Error('Unique is missing'); + await this.publishingRepository.publishWithDescendants( + unique, + variantIds, + result.includeUnpublishedDescendants ?? false, + ); + + const data = this.getData(); + if (!data) throw new Error('Data is missing'); + + this.#persistedData.setValue(data); + this.#currentData.setValue(data); + + this.workspaceComplete(data); } async delete() {