Preview: Add validation support to Save and Preview button (closes #20616) (#20805)

* chore(mock): adds missing try/catch around document lookup

* fix: lets the 'save and preview' button extend the 'save' button to follow the same logic in terms of when it enables/disabled - it did not have much logic before

* fix: runs validation from the server when save and previewing to ensure the UI shows what is missing
This commit is contained in:
Jacob Overgaard
2025-11-13 12:25:17 +01:00
committed by GitHub
parent 597eb58063
commit eeda55c06f
3 changed files with 22 additions and 29 deletions

View File

@@ -1,4 +1,5 @@
const { rest } = window.MockServiceWorker; const { rest } = window.MockServiceWorker;
import type { UmbMockDocumentModel } from '../../data/document/document.data.js';
import { umbDocumentMockDb } from '../../data/document/document.db.js'; import { umbDocumentMockDb } from '../../data/document/document.db.js';
import { items as referenceData } from '../../data/tracked-reference.data.js'; import { items as referenceData } from '../../data/tracked-reference.data.js';
import { UMB_SLUG } from './slug.js'; import { UMB_SLUG } from './slug.js';
@@ -77,8 +78,14 @@ export const detailHandlers = [
rest.get(umbracoPath(`${UMB_SLUG}/:id/available-segment-options`), (req, res, ctx) => { rest.get(umbracoPath(`${UMB_SLUG}/:id/available-segment-options`), (req, res, ctx) => {
const id = req.params.id as string; const id = req.params.id as string;
if (!id) return res(ctx.status(400)); if (!id) return res(ctx.status(400));
const document = umbDocumentMockDb.detail.read(id);
if (!document) return res(ctx.status(404)); let document: UmbMockDocumentModel | null = null;
try {
document = umbDocumentMockDb.detail.read(id);
} catch {
return res(ctx.status(404));
}
const availableSegments = document.variants.filter((v) => !!v.segment).map((v) => v.segment!) ?? []; const availableSegments = document.variants.filter((v) => !!v.segment).map((v) => v.segment!) ?? [];

View File

@@ -1,30 +1,9 @@
import { UmbDocumentUserPermissionCondition } from '../../user-permissions/document/conditions/document-user-permission.condition.js'; import { UmbDocumentSaveWorkspaceAction } from '../../workspace/actions/save.action.js';
import { UMB_USER_PERMISSION_DOCUMENT_UPDATE } from '../../user-permissions/document/constants.js';
import { UmbWorkspaceActionBase } from '@umbraco-cms/backoffice/workspace';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
export class UmbDocumentSaveAndPreviewWorkspaceAction extends UmbWorkspaceActionBase { export class UmbDocumentSaveAndPreviewWorkspaceAction extends UmbDocumentSaveWorkspaceAction {
constructor(host: UmbControllerHost, args: any) { override async execute() {
super(host, args); await this._retrieveWorkspaceContext;
await this._workspaceContext?.saveAndPreview();
/* The action is disabled by default because the onChange callback
will first be triggered when the condition is changed to permitted */
this.disable();
const condition = new UmbDocumentUserPermissionCondition(host, {
host,
config: {
alias: 'Umb.Condition.UserPermission.Document',
allOf: [UMB_USER_PERMISSION_DOCUMENT_UPDATE],
},
onChange: () => {
if (condition.permitted) {
this.enable();
} else {
this.disable();
}
},
});
} }
} }

View File

@@ -332,7 +332,14 @@ export class UmbDocumentWorkspaceContext
firstVariantId = UmbVariantId.FromString(selected[0]); firstVariantId = UmbVariantId.FromString(selected[0]);
const variantIds = [firstVariantId]; const variantIds = [firstVariantId];
const saveData = await this._data.constructData(variantIds); const saveData = await this._data.constructData(variantIds);
await this.runMandatoryValidationForSaveData(saveData);
// Run mandatory validation (checks for name, etc.)
await this.runMandatoryValidationForSaveData(saveData, variantIds);
// Ask server to validate and show validation tooltips (like the Save action does)
await this.askServerToValidate(saveData, variantIds);
// Perform save
await this.performCreateOrUpdate(variantIds, saveData); await this.performCreateOrUpdate(variantIds, saveData);
} }