fix(edit-content): parse block editor JSON strings when translating content#35247
fix(edit-content): parse block editor JSON strings when translating content#35247
Conversation
|
Claude finished @oidacra's task in 3m 39s —— View job Code Review
3 items worth a second look: 1.
|
There was a problem hiding this comment.
Pull request overview
Fixes translated/copied Block Editor fields being displayed as plain text by parsing JSON-string values into structured objects during initial form value resolution.
Changes:
- Added a dedicated
blockEditorResolutionFnthat attempts toJSON.parse()Block Editor values when they arrive as JSON strings. - Wired
FIELD_TYPES.BLOCK_EDITORto use the new resolution function instead ofdefaultResolutionFn. - Added Jest tests covering Block Editor resolution behavior and removed
BLOCK_EDITORfrom the “default resolution fn” group.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| core-web/libs/edit-content/src/lib/components/dot-edit-content-form/dot-edit-content-form-resolutions.ts | Introduces blockEditorResolutionFn and maps it to FIELD_TYPES.BLOCK_EDITOR so block editor receives structured data when API returns JSON strings. |
| core-web/libs/edit-content/src/lib/components/dot-edit-content-form/dot-edit-content-form-resolutions.spec.ts | Adds unit tests for Block Editor resolution and updates the default-mapping assertions accordingly. |
...s/edit-content/src/lib/components/dot-edit-content-form/dot-edit-content-form-resolutions.ts
Outdated
Show resolved
Hide resolved
...t-content/src/lib/components/dot-edit-content-form/dot-edit-content-form-resolutions.spec.ts
Show resolved
Hide resolved
e92a2c2 to
3062ffb
Compare
…ontent Add blockEditorResolutionFn that JSON.parse()s string values returned by the API when copying/translating content to a new language. Closes #34025
Use Record<string, unknown> instead of object for blockEditorResolutionFn type and add test for invalid JSON catch path.
… Map.toString() persistence After blockEditorResolutionFn parses the JSON string to an object so the editor can render translated content, the FormControl holds an object. If the user saves without interacting with the editor (which is what emits the JSON.stringify via onChange), the object was sent to the backend and persisted as Map.toString(), corrupting the field on subsequent loads. Stringify BLOCK_EDITOR object values in processFieldValue so the submit payload matches what the editor's own onChange emits. Closes #34025
3062ffb to
0630dc7
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (1)
core-web/libs/edit-content/src/lib/utils/functions.util.ts:614
processFieldValuenow acceptsRecord<string, unknown>, but it callsisFlattenedField(fieldValue, field)whereisFlattenedFieldis still typed to accept onlystring | string[] | Date | number | null | undefined. This makes the call site type-incompatible and can fail TypeScript compilation. Consider wideningisFlattenedField'sfieldValueparameter to include the new object type (orunknown) so it matchesprocessFieldValue's input union.
export const processFieldValue = (
fieldValue: string | string[] | Date | number | Record<string, unknown> | null | undefined,
field: DotCMSContentTypeField
): string | number | null | undefined => {
// Handle flattened fields (multi-select, etc.)
if (isFlattenedField(fieldValue, field)) {
return (fieldValue as string[]).join(',');
}
…ly primitives processFieldValue widened its input type to include Record<string, unknown> for the block editor path, but downstream helpers (isFlattenedField, processCalendarFieldValue) still declare primitive-only signatures. Handle the block editor branch up front and cast the remaining value to the primitive union, so helper signatures remain accurate. Also guard against arrays and Date instances (typeof 'object' in JS) to make the intent explicit.
…hrough processFieldValue Replace the previous early-return-with-as-cast approach with wider helper signatures. isFlattenedField and processCalendarFieldValue already guard internally against unexpected inputs at runtime (type guard / explicit fallthrough), so accepting unknown honestly reflects their defensive behavior and removes the need for casts in processFieldValue.
…lue to keep FormValues inference intact Widening processFormValue's input to include Record<string, unknown> caused TS to infer that the !field branch could return an object, breaking FormValues assignability. At runtime the input never carries that shape to this function's output (processFieldValue stringifies BLOCK_EDITOR objects before they reach Object.fromEntries), so the widening was never necessary here. processFieldValue keeps its widened input since it legitimately handles the object path internally.
Summary
blockEditorResolutionFnthatJSON.parse()s block editor values when they come as JSON strings from the API (happens during content translation/copy to new language)defaultResolutionFnwhich returned the raw JSON string, causing the editor to display it as plain text instead of structured contentCloses #34025
Acceptance Criteria
Test Plan
yarn nx test edit-content --testPathPattern=dot-edit-content-form-resolutions— all tests passChanged Files
libs/edit-content/.../dot-edit-content-form-resolutions.tsblockEditorResolutionFn, mapped toFIELD_TYPES.BLOCK_EDITORlibs/edit-content/.../dot-edit-content-form-resolutions.spec.tsThis PR fixes: #34025