Skip to content

fix(edit-content): forward contentlet languageId to file field browser selector#35297

Draft
oidacra wants to merge 3 commits intomainfrom
issue-34459-language-specific-images-not-visible-in-new-edit-c
Draft

fix(edit-content): forward contentlet languageId to file field browser selector#35297
oidacra wants to merge 3 commits intomainfrom
issue-34459-language-specific-images-not-visible-in-new-edit-c

Conversation

@oidacra
Copy link
Copy Markdown
Member

@oidacra oidacra commented Apr 13, 2026

Summary

Fixes a defect where image (and other file) fields in the new Edit Content screen did not show assets that exist only in the active editing language. The browser selector was opening without the contentlet's languageId, so the POST /api/v1/browser request defaulted to the system default language and hid language-specific assets.

The fix carries languageId end-to-end through the dialog → store → HTTP chain:

  • ContentByFolderParams now accepts an optional languageId?: number (both copies kept in sync).
  • DotFileFieldComponent.showSelectExistingFileDialog() forwards this.$contentlet().languageId in the dialog data.
  • DotBrowserSelectorComponent.ngOnInit() already spreads DynamicDialogConfig.data into $folderParams, so the value propagates to the store and HTTP call without further code changes.
  • AngularFormBridge.openBrowserModal also already passes params through via a shallow spread, so VTL custom fields that set languageId in options.params are automatically forwarded now that the interface supports it.

Closes #34459

Acceptance Criteria

  • ContentByFolderParams includes an optional languageId
  • File field passes the contentlet's languageId to the browser selector dialog data
  • AngularFormBridge.openBrowserModal forwards languageId (no bridge code change needed beyond the interface)
  • Language-specific images (e.g. French-only) appear in the browser selector when editing content in that language
  • Default-language images continue to appear for default-language edits (no regression)
  • Behavior matches the legacy Edit Content screen for localized content
  • Unit tests added for the forwarding chain (dot-browser-selector.component.spec.ts, dot-edit-content-file-field.component.spec.ts)

Test Plan

Automated

  • yarn nx test ui --testPathPattern=dot-browser-selector — 3 new tests assert languageId propagation from DynamicDialogConfig.data through $folderParams and into store.uploadFile
  • yarn nx test edit-content --testPathPattern=dot-edit-content-file-field — passes (new assertion added inside the existing xdescribe'd suite will run when that suite is un-skipped)
  • yarn nx build dotcms-ui — compiles cleanly
  • yarn nx lint data-access edit-content — clean (pre-existing lint errors in dotcms-models are unrelated to this change and exist on main)

Manual

  • Create an image asset that only has a French language version
  • Create/edit a contentlet with an image field in French in the new Edit Content screen
  • Open the "Select Existing File" dialog — the French-only image is visible and selectable
  • Repeat while editing in English — default-language images still appear
  • Confirm parity with the legacy Edit Content screen

Changed Files

  • core-web/libs/dotcms-models/src/lib/dot-site.model.ts
  • core-web/libs/data-access/src/lib/dot-site/dot-site.service.ts
  • core-web/libs/edit-content/src/lib/fields/dot-edit-content-file-field/components/dot-file-field/dot-file-field.component.ts
  • core-web/libs/edit-content/src/lib/fields/dot-edit-content-file-field/dot-edit-content-file-field.component.spec.ts
  • core-web/libs/ui/src/lib/components/dot-browser-selector/dot-browser-selector.component.spec.ts

Visual Changes

UI-visible change: the "Select Existing File" dialog in the new Edit Content screen now lists images/files that match the contentlet's current language. Please attach before/after screenshots or a short clip showing a French-only image appearing in the selector when editing in French.

…r selector

The new Edit Content screen file field was opening the browser selector dialog
without passing the contentlet's languageId, so the backend
POST /api/v1/browser request defaulted to the system default language and
excluded assets that only exist in the active language (e.g. French-only
images were invisible when editing French content).

Add an optional languageId to ContentByFolderParams and forward the current
contentlet's languageId from DotFileFieldComponent.showSelectExistingFileDialog
so it flows through DotBrowserSelectorComponent's $folderParams into the
browser API call. The AngularFormBridge is unaffected; it already spreads
params into the dialog data.

Closes #34459
@claude
Copy link
Copy Markdown
Contributor

claude bot commented Apr 13, 2026

Claude finished @oidacra's task in 2m 35s —— View job


PR Review

  • Gather context and read changed files
  • Review model/interface changes
  • Review component changes
  • Review test changes
  • Post findings

The approach is sound. A few issues worth flagging:

1. Primary fix path has no running test coverage

dot-edit-content-file-field.component.spec.ts — the new showSelectExistingFileDialog describe block (L295+) is inside the outer xdescribe, so it is permanently skipped. The store-based path (#editContentStore?.currentLocale()?.id) — which is the actual fix — is never exercised by the test suite. The fallback path ($contentlet()?.languageId) was the behavior before the fix, and even that test can't run. Either move the new tests outside the xdescribe, or un-skip the parent suite.

2. Optional-chain guard on a required input is dead code

dot-file-field.component.ts:455

this.$contentlet()?.languageId

$contentlet is declared as input.required<DotCMSContentlet>() (L136), so it can never return null or undefined. The ?. will never short-circuit and the ?? branch via this path never triggers. It's harmless but the comment in commit 8a7b768a ("guard contentlet null") is misleading — it guards against something that can't happen given the type.

3. Silent no-op when locales haven't loaded yet

currentLocale initializes to null in the store state. If showSelectExistingFileDialog() is called before the locales effect resolves (uncommon but possible with a slow network), currentLocale()?.id is undefined, the ?? fires, and the behavior degrades to the pre-fix state (uses contentlet's languageId, which may also be undefined for a new draft). No error, no visible signal to the user. Acceptable as a graceful degradation but worth documenting in the component comment or the PR acceptance criteria.

4. ContentByFolderParams is duplicated across two files

The interface lives in both dotcms-models/dot-site.model.ts and data-access/dot-site.service.ts. Both are updated here, but they'll silently drift the next time someone adds a field to one and forgets the other. This is pre-existing, but it's a latent bug surface that this PR touches directly. Fix this →

5. onNodeSelect spread preserves languageId — confirmed correct

$folderParams.update((prev) => ({ ...prev, hostFolderId: id })) naturally preserves all other fields. The test at L243–255 in dot-browser-selector.component.spec.ts verifies this. No issue.

Summary: the fix logic is correct. The blocking concern is (1) — if #editContentStore?.currentLocale()?.id is the preferred path but its test is in xdescribe, there is no CI signal if that path regresses.

…ile field dialog

$contentlet is input.required but its value can be null while a contentlet
is still being hydrated (e.g. new content with no saved contentlet yet),
causing "Cannot read properties of null (reading 'languageId')" when the
Select Existing File dialog is opened. Restore the optional chain so the
dialog still opens in that state; languageId is forwarded as undefined
which the backend treats as "any language", matching prior behavior.
…tore

For new contentlets the $contentlet input has no languageId yet, so the
"Select Existing File" dialog was falling back to the session language
and hiding assets the user actually wanted to pick when editing in a
non-default locale (e.g. fr-FR).

Read the active locale from DotEditContentStore.currentLocale() first
(injected as optional so the component can still render outside the
edit-content layout / in unit tests) and fall back to the contentlet's
languageId when the store isn't available. Verified in the UI: switching
to fr-FR on a new contentlet and opening the Select Existing Image
dialog now sends the fr-FR languageId in the /api/v1/browser POST and
shows French-only assets.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI: Safe To Rollback Area : Frontend PR changes Angular/TypeScript frontend code

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

[DEFECT] Language-specific images not visible in new Edit Content screen

1 participant