37132 new assetpicker must not be used in the legacy dojo editor pick the picker per host wysiwyg block editor fileimage - #37134
Conversation
Introduces ASSET_PICKER_LAUNCHER (AngularAssetPickerLauncher) as an optional DI token so the new DotAssetPickerComponent only opens in Angular Edit Content hosts. Legacy Dojo hosts (binary field, block editor, WYSIWYG plugin), where the token is absent, fall back to the pre-existing DotBrowserSelectorComponent / DotAssetSearchDialogComponent, since the new picker was never designed for those hosts.
Introduces ASSET_PICKER_LAUNCHER (AngularAssetPickerLauncher) as an optional DI token so the new DotAssetPickerComponent only opens in Angular Edit Content hosts. Legacy Dojo hosts (binary field, block editor, WYSIWYG plugin), where the token is absent, fall back to the pre-existing DotBrowserSelectorComponent / DotAssetSearchDialogComponent, since the new picker was never designed for those hosts.
|
Claude finished @nicobytes's task in 3m 20s —— View job Claude Code ReviewI reviewed the picker-per-host DI seam, both fallback paths, the launcher/token, and the guard/teardown logic across all three entry points. Findings below. New Issues
Existing (non-blocking, prior reviewer suggestions still open)
Resolved
Notes (not blocking)
The core design — an optional |
There was a problem hiding this comment.
Pull request overview
This PR addresses regression #37132 by introducing a host-capability DI seam so asset selection opens the new DotAssetPickerComponent only in the Angular Edit Content hosts, while legacy Dojo/JSP-mounted custom elements fall back to the pre-#36944 pickers.
Changes:
- Added
ASSET_PICKER_LAUNCHERinjection token +AngularAssetPickerLauncherimplementation in@dotcms/uiand exported them from the UI barrel. - Rewired the three entry points (Story Block, WYSIWYG “Add image”, File/Image “Select Existing File”) to choose new vs legacy picker based on optional token presence, and restored legacy browser-selector config for the block editor.
- Added/updated unit tests to cover both token-present (Angular host) and token-absent (legacy host) branches; updated docs/spec-kit metadata.
Reviewed changes
Copilot reviewed 22 out of 22 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| specs/37132-picker-per-host/spec.md | Spec-kit issue resolution spec describing host-based picker selection and acceptance criteria. |
| core-web/libs/ui/src/lib/components/dot-asset-picker/dot-asset-picker.component.legacy-host.spec.ts | Updates test documentation to reflect picker no longer opened from legacy host while remaining a dependency-graph guard. |
| core-web/libs/ui/src/lib/components/dot-asset-picker/asset-picker-launcher.token.ts | Introduces ASSET_PICKER_LAUNCHER token + launcher contract for host-driven picker selection. |
| core-web/libs/ui/src/lib/components/dot-asset-picker/angular-asset-picker.launcher.ts | Implements launcher that opens DotAssetPickerComponent via the caller-provided DialogService. |
| core-web/libs/ui/src/lib/components/dot-asset-picker/angular-asset-picker.launcher.spec.ts | Unit tests for launcher behavior/config translation and override handling. |
| core-web/libs/ui/src/index.ts | Exports the new token + launcher from @dotcms/ui. |
| core-web/libs/new-block-editor/src/lib/editor/services/editor-modal.service.ts | Chooses new picker vs legacy browser selector by optional ASSET_PICKER_LAUNCHER; avoids site lookup on legacy path. |
| core-web/libs/new-block-editor/src/lib/editor/services/editor-modal.service.spec.ts | Updates Angular-host tests to provide ASSET_PICKER_LAUNCHER. |
| core-web/libs/new-block-editor/src/lib/editor/services/editor-modal.service.legacy-host.spec.ts | New legacy-host tests asserting browser selector usage and no site lookup when token is absent. |
| core-web/libs/new-block-editor/src/lib/editor/config.utils.ts | Restores legacy browser-selector dialog config builder for the block editor. |
| core-web/libs/new-block-editor/CLAUDE.md | Updates library documentation to describe host-based picker selection and site-lookup behavior. |
| core-web/libs/edit-content/src/lib/fields/dot-edit-content-wysiwyg-field/dot-wysiwyg-plugin/dot-wysiwyg-plugin.service.ts | Adds optional token gating and legacy fallback dialog; adds teardown via OnDestroy. |
| core-web/libs/edit-content/src/lib/fields/dot-edit-content-wysiwyg-field/dot-wysiwyg-plugin/dot-wysiwyg-plugin.service.spec.ts | Updates Angular-host tests to provide ASSET_PICKER_LAUNCHER. |
| core-web/libs/edit-content/src/lib/fields/dot-edit-content-wysiwyg-field/dot-wysiwyg-plugin/dot-wysiwyg-plugin.service.legacy-host.spec.ts | New legacy-host tests validating legacy dialog, focus behavior, and teardown when token is absent. |
| core-web/libs/edit-content/src/lib/fields/dot-edit-content-file-field/dot-edit-content-file-field.component.spec.ts | Updates Angular-host tests to provide ASSET_PICKER_LAUNCHER. |
| core-web/libs/edit-content/src/lib/fields/dot-edit-content-file-field/components/dot-file-field/dot-file-field.component.ts | Uses optional token to select new picker vs legacy DotBrowserSelectorComponent and skips site lookup on legacy path. |
| core-web/libs/edit-content/src/lib/fields/dot-edit-content-file-field/components/dot-file-field/dot-file-field.component.spec.ts | Adds/adjusts Angular-host tests validating the new picker branch. |
| core-web/libs/edit-content/src/lib/fields/dot-edit-content-file-field/components/dot-file-field/dot-file-field.component.legacy-picker.spec.ts | New legacy-host tests validating browser selector branch and no site lookup when token is absent. |
| core-web/libs/edit-content/src/lib/edit-content.shell.component.ts | Provides ASSET_PICKER_LAUNCHER in the full-screen Edit Content host. |
| core-web/libs/edit-content/src/lib/components/dot-edit-content-side-panel/dot-edit-content-side-panel.component.ts | Provides ASSET_PICKER_LAUNCHER in the side-panel Edit Content host. |
| core-web/libs/edit-content/src/lib/components/dot-create-content-dialog/dot-create-content-dialog.component.ts | Provides ASSET_PICKER_LAUNCHER in the dialog Edit Content host (UVE/Relationship). |
| .specify/feature.json | Points Spec-Kit to the feature directory for this work. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
…used-in-the-legacy-dojo-editor-pick-the-picker-per-host-wysiwyg-block-editor-fileimage
…rdown closes it `DynamicDialogRef.close()` pushes through `onClose` synchronously (`_onClose.next(result)`; the close animation only gates `destroy()`), so the handler ran inline inside `ngOnDestroy` and called `editor.focus()` on a TinyMCE instance `DotWysiwygTinymceComponent.ngOnDestroy` may already have `remove()`d. The PR review suggested `takeUntilDestroyed`, but that gives no ordering guarantee against this very hook — if `ngOnDestroy` runs first the subscription is still live and the handler fires anyway. So the `Subscription` is held and unsubscribed *before* the dialog is closed, which is deterministic regardless of hook order and also covers the leaked-subscription concern. Suppressing the handler means nothing else clears `imagePickerBusy`, so teardown clears it. Two tests pin this, using a ref stub whose `close()` emits synchronously like the real one. Also rewords `buildBrowserSelectorConfig`'s JSDoc. It claimed the config mirrors the File field's, but this builder keeps `style.overflow: 'hidden'` and a viewport-clamped `min-height` because the editor opens it from inside its full-screen shell. Both builders are faithful restores of their own host's pre-#36944 config — the comment, restored verbatim along with the function, was the part that was wrong. Addresses review feedback on #37134. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…used-in-the-legacy-dojo-editor-pick-the-picker-per-host-wysiwyg-block-editor-fileimage
…used-in-the-legacy-dojo-editor-pick-the-picker-per-host-wysiwyg-block-editor-fileimage
The legacy branches added by this PR set their busy/pending guard and then open synchronously, but the guard is only ever cleared by the picker's `onClose`. An open that throws never wires one, so the flag stayed `true` and "Select Existing File" / the WYSIWYG *Add image* button were dead for the rest of the session, with no toast and no log. Both entry points now release the guard and rethrow — swallowing would leave a button that silently does nothing. Also from review: - Soften the `DotWysiwygPluginService` doc blocks. They asserted as settled fact that legacy Dojo pages construct the service, which contradicts the spec's own Assumptions: the Dojo editor renders WYSIWYG as a textarea plus JSP-side TinyMCE and no Angular custom element exists for the field, so the fallback is a consistency guard, not a live regression path. - Add `config.utils.spec.ts`, pinning `buildBrowserSelectorConfig`'s restored values — every browse flag, the sizing, and the fullscreen-clearing `baseZIndex`. Restoring that config exactly is an acceptance criterion of #37132 and nothing covered it directly. Verified by mutation: dropping `showWorking` fails this spec. - Assert the whole config object in `editor-modal.service.legacy-host.spec.ts` instead of four fields, which pins that the service delegates to the builder with the right arguments. Note this cannot catch a field dropped from the builder — both sides move together — which is why the spec above exists. - Use the shared `createFakeContentlet` / `createFakeSite` factories instead of a cast literal and a hand-built `DotSite`. Addresses review feedback on #37134. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This pull request introduces a new Angular-based Asset Picker for file and image selection in the Edit Content experience, ensuring it is only available in modern Angular hosts while maintaining the legacy picker for older or custom element hosts. It also adds comprehensive tests to verify both picker behaviors. The changes ensure a seamless transition between the new and legacy pickers depending on the hosting context, and provide clear dependency injection for the new picker.
Asset Picker Integration (Angular Hosts):
AngularAssetPickerLauncheras the provider forASSET_PICKER_LAUNCHERin all Angular Edit Content hosts (dot-create-content-dialog, side panel, and shell), ensuring the new Asset Picker is used in these contexts. [1] [2] [3]ASSET_PICKER_LAUNCHERandAngularAssetPickerLauncherwhere needed. [1] [2] [3] [4] [5]Legacy Picker Preservation (Custom Element/Legacy Hosts):
DotFileFieldComponentto injectASSET_PICKER_LAUNCHERoptionally; if absent, falls back to the legacyDotBrowserSelectorComponentfor file selection, maintaining previous behavior in legacy hosts. [1] [2] [3]dot-file-field.component.legacy-picker.spec.ts) to verify the legacy picker is used and behaves as expected when the new launcher is not provided.Testing and Verification:
Project Configuration:
.specify/feature.json.Closes #37132