feat(uve): auto-create page language version on language switch (#36348)#36358
feat(uve): auto-create page language version on language switch (#36348)#36358zJaaal wants to merge 3 commits into
Conversation
The Upload-button flow silently dropped the file in Chrome: onFileChange read input.files (a live FileList) but reset input.value='' BEFORE the guard, which empties that same live FileList, so files.length was 0 and the upload no-oped. Consume the files (capture the File into FormData via resolveFilesUpload) before resetting the input. Adds a regression test (verified red on the old ordering, green on the fix) that models the live-FileList behavior jsdom doesn't reproduce. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replace the confirmation dialog + legacy edit-contentlet iframe with a programmatic flow: on switching to an untranslated language, fetch the page's content type, build the new-version payload from its actual field definitions, fire a workflow NEW action to create the version in the target language, show a success toast, and reload via pageLoad. Both triggers (toolbar onLanguageSelected and the editor $translatePageEffect) route through the same path. Spike #36348. Does NOT handle URL-content-map detail pages — see #36355. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
🤖 dotBot Review (Bedrock)Reviewed 3 file(s); 2 candidate(s) → 2 confirmed, 0 uncertain (unverified, kept for review). Confirmed findings
us.deepseek.r1-v1:0 · Run: #28396001519 · tokens: in: 18266 · out: 3423 · total: 21689 · calls: 7 · est. ~$0.043 |
|
Claude finished @zJaaal's task in 1m 0s —— View job Rollback Safety Analysis
Verdict: ✅ Safe To RollbackAfter analyzing the full diff against all rollback-unsafe categories in AnalysisThe changes in this PR are entirely frontend/UI in scope:
Categories checked and cleared:
The PR invokes the existing The label |
|
|
||
| if (!languageHasTranslation) { | ||
| // Show confirmation dialog to create a new translation | ||
| // Emit to the shell, which creates the language version and reloads. |
There was a problem hiding this comment.
🟠 [High] Automatic language version creation removes user consent mechanism
The removal of the confirmation dialog (createNewTranslation) enables silent content creation on language switch. The code now directly calls translatePage without user confirmation, as shown by the removed dialog service call and conditional workflow. This violates user expectations for destructive actions by removing cancellation capability.
| const data: Record<string, string> = {}; | ||
|
|
||
| (contentType.fields ?? []).forEach((field) => { | ||
| const key = field.variable; |
There was a problem hiding this comment.
🟠 [High] String conversion of all field values corrupts non-string data types
The code uses String() to convert all field values when building translation data, which will improperly serialize non-string types (numbers, booleans, dates) into string representations. This violates content type field definitions and will corrupt data integrity for non-string fields in translated pages.
| const source = page as unknown as Record<string, unknown>; | ||
| const data: Record<string, string> = {}; | ||
|
|
||
| (contentType.fields ?? []).forEach((field) => { |
There was a problem hiding this comment.
🟠 [High] Skipping object-type fields creates incomplete translations
The code explicitly skips fields with fieldType === 'object' when building translation data (line 1759), resulting in missing data for all object-type fields during language version creation. This includes valid JSON field data that should be preserved across translations.
| // Show confirmation dialog to create a new translation | ||
| // Emit to the shell, which creates the language version and reloads. | ||
| const page = this.#store.pageAsset()?.page; | ||
| if (page) { |
There was a problem hiding this comment.
🟠 [High] Missing error handling after translatePage emission leaves language selector in inconsistent state
The code emits translatePage but doesn't handle errors or reset the language selector on failure. When autoCreateTranslation fails (caught in editor component's error handler), the toolbar's language selector remains set to the new language while the page stays in original language. The removed dialog's rejection callback previously handled this reset, but current implementation lacks equivalent safety.
|
|
||
| // Only copy primitive field values that exist on the source page. | ||
| if (value === null || value === undefined || typeof value === 'object') { | ||
| return; |
There was a problem hiding this comment.
🟠 [High] Array field values corrupted during translation
The code uses typeof value === 'object' which includes arrays, then spreads them as objects via Object.keys().forEach(), converting arrays to {0:...,1:...} objects. This corrupts multi-select/tag fields that require array values.
Proposed Changes
Draft / spike (#36348). Prototype that replaces the "Create new language version?" confirmation dialog + legacy edit-contentlet iframe with a programmatic auto-create on language switch. Opened as a draft to demonstrate the behavior and inform the decision — see the trade-offs and the open detail-page gap below before considering this for merge.
What changed
DotContentTypeService.getContentType) and builds the new-version payload from its real field definitions (no hard-coded field allow/deny list).identifier(new language version of the same content), overrideslanguageId, and setsindexPolicy=WAIT_FOR.NEWaction viaDotWorkflowActionsFireService.newContentlet(...).uveStore.pageLoad({ language_id }).onLanguageSelectedand the editor$translatePageEffect(deep-link / direct-load guard).createNewTranslationin both the toolbar and the editor.Files
edit-ema-editor.component.ts—translatePage→#autoCreateTranslation(content-type fetch + fire + toast + reload) and#buildTranslationData.dot-uve-toolbar.component.ts— emittranslatePagedirectly instead of prompting; removedcreateNewTranslation.Language.properties— new keyeditpage.language-change-missing-lang-populate.success.Spike findings
NEWaction with the sameidentifier+ newlanguageIdcreates the language version, andpageLoadre-renders it.urlContentMapcontent.Recommendation
Keep the confirmation dialog as a guardrail rather than removing the friction product-wide for a single customer; the complaint is a UX/education issue (creating the version already works). If we do reduce friction, prefer an informative, cancellable pre-filled dialog over a silent write. Prioritize #36355 as the higher-impact bug. Capture the decision in an ADR.
Testing
dialog.translatePage/ confirm-then-emit) and will fail until updated — intentionally left for the spike branch.Related: spike #36348 · original #35647 · detail-page defect #36355
🤖 Generated with Claude Code