[Listing] Search-mode extension seam (SearchModeRegistry) for pluggable smart search - #4076
Open
xIrusux wants to merge 28 commits into
Open
[Listing] Search-mode extension seam (SearchModeRegistry) for pluggable smart search#4076xIrusux wants to merge 28 commits into
xIrusux wants to merge 28 commits into
Conversation
Generic seam for pluggable search modes on the listing search bar, so bundles (first consumer: backend-power-tools semantic search) can register modes that swap what the search input emits: - SearchModeAbstract + SearchModeRegistry (DynamicTypeRegistryAbstract-based), bound as Element/Listing/SearchModeRegistry and SDK-exported - SearchModeSelect dropdown as a left Compact segment of SearchTermFilter, with per-mode availability, disabled entries with hints, warning line, and a purple collapsed label for active smart modes - searchMode filter value (hidden descriptor, Clear-all resets to full text); the searchTerm descriptor emits the active mode's column filter instead of system.fulltext; registered mode filter types are stripped from restored base filters (duplicates would 422) - blocked modes gate Apply (sidebar) and Enter (search-modal top bars) - opt-in per listing via GeneralFiltersDecoratorConfig.elementType (asset and data-object grids + search-modal Assets/Data Objects tabs); listings without it keep the plain search bar, as does any install with no registered modes - new full-text-search / smart-search icons (generate-icons ride-along rewrites reverted) Part of pimcore/product-management#1369. Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
Saved-search restoration, filter cleanup, and blocked-search clearing have unresolved moderate issues.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Adds an SDK-extensible search-mode registry and integrates smart-search modes into asset and data-object listings.
Changes:
- Adds search-mode contracts, registry, selector UI, icons, and translations.
- Routes search terms through selected modes with availability handling.
- Enables modes for asset/object grids and search-modal tabs.
Unresolved comments:
- Moderate (1 vote) —
search-mode-filter.ts:20: Saved smart searches do not restore their mode/query correctly. Add registry-aware restoration and tests. - Moderate (2 votes) —
element-filter-setup.ts:44: Cleanup excludes hidden or permission-gated modes. Derive cleanup types from all registry entries. - Moderate (1 vote) —
search-mode-abstract.ts:67: The public contract lacks generic deserialization for saved searches. Add a restoration hook, integration, and test. - Nit (2 votes) —
search-mode-select.tsx:74: Use the repository’sIconButtonabstraction. - Moderate (1 vote) —
search-term-filter.tsx:58: Blocked modes prevent clearing the applied search. Allow empty searches through the guard.
File summaries
| File | Reviewed change |
|---|---|
translations/studio.sv.yaml |
Adds Swedish labels. |
translations/studio.no.yaml |
Adds Norwegian labels. |
translations/studio.it.yaml |
Adds Italian labels. |
translations/studio.fr.yaml |
Adds French labels. |
translations/studio.es.yaml |
Adds Spanish labels. |
translations/studio.en.yaml |
Adds English labels. |
translations/studio.de.yaml |
Adds German labels. |
assets/js/src/sdk/modules/element/index.ts |
Exports the search-mode API. |
assets/js/src/core/modules/search/modal/tabs/object/listing/object-search-listing.tsx |
Enables object search modes. |
assets/js/src/core/modules/search/modal/tabs/asset/listing/asset-search-listing.tsx |
Enables asset search modes. |
assets/js/src/core/modules/icon-library/index.ts |
Registers new icons. |
assets/js/src/core/modules/element/listing/decorators/general-filters/view-layer/components/sidebar/tabs/filters/filter-container-inner.tsx |
Applies and gates mode state. |
assets/js/src/core/modules/element/listing/decorators/general-filters/view-layer/components/search/search-term-filter.tsx |
Integrates mode selection with search. |
assets/js/src/core/modules/element/listing/decorators/general-filters/view-layer/components/search/search-mode-select.tsx |
Implements the mode selector. |
assets/js/src/core/modules/element/listing/decorators/general-filters/view-layer/components/search/search-mode-select.styles.ts |
Styles the selector. |
assets/js/src/core/modules/element/listing/decorators/general-filters/search-modes/use-search-mode.ts |
Resolves mode state and availability. |
assets/js/src/core/modules/element/listing/decorators/general-filters/search-modes/search-mode-registry.ts |
Adds the registry. |
assets/js/src/core/modules/element/listing/decorators/general-filters/search-modes/search-mode-abstract.ts |
Defines the extension contract. |
assets/js/src/core/modules/element/listing/decorators/general-filters/search-modes/constants.ts |
Defines the built-in mode ID. |
assets/js/src/core/modules/element/listing/decorators/general-filters/general-filters-decorator.ts |
Adds listing opt-in configuration. |
assets/js/src/core/modules/element/listing/decorators/general-filters/element-filters/use-element-filter-values.ts |
Adds mode filter state. |
assets/js/src/core/modules/element/listing/decorators/general-filters/element-filters/element-filter-types.ts |
Extends filter context types. |
assets/js/src/core/modules/element/listing/decorators/general-filters/element-filters/element-filter-setup.ts |
Builds mode-aware query context. |
assets/js/src/core/modules/element/listing/decorators/general-filters/element-filters/definitions/search-term-filter.tsx |
Emits mode-specific filters. |
assets/js/src/core/modules/element/listing/decorators/general-filters/element-filters/definitions/search-mode-filter.ts |
Defines hidden mode state. |
assets/js/src/core/modules/element/listing/decorators/general-filters/element-filters/definitions/index.ts |
Registers the mode descriptor. |
assets/js/src/core/modules/element/listing/decorators/general-filters/element-filters/build-element-filter-query.ts |
Removes conflicting base filters. |
assets/js/src/core/modules/data-object/listing/index.ts |
Enables object listing modes. |
assets/js/src/core/modules/asset/listing/index.ts |
Enables asset listing modes. |
assets/js/src/core/assets/icons/smart-search.inline.svg |
Adds the smart-search icon. |
assets/js/src/core/assets/icons/full-text-search.inline.svg |
Adds the full-text icon. |
assets/js/src/core/app/config/services/service-ids.ts |
Adds the registry service ID. |
assets/js/src/core/app/config/services/index.ts |
Binds the registry service. |
Review details
- Files reviewed: 31/34 changed files
- Comments generated: 5
- Review effort level: Balanced
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
…rch degradation - Derive registeredFilterTypes from every registry entry, not only visible modes, so a hidden mode's filter is still cleaned from restored base filters - Let an empty term through the blocked-mode guard so clearing recovers from a blocked smart search instead of keeping the stale applied query - Saved-search restore: exclude registered mode filter types from the field filters and reset the search mode to full text; a saved smart search degrades cleanly until a mode-level restore contract lands with the first concrete mode Co-Authored-By: Claude <noreply@anthropic.com>
Replace the hardwired SearchModeSelect mount with the component-registry slot 'element.listing.search.slots.prefix' (SlotRenderer, same pattern as asset.tree.node.meta). SearchModeSelect becomes a self-contained default entry registered by the element module: it reads the listing context via hooks, owns the mode-change side effects, and renders nothing when no modes are registered. Any bundle can now put other controls beside the listing search input without touching the search-mode contract. Co-Authored-By: Claude <noreply@anthropic.com>
…mode warning Verified via Playwright in the demo: the blocked-mode warning rendered into the DOM but was invisible in both modal tabs until size='auto'. Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…e-seam Conflict resolution: 2026.x moved the service bindings from services/index.ts into the side-effect-free install-core-services.ts — took the refactored index.ts and re-added the SearchModeRegistry binding in the installer. build-dist: kept the branch build; the workflow regenerates it on push. Co-Authored-By: Claude <noreply@anthropic.com>
… Array#push) Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
The search icon/Enter in the filter sidebar applied only the term: a drafted smart mode never reached the applied store, so the search silently ran as full text and the draft re-seeded from applied, visibly reverting the mode selection. The shortcut now behaves like Apply for the control values (searchMode, fieldFilters, directChildren, unreferenced) and respects the blocked gate on every surface; pql still applies only through the Apply button. Found and verified via Playwright gestures in the demo. Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…it fail state The warning Text rendered inline after the Compact row and drifted into the top bar's horizontal-scroll overflow — present in the DOM, invisible on screen (measured at x=1304 in a 1336px-wide modal). It now renders as a block line under the input. A blocked mode additionally shows a warning status on the input, and an attempted search escalates to an error status with the warning in danger color until the block is resolved. Verified via Playwright geometry and state assertions in the demo. Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- warning renders in the darker warn shade (colorWarningTextActive) with the warning-circle icon, matching the design frame - the search-modal top bars pass their selects into SearchTermFilter as prefixControls, so the warning line spans the row and left-aligns with the type select instead of the input column - the input carries no warning border at rest; an attempted search while blocked shows the error border and turns the warning red until resolved Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- trigger uses the shared IconTextButton with the resting border pinned to colorBorder, matching the search button on the other end of the input - the chevron toggles down/up with the dropdown open state and renders at 12px (sizing goes through icon.options — IconTextButton's separate iconOptions prop is dead and worth its own cleanup), vertically centered Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- smart-search-text / smart-search-visual replace the shared smart-search icon (generate-icons ride-alongs reverted) - a mode reporting available: false can never work on the surface (per the backend-computed targets, e.g. image search on data objects) and is now hidden instead of rendered disabled; blocked-but-fixable modes keep their entry, hint and warning Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Feature-specific icons ship with the bundle that registers the modes, via the runtime IconLibrary registration. Core keeps full-text-search for its built-in menu entry. Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Replaces the hand-drawn placeholders with the official SVG exports (full-text-search, smart-search-text, smart-search-visual; fills converted to currentColor), owned by the core library like every other bundle-consumed icon — the earlier bundle-side IconLibrary registration is reverted in backend-power-tools. Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ack) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Part of pimcore/product-management#1369 (Studio semantic-search UI). PR 1 of 3 — backend-power-tools-bundle registers its Smart search: Text / Image modes against this seam (follow-up PR); pimcore/backend-power-tools-bundle#753 adds the user permission.
What
SearchModeAbstract+SearchModeRegistry(based onDynamicTypeRegistryAbstract), bound asElement/Listing/SearchModeRegistry, SDK-exported fromsdk/modules/element— bundles register modes from their plugin modules, same attach pattern as the existing component/dynamic-type registries.SearchModeSelect: dropdown as a leftCompactsegment ofSearchTermFilter— mode menu with icons, per-mode availability, disabled entries with grey type/class hints, warning line under the input, purple collapsed label when a smart mode is active ("Full text"/"Default" for the built-in mode).searchModevalue (Clear-all resets to full text); thesearchTermdescriptor emits the active mode's column filter instead ofsystem.fulltext; registered mode filter types are stripped from restored base filters (a duplicate simple column filter of the same type is a BE 422).GeneralFiltersDecoratorConfig.elementType— enabled on the asset grid, data-object grid, and the search modal's Assets/Data Objects tabs. Listings without it, and installs with no registered modes, render today's plain search bar (zero visual change).full-text-search/smart-searchicons viagenerate-icons(the script's known ride-along rewrites of 5 unrelated icons were reverted). Icons are hand-drawn to match the library's stroke style — swap for the Figma exports if the design team has finals.True/Falsequoting issues, untouched).Verified
tsc --noEmitandeslintclean on all changed files. No unit tests per team practice; end-to-end verification happens with the BPT consumer PR in the demo env.🤖 Generated with Claude Code