V15: Save the variant before scheduling (#18344)
* feat: adds validation checks and saves a version when scheduling content * chore: adds mock handler for validate * docs: adds documentation for umbracoPath * chore: adds deprecation and todos * feat: adds a method to output a list format * test: adds test for list format * feat: rename to list * feat: adds localization for scheduling * feat: adds notifications for publishing by action * test: fixes naming * feat: adds notification for publishing in bulk * feat: fixes todo by adding localization * feat: adds notification when publishing from workspace --------- Co-authored-by: leekelleher <leekelleher@gmail.com>
This commit is contained in:
@@ -1412,14 +1412,14 @@ export default {
|
||||
cssSavedText: 'Stylesheet saved without any errors',
|
||||
dataTypeSaved: 'Datatype saved',
|
||||
dictionaryItemSaved: 'Dictionary item saved',
|
||||
editContentPublishedHeader: 'Content published',
|
||||
editContentPublishedHeader: 'Document published',
|
||||
editContentPublishedText: 'and is visible on the website',
|
||||
editMultiContentPublishedText: '%0% documents published and visible on the website',
|
||||
editVariantPublishedText: '%0% published and visible on the website',
|
||||
editMultiVariantPublishedText: '%0% documents published for languages %1% and visible on the website',
|
||||
editMultiContentPublishedText: '%0% documents published and are visible on the website',
|
||||
editVariantPublishedText: '%0% published and is visible on the website',
|
||||
editMultiVariantPublishedText: '%0% documents published for languages %1% and are visible on the website',
|
||||
editBlueprintSavedHeader: 'Document Blueprint saved',
|
||||
editBlueprintSavedText: 'Changes have been successfully saved',
|
||||
editContentSavedHeader: 'Content saved',
|
||||
editContentSavedHeader: 'Document saved',
|
||||
editContentSavedText: 'Remember to publish to make changes visible',
|
||||
editContentScheduledSavedText: 'A schedule for publishing has been updated',
|
||||
editVariantSavedText: '%0% saved',
|
||||
|
||||
@@ -1412,7 +1412,7 @@ export default {
|
||||
folderUploadNotAllowed:
|
||||
'This file is being uploaded as part of a folder, but creating a new folder is not allowed here',
|
||||
folderCreationNotAllowed: 'Creating a new folder is not allowed here',
|
||||
contentPublishedFailedByEvent: 'Content could not be published, a 3rd party add-in cancelled the action',
|
||||
contentPublishedFailedByEvent: 'Document could not be published, a 3rd party add-in cancelled the action',
|
||||
contentTypeDublicatePropertyType: 'Property type already exists',
|
||||
contentTypePropertyTypeCreated: 'Property type created',
|
||||
contentTypePropertyTypeCreatedText: 'Name: %0% <br /> DataType: %1%',
|
||||
@@ -1426,12 +1426,13 @@ export default {
|
||||
cssSavedText: 'Stylesheet saved without any errors',
|
||||
dataTypeSaved: 'Datatype saved',
|
||||
dictionaryItemSaved: 'Dictionary item saved',
|
||||
editContentPublishedFailedByParent: 'Content could not be published, because a parent page is not published',
|
||||
editContentPublishedHeader: 'Content published',
|
||||
editContentPublishedText: 'and visible on the website',
|
||||
editContentPublishedFailedByValidation: 'Document could not be published, but we saved it for you',
|
||||
editContentPublishedFailedByParent: 'Document could not be published, because a parent page is not published',
|
||||
editContentPublishedHeader: 'Document published',
|
||||
editContentPublishedText: 'and is visible on the website',
|
||||
editBlueprintSavedHeader: 'Document Blueprint saved',
|
||||
editBlueprintSavedText: 'Changes have been successfully saved',
|
||||
editContentSavedHeader: 'Content saved',
|
||||
editContentSavedHeader: 'Document saved',
|
||||
editContentSavedText: 'Remember to publish to make changes visible',
|
||||
editContentSendToPublish: 'Sent For Approval',
|
||||
editContentSendToPublishText: 'Changes have been sent for approval',
|
||||
@@ -1493,10 +1494,11 @@ export default {
|
||||
cannotCopyInformation: 'Could not copy your system information to the clipboard',
|
||||
webhookSaved: 'Webhook saved',
|
||||
operationSavedHeaderReloadUser: 'Saved. To view the changes please reload your browser',
|
||||
editMultiContentPublishedText: '%0% documents published and visible on the website',
|
||||
editVariantPublishedText: '%0% published and visible on the website',
|
||||
editMultiVariantPublishedText: '%0% documents published for languages %1% and visible on the website',
|
||||
editMultiContentPublishedText: '%0% documents published and are visible on the website',
|
||||
editVariantPublishedText: '%0% published and is visible on the website',
|
||||
editMultiVariantPublishedText: '%0% documents published for languages %1% and are visible on the website',
|
||||
editContentScheduledSavedText: 'A schedule for publishing has been updated',
|
||||
editContentScheduledNotSavedText: 'The schedule for publishing could not be updated',
|
||||
editVariantSavedText: '%0% saved',
|
||||
editVariantSendToPublishText: '%0% changes have been sent for approval',
|
||||
contentCultureUnpublished: 'Content variation %0% unpublished',
|
||||
|
||||
@@ -282,6 +282,16 @@ describe('UmbLocalizeController', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('list format', () => {
|
||||
it('should return a list with conjunction', () => {
|
||||
expect(controller.list(['one', 'two', 'three'], { type: 'conjunction' })).to.equal('one, two, and three');
|
||||
});
|
||||
|
||||
it('should return a list with disjunction', () => {
|
||||
expect(controller.list(['one', 'two', 'three'], { type: 'disjunction' })).to.equal('one, two, or three');
|
||||
});
|
||||
});
|
||||
|
||||
describe('duration', () => {
|
||||
it('should return a duration', () => {
|
||||
const now = new Date('2020-01-01T00:00:00');
|
||||
|
||||
@@ -941,8 +941,16 @@ export const data: Array<UmbMockDataTypeModel> = [
|
||||
{
|
||||
alias: 'layouts',
|
||||
value: [
|
||||
{ icon: 'icon-grid', isSystem: true, name: 'Grid', path: '', selected: true },
|
||||
{ icon: 'icon-list', isSystem: true, name: 'Table', path: '', selected: true },
|
||||
{
|
||||
icon: 'icon-grid',
|
||||
name: 'Document Grid Collection View',
|
||||
collectionView: 'Umb.CollectionView.Document.Grid',
|
||||
},
|
||||
{
|
||||
icon: 'icon-list',
|
||||
name: 'Document Table Collection View',
|
||||
collectionView: 'Umb.CollectionView.Document.Table',
|
||||
},
|
||||
],
|
||||
},
|
||||
{ alias: 'icon', value: 'icon-layers' },
|
||||
|
||||
@@ -41,6 +41,13 @@ export const detailHandlers = [
|
||||
return res(ctx.status(200), ctx.json<PagedIReferenceResponseModel>(PagedTrackedReference));
|
||||
}),
|
||||
|
||||
rest.put(umbracoPath(`${UMB_SLUG}/:id/validate`, 'v1.1'), (_req, res, ctx) => {
|
||||
const id = _req.params.id as string;
|
||||
if (!id) return res(ctx.status(400));
|
||||
|
||||
return res(ctx.status(200));
|
||||
}),
|
||||
|
||||
rest.get(umbracoPath(`${UMB_SLUG}/:id`), (req, res, ctx) => {
|
||||
const id = req.params.id as string;
|
||||
if (!id) return res(ctx.status(400));
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
// TODO: Rename to something more obvious, naming wise this can mean anything. I suggest: umbracoManagementApiPath()
|
||||
/**
|
||||
*
|
||||
* @param path
|
||||
* Generates a path to an Umbraco API endpoint.
|
||||
* @param {string} path - The path to the Umbraco API endpoint.
|
||||
* @param {string} version - The version of the Umbraco API (default is 'v1').
|
||||
* @returns {string} The path to the Umbraco API endpoint.
|
||||
*/
|
||||
export function umbracoPath(path: string) {
|
||||
return `/umbraco/management/api/v1${path}`;
|
||||
export function umbracoPath(path: string, version = 'v1') {
|
||||
return `/umbraco/management/api/${version}${path}`;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@ import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal';
|
||||
import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action';
|
||||
import { UMB_CURRENT_USER_CONTEXT } from '@umbraco-cms/backoffice/current-user';
|
||||
import { UMB_NOTIFICATION_CONTEXT } from '@umbraco-cms/backoffice/notification';
|
||||
import { UmbLocalizationController } from '@umbraco-cms/backoffice/localization-api';
|
||||
|
||||
export class UmbPublishDocumentEntityAction extends UmbEntityActionBase<never> {
|
||||
constructor(host: UmbControllerHost, args: UmbEntityActionArgs<never>) {
|
||||
@@ -19,6 +21,9 @@ export class UmbPublishDocumentEntityAction extends UmbEntityActionBase<never> {
|
||||
override async execute() {
|
||||
if (!this.args.unique) throw new Error('The document unique identifier is missing');
|
||||
|
||||
const notificationContext = await this.getContext(UMB_NOTIFICATION_CONTEXT);
|
||||
const localize = new UmbLocalizationController(this);
|
||||
|
||||
const languageRepository = new UmbLanguageCollectionRepository(this._host);
|
||||
const { data: languageData } = await languageRepository.requestCollection({});
|
||||
|
||||
@@ -65,7 +70,15 @@ export class UmbPublishDocumentEntityAction extends UmbEntityActionBase<never> {
|
||||
if (options.length === 1) {
|
||||
const variantId = UmbVariantId.Create(documentData.variants[0]);
|
||||
const publishingRepository = new UmbDocumentPublishingRepository(this._host);
|
||||
await publishingRepository.publish(this.args.unique, [{ variantId }]);
|
||||
const { error } = await publishingRepository.publish(this.args.unique, [{ variantId }]);
|
||||
if (!error) {
|
||||
notificationContext.peek('positive', {
|
||||
data: {
|
||||
headline: localize.term('speechBubbles_editContentPublishedHeader'),
|
||||
message: localize.term('speechBubbles_editContentPublishedText'),
|
||||
},
|
||||
});
|
||||
}
|
||||
actionEventContext.dispatchEvent(event);
|
||||
return;
|
||||
}
|
||||
@@ -103,10 +116,24 @@ export class UmbPublishDocumentEntityAction extends UmbEntityActionBase<never> {
|
||||
|
||||
if (variantIds.length) {
|
||||
const publishingRepository = new UmbDocumentPublishingRepository(this._host);
|
||||
await publishingRepository.publish(
|
||||
const { error } = await publishingRepository.publish(
|
||||
this.args.unique,
|
||||
variantIds.map((variantId) => ({ variantId })),
|
||||
);
|
||||
|
||||
if (!error) {
|
||||
const documentVariants = documentData.variants.filter((variant) => result.selection.includes(variant.culture!));
|
||||
notificationContext.peek('positive', {
|
||||
data: {
|
||||
headline: localize.term('speechBubbles_editContentPublishedHeader'),
|
||||
message: localize.term(
|
||||
'speechBubbles_editVariantPublishedText',
|
||||
localize.list(documentVariants.map((v) => v.culture ?? v.name)),
|
||||
),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
actionEventContext.dispatchEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import { UmbLocalizationController } from '@umbraco-cms/backoffice/localization-
|
||||
import { UMB_ENTITY_CONTEXT } from '@umbraco-cms/backoffice/entity';
|
||||
import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action';
|
||||
import { UmbRequestReloadChildrenOfEntityEvent } from '@umbraco-cms/backoffice/entity-action';
|
||||
import { UMB_NOTIFICATION_CONTEXT } from '@umbraco-cms/backoffice/notification';
|
||||
|
||||
export class UmbDocumentPublishEntityBulkAction extends UmbEntityBulkActionBase<object> {
|
||||
async execute() {
|
||||
@@ -18,6 +19,9 @@ export class UmbDocumentPublishEntityBulkAction extends UmbEntityBulkActionBase<
|
||||
const entityType = entityContext.getEntityType();
|
||||
const unique = entityContext.getUnique();
|
||||
|
||||
const notificationContext = await this.getContext(UMB_NOTIFICATION_CONTEXT);
|
||||
const localize = new UmbLocalizationController(this);
|
||||
|
||||
if (!entityType) throw new Error('Entity type not found');
|
||||
if (unique === undefined) throw new Error('Entity unique not found');
|
||||
|
||||
@@ -46,7 +50,7 @@ export class UmbDocumentPublishEntityBulkAction extends UmbEntityBulkActionBase<
|
||||
updateDate: null,
|
||||
segment: null,
|
||||
scheduledPublishDate: null,
|
||||
scheduledUnpublishDate: null
|
||||
scheduledUnpublishDate: null,
|
||||
},
|
||||
unique: new UmbVariantId(language.unique, null).toString(),
|
||||
culture: language.unique,
|
||||
@@ -79,11 +83,24 @@ export class UmbDocumentPublishEntityBulkAction extends UmbEntityBulkActionBase<
|
||||
if (confirm !== false) {
|
||||
const variantId = new UmbVariantId(options[0].language.unique, null);
|
||||
const publishingRepository = new UmbDocumentPublishingRepository(this._host);
|
||||
let documentCnt = 0;
|
||||
|
||||
for (let i = 0; i < this.selection.length; i++) {
|
||||
const id = this.selection[i];
|
||||
await publishingRepository.publish(id, [{ variantId }]);
|
||||
const { error } = await publishingRepository.publish(id, [{ variantId }]);
|
||||
|
||||
if (!error) {
|
||||
documentCnt++;
|
||||
}
|
||||
}
|
||||
|
||||
notificationContext.peek('positive', {
|
||||
data: {
|
||||
headline: localize.term('speechBubbles_editContentPublishedHeader'),
|
||||
message: localize.term('speechBubbles_editMultiContentPublishedText', documentCnt),
|
||||
},
|
||||
});
|
||||
|
||||
eventContext.dispatchEvent(event);
|
||||
}
|
||||
return;
|
||||
@@ -116,13 +133,30 @@ export class UmbDocumentPublishEntityBulkAction extends UmbEntityBulkActionBase<
|
||||
const repository = new UmbDocumentPublishingRepository(this._host);
|
||||
|
||||
if (variantIds.length) {
|
||||
let documentCnt = 0;
|
||||
for (const unique of this.selection) {
|
||||
await repository.publish(
|
||||
const { error } = await repository.publish(
|
||||
unique,
|
||||
variantIds.map((variantId) => ({ variantId })),
|
||||
);
|
||||
eventContext.dispatchEvent(event);
|
||||
|
||||
if (!error) {
|
||||
documentCnt++;
|
||||
}
|
||||
}
|
||||
|
||||
notificationContext.peek('positive', {
|
||||
data: {
|
||||
headline: localize.term('speechBubbles_editContentPublishedHeader'),
|
||||
message: localize.term(
|
||||
'speechBubbles_editMultiVariantPublishedText',
|
||||
documentCnt,
|
||||
localize.list(variantIds.map((v) => v.culture ?? '')),
|
||||
),
|
||||
},
|
||||
});
|
||||
|
||||
eventContext.dispatchEvent(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,10 @@ import type { UmbVariantId } from '@umbraco-cms/backoffice/variant';
|
||||
export class UmbDocumentPublishingRepository extends UmbRepositoryBase {
|
||||
#init!: Promise<unknown>;
|
||||
#publishingDataSource: UmbDocumentPublishingServerDataSource;
|
||||
|
||||
/**
|
||||
* @deprecated The calling workspace context should be used instead to show notifications
|
||||
*/
|
||||
#notificationContext?: UmbNotificationContext;
|
||||
|
||||
constructor(host: UmbControllerHost) {
|
||||
@@ -36,14 +40,7 @@ export class UmbDocumentPublishingRepository extends UmbRepositoryBase {
|
||||
if (!variants.length) throw new Error('variant IDs are missing');
|
||||
await this.#init;
|
||||
|
||||
const { error } = await this.#publishingDataSource.publish(unique, variants);
|
||||
|
||||
if (!error) {
|
||||
const notification = { data: { message: `Document published` } };
|
||||
this.#notificationContext?.peek('positive', notification);
|
||||
}
|
||||
|
||||
return { error };
|
||||
return this.#publishingDataSource.publish(unique, variants);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -62,6 +59,7 @@ export class UmbDocumentPublishingRepository extends UmbRepositoryBase {
|
||||
|
||||
if (!error) {
|
||||
const notification = { data: { message: `Document unpublished` } };
|
||||
// TODO: Move this to the calling workspace context [JOV]
|
||||
this.#notificationContext?.peek('positive', notification);
|
||||
}
|
||||
|
||||
@@ -76,7 +74,12 @@ export class UmbDocumentPublishingRepository extends UmbRepositoryBase {
|
||||
* @param forceRepublish
|
||||
* @memberof UmbDocumentPublishingRepository
|
||||
*/
|
||||
async publishWithDescendants(id: string, variantIds: Array<UmbVariantId>, includeUnpublishedDescendants: boolean, forceRepublish: boolean) {
|
||||
async publishWithDescendants(
|
||||
id: string,
|
||||
variantIds: Array<UmbVariantId>,
|
||||
includeUnpublishedDescendants: boolean,
|
||||
forceRepublish: boolean,
|
||||
) {
|
||||
if (!id) throw new Error('id is missing');
|
||||
if (!variantIds) throw new Error('variant IDs are missing');
|
||||
await this.#init;
|
||||
@@ -90,6 +93,7 @@ export class UmbDocumentPublishingRepository extends UmbRepositoryBase {
|
||||
|
||||
if (!error) {
|
||||
const notification = { data: { message: `Document published with descendants` } };
|
||||
// TODO: Move this to the calling workspace context [JOV]
|
||||
this.#notificationContext?.peek('positive', notification);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ import { firstValueFrom } from '@umbraco-cms/backoffice/external/rxjs';
|
||||
import { observeMultiple } from '@umbraco-cms/backoffice/observable-api';
|
||||
import { DocumentVariantStateModel } from '@umbraco-cms/backoffice/external/backend-api';
|
||||
import type { UmbEntityUnique } from '@umbraco-cms/backoffice/entity';
|
||||
import { UmbLocalizationController } from '@umbraco-cms/backoffice/localization-api';
|
||||
|
||||
export class UmbDocumentPublishingWorkspaceContext extends UmbContextBase<UmbDocumentPublishingWorkspaceContext> {
|
||||
/**
|
||||
@@ -39,6 +40,8 @@ export class UmbDocumentPublishingWorkspaceContext extends UmbContextBase<UmbDoc
|
||||
#publishingRepository = new UmbDocumentPublishingRepository(this);
|
||||
#publishedDocumentData?: UmbDocumentDetailModel;
|
||||
#currentUnique?: UmbEntityUnique;
|
||||
#notificationContext?: typeof UMB_NOTIFICATION_CONTEXT.TYPE;
|
||||
readonly #localize = new UmbLocalizationController(this);
|
||||
|
||||
constructor(host: UmbControllerHost) {
|
||||
super(host, UMB_DOCUMENT_PUBLISHING_WORKSPACE_CONTEXT);
|
||||
@@ -53,6 +56,10 @@ export class UmbDocumentPublishingWorkspaceContext extends UmbContextBase<UmbDoc
|
||||
this.#eventContext = context;
|
||||
}).asPromise(),
|
||||
]);
|
||||
|
||||
this.consumeContext(UMB_NOTIFICATION_CONTEXT, (context) => {
|
||||
this.#notificationContext = context;
|
||||
});
|
||||
}
|
||||
|
||||
public async publish() {
|
||||
@@ -118,17 +125,47 @@ export class UmbDocumentPublishingWorkspaceContext extends UmbContextBase<UmbDoc
|
||||
|
||||
if (!variants.length) return;
|
||||
|
||||
// TODO: Validate content & Save changes for the selected variants — This was how it worked in v.13 [NL]
|
||||
const { error } = await this.#publishingRepository.publish(unique, variants);
|
||||
if (!error) {
|
||||
// reload the document so all states are updated after the publish operation
|
||||
await this.#documentWorkspaceContext.reload();
|
||||
this.#loadAndProcessLastPublished();
|
||||
const variantIds = variants.map((x) => x.variantId);
|
||||
const saveData = await this.#documentWorkspaceContext.constructSaveData(variantIds);
|
||||
await this.#documentWorkspaceContext.runMandatoryValidationForSaveData(saveData);
|
||||
await this.#documentWorkspaceContext.askServerToValidate(saveData, variantIds);
|
||||
|
||||
// request reload of this entity
|
||||
const structureEvent = new UmbRequestReloadStructureForEntityEvent({ entityType, unique });
|
||||
this.#eventContext?.dispatchEvent(structureEvent);
|
||||
}
|
||||
// TODO: Only validate the specified selection.. [NL]
|
||||
return this.#documentWorkspaceContext.validateAndSubmit(
|
||||
async () => {
|
||||
if (!this.#documentWorkspaceContext) {
|
||||
throw new Error('Document workspace context is missing');
|
||||
}
|
||||
|
||||
// Save the document before scheduling
|
||||
await this.#documentWorkspaceContext.performCreateOrUpdate(variantIds, saveData);
|
||||
|
||||
// Schedule the document
|
||||
const { error } = await this.#publishingRepository.publish(unique, variants);
|
||||
if (error) {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
|
||||
const notification = { data: { message: this.#localize.term('speechBubbles_editContentScheduledSavedText') } };
|
||||
this.#notificationContext?.peek('positive', notification);
|
||||
|
||||
// reload the document so all states are updated after the publish operation
|
||||
await this.#documentWorkspaceContext.reload();
|
||||
this.#loadAndProcessLastPublished();
|
||||
|
||||
// request reload of this entity
|
||||
const structureEvent = new UmbRequestReloadStructureForEntityEvent({ entityType, unique });
|
||||
this.#eventContext?.dispatchEvent(structureEvent);
|
||||
},
|
||||
async () => {
|
||||
const notificationContext = await this.getContext(UMB_NOTIFICATION_CONTEXT);
|
||||
notificationContext.peek('danger', {
|
||||
data: { message: this.#localize.term('speechBubbles_editContentScheduledNotSavedText') },
|
||||
});
|
||||
|
||||
return Promise.reject();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -280,9 +317,8 @@ export class UmbDocumentPublishingWorkspaceContext extends UmbContextBase<UmbDoc
|
||||
// Notifying that the save was successful, but we did not publish, which is what we want to symbolize here. [NL]
|
||||
const notificationContext = await this.getContext(UMB_NOTIFICATION_CONTEXT);
|
||||
// TODO: Get rid of the save notification.
|
||||
// TODO: Translate this message [NL]
|
||||
notificationContext.peek('danger', {
|
||||
data: { message: 'Document was not published, but we saved it for you.' },
|
||||
data: { message: this.#localize.term('speechBubbles_editContentPublishedFailedByValidation') },
|
||||
});
|
||||
// Reject even thought the save was successful, but we did not publish, which is what we want to symbolize here. [NL]
|
||||
return await Promise.reject();
|
||||
@@ -308,6 +344,17 @@ export class UmbDocumentPublishingWorkspaceContext extends UmbContextBase<UmbDoc
|
||||
);
|
||||
|
||||
if (!error) {
|
||||
const variants = saveData.variants.filter((v) => variantIds.some((id) => id.culture === v.culture));
|
||||
this.#notificationContext?.peek('positive', {
|
||||
data: {
|
||||
headline: this.#localize.term('speechBubbles_editContentPublishedHeader'),
|
||||
message: this.#localize.term(
|
||||
'speechBubbles_editVariantPublishedText',
|
||||
this.#localize.list(variants.map((v) => v.culture ?? v.name)),
|
||||
),
|
||||
},
|
||||
});
|
||||
|
||||
// reload the document so all states are updated after the publish operation
|
||||
await this.#documentWorkspaceContext.reload();
|
||||
this.#loadAndProcessLastPublished();
|
||||
|
||||
Reference in New Issue
Block a user