fix(timeline): rehydrate event-form pickers after a validation failure
Decision 6 / REQ-010 promised the pickers survive a fail(400) "including pre-selected persons/documents", but EventForm only seeded them from event/initialPersons — never from the fail payload — and the payload carried only bare ids, which can't rebuild a chip (chips need displayName/title). On the use:enhance path the in-memory selection survived; on a no-JS full reload the chips were silently dropped. Now the save action re-fetches the selected persons/documents by id (lookupSelections, non-ok swallowed like the prefill path) and returns full chip data; EventForm seeds the pickers from form.persons/documents ahead of the seeded event. Extract preservedFormFields() to DRY the four fail payloads; validateEventForm now returns the error pair and the route owns the fail(). Component test pins the rehydration; the server spec now asserts the fail payload carries labelled chips, not just ids. Addresses PR #832 review (Developer + Requirements Engineer concern, REQ-010). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -5,6 +5,8 @@ import { requireWriteAll } from '$lib/shared/server/permissions';
|
||||
import {
|
||||
parseEventForm,
|
||||
validateEventForm,
|
||||
preservedFormFields,
|
||||
lookupSelections,
|
||||
toEventRequest,
|
||||
resolveNavTarget
|
||||
} from '$lib/timeline/eventFormServer';
|
||||
@@ -47,14 +49,21 @@ export const actions = {
|
||||
}) => {
|
||||
const formData = await request.formData();
|
||||
const parsed = parseEventForm(formData);
|
||||
const api = createApiClient(fetch);
|
||||
|
||||
const invalid = validateEventForm(parsed);
|
||||
if (invalid) return invalid;
|
||||
const errors = validateEventForm(parsed);
|
||||
if (errors) {
|
||||
const { persons, documents } = await lookupSelections(
|
||||
api,
|
||||
parsed.personIds,
|
||||
parsed.documentIds
|
||||
);
|
||||
return fail(400, { ...errors, ...preservedFormFields(parsed), persons, documents });
|
||||
}
|
||||
|
||||
const versionRaw = formData.get('version')?.toString();
|
||||
const version = versionRaw ? Number(versionRaw) : undefined;
|
||||
|
||||
const api = createApiClient(fetch);
|
||||
const result = await api.PUT('/api/timeline/events/{id}', {
|
||||
params: { path: { id: params.id } },
|
||||
body: toEventRequest(parsed, version)
|
||||
@@ -63,11 +72,7 @@ export const actions = {
|
||||
if (!result.response.ok) {
|
||||
return fail(result.response.status, {
|
||||
error: getErrorMessage(extractErrorCode(result.error)),
|
||||
title: parsed.title,
|
||||
description: parsed.description,
|
||||
type: parsed.type,
|
||||
personIds: parsed.personIds,
|
||||
documentIds: parsed.documentIds
|
||||
...preservedFormFields(parsed)
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user