Skip to content

[Translations] Fix: search & field filters in Translations sidebar don't trigger on Enter/search icon - #4012

Merged
ValeriaMaltseva merged 11 commits into
pimcore:2026.2from
albertmueller:fix/translations-sidebar-search-trigger
Sep 4, 2026
Merged

[Translations] Fix: search & field filters in Translations sidebar don't trigger on Enter/search icon#4012
ValeriaMaltseva merged 11 commits into
pimcore:2026.2from
albertmueller:fix/translations-sidebar-search-trigger

Conversation

@albertmueller

Copy link
Copy Markdown
Contributor

Summary

  • The top search field in the Translations "Search & Filter" sidebar only wrote the typed value into a draft store on change; clicking the search icon or pressing Enter (which antd's Input.Search reports via onSearch, not onChange) did nothing. Fixed by wiring onSearch to apply the term immediately.
  • Field filters (e.g. the "German" text column) used a plain Input with no search icon, only committing on blur into the draft store — the value was lost unless "Apply" was clicked afterwards. Fixed by switching to SearchInput, adding an optional onCommit callback threaded through
    DynamicFilterProvider → FieldFilters → the translations field-filter hook, so Enter/search-icon immediately applies the filter, and stretched the input to full sidebar width.

Changes

  • filters/filters.tsx: search term control now applies on onSearch, not just onChange.
  • components/dynamic-filter/provider/dynamic-filter-provider.tsx: added commit()/onCommit alongside the existing setData()/onChange.
  • components/field-filters/field-filters.tsx: added an onCommit prop, mirroring the existing onChange handling.
  • dynamic-type-field-filter-text-component.tsx: switched from Input to SearchInput, wired onSearch to commit(), set full width.
  • translations/filters/hooks/use-translations-field-filter-editor.ts: added onFilterCommit, which writes the committed field filter directly into both the draft and applied filter stores.
  • translations-sidebar/components/filter-tab/filter-tab.tsx: wired the new onCommit handler into FieldFilters.

Fixed state:
image

Fixes pimcore/platform-version#354
The issue was also reported as an enterprise issue: PEES-1392

albertmueller and others added 3 commits August 21, 2026 09:02
SearchTermControl only wired onChange, but antd's Input.Search fires
onSearch (not onChange) for the search icon click and the Enter key.
As a result, the search & filter sidebar required using the "Apply"
button, silently ignoring the search icon and Enter key.

Add an onSearch handler that applies the term immediately, mirroring
the working element listing's SearchTermFilter.
Text field filters (e.g. the "German" column) only wrote into the
sidebar's draft store on blur, so a value typed there was silently
dropped unless the user also clicked the separate "Apply" button.

Give the field-filter dynamic type a search input and thread an
optional onCommit callback through DynamicFilterProvider and
FieldFilters so a committed value (Enter or the search icon) is
written straight to the applied filter store, matching the existing
"Apply" button behavior. Also stretch the input to the full sidebar
width to match the main search field.
Copilot AI balanced review requested due to automatic review settings August 21, 2026 08:12

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Enables immediate submission of translation search and text field filters via Enter or the search icon.

Changes:

  • Adds commit handling across dynamic and field-filter components.
  • Uses SearchInput for text field filters.
  • Applies committed translation filters immediately.

Reviewed changes

Copilot reviewed 6 out of 7 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
filter-tab.tsx Connects field-filter commits.
use-translations-field-filter-editor.ts Synchronizes committed field filters.
filters.tsx Handles top-level search submission.
dynamic-type-field-filter-text-component.tsx Adds searchable text-filter input.
field-filters.tsx Propagates filter commits.
dynamic-filter-provider.tsx Adds commit support to filter context.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread assets/js/src/core/modules/translations/filters/filters.tsx
Committing the search term or a field filter only wrote that single
key into the applied filter store, so any other still-unsaved draft
change (e.g. a field filter typed but not yet applied) was silently
dropped instead of being applied together, unlike clicking "Apply"
which applies the entire draft snapshot at once.

Apply the full current draft values on commit, overriding just the
field being committed to avoid reading a stale React state value for
it.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 7 changed files in this pull request and generated no new comments.

Suppressed comments (1)

assets/js/src/core/modules/element/dynamic-types/definitions/field-filters/components/dynamic-type-field-filter-text-component.tsx:32

  • Use the searchValue supplied by SearchInput here. The clear control invokes onSearch with an empty value in the same event as onChange, before _value has re-rendered, so this closure can recommit the previous text and leave the filter applied instead of clearing it.
      onSearch={ () => { commit(_value) } }

…state

The field filter's SearchInput read the committed value from local
component state (_value) rather than the value onSearch itself
received. Clicking the clear (x) icon fires onChange('') and
onSearch('') in the same event before the state update from onChange
has re-rendered, so the stale closure could recommit the previous
text and leave the filter applied instead of clearing it.

Commit the value passed into onSearch directly to avoid the race.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 7 changed files in this pull request and generated no new comments.

Suppressed comments (2)

assets/js/src/core/components/field-filters/field-filters.tsx:67

  • This newly added direct undefined comparison bypasses the project's type-safe check convention. Invoke the optional callback directly (or use isUndefined) so this branch follows the required nullability pattern.
    if (onCommit !== undefined) {
      onCommit(updatedData)
    }

assets/js/src/core/components/dynamic-filter/provider/dynamic-filter-provider.tsx:65

  • This newly added direct undefined comparison bypasses the project's type-safe check convention. Invoke the optional callback directly (or use isUndefined) so this branch follows the required nullability pattern.
    if (onCommit !== undefined) {
      onCommit(data)
    }

@ValeriaMaltseva
ValeriaMaltseva self-requested a review August 24, 2026 10:37
@ValeriaMaltseva ValeriaMaltseva self-assigned this Aug 25, 2026
…d onCommit

FieldFilters has six hosts (element listing, notes & events, notifications,
recycle bin, reports, translations) and all of them collect draft values
behind their own "Apply" button. Switching the shared text field filter to
SearchInput gave all six a search icon and Enter handling, but only
translations wires onCommit -- in the other five commit() falls through to
onChange, i.e. a draft write, so the new control looked actionable while
doing no more than blur already did.

Make commit() optional and build it only when the host passed onCommit;
FieldFilters forwards onCommit only when it has one. The text filter renders
SearchInput when commit is available and the previous plain Input otherwise,
so the five draft-only hosts keep their markup unchanged and each opts in
later by passing onCommit.

This also drops an accidental BC break: commit was a required member of the
SDK-exported DynamicFilterData, which breaks external code constructing that
object.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Commit currently emits duplicate change callbacks, and the new reusable component behavior lacks its required Storybook coverage.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details
  • Files reviewed: 6/7 changed files
  • Comments generated: 2
  • Review effort level: Balanced

Comment thread assets/js/src/core/components/field-filters/field-filters.tsx
Comment thread assets/js/src/core/components/field-filters/field-filters.tsx
ValeriaMaltseva and others added 3 commits September 4, 2026 11:46
The search-input treatment did not fit a field filter row: a magnifier addon
and a clear icon on every text filter read as a second, competing search box
next to the sidebar's own search field.

Drop SearchInput and keep the antd Input the component always used, wiring
onPressEnter instead. Enter applies immediately where the host exposes
commit() and otherwise behaves like leaving the field, so the rendered markup
is now unchanged in every host and no styling or e2e selector shifts.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
DynamicFilterProvider.commit called onChange and then onCommit, and the
onCommit consumer in FieldFilters calls setData itself, which fires onChange
again. A single commit therefore delivered the same value to the host's
onChange twice before onCommit, doubling the state updates and breaking the
one-callback-per-interaction expectation.

Drop the onChange call from commit(); FieldFilters.onFilterCommit already
reports the change through setData before invoking onCommit. Hosts without an
onCommit handler never reach commit(), so their onChange path is untouched.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…pers

The classification-store id-plus-config comparison was written out four
times: three findIndex lookups (change, commit, language selection) and once
more inverted inside onRemoveClick. onFilterCommit in particular was a
character-for-character copy of onFilterChange.

Pull the comparison into isSameFilter() and the array patch into
withUpdatedFilter(), and express all four handlers through them. Behaviour is
unchanged: the same entry is matched and the same object spread applied.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@sonarqubecloud

sonarqubecloud Bot commented Sep 4, 2026

Copy link
Copy Markdown

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Field filters still use a plain input without the required clickable search icon or full-width search control.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details
  • Files reviewed: 6/7 changed files
  • Comments generated: 1
  • Review effort level: Balanced

@ValeriaMaltseva ValeriaMaltseva added this to the 2026.2.9 milestone Sep 4, 2026

@ValeriaMaltseva ValeriaMaltseva left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@albertmueller

Thanks a lot for the report and the fix. I also pushed commits to your branch to change one thing: the search control inside the field filter rows.

Why. DynamicTypeFieldFilterTextComponent is not specific to Translations - it powers the text field filter in six sidebars. Switching it to SearchInput added a magnifier icon and a clear button to all six. There were two issues with that:

  1. Only Translations wires onCommit. In the other five cases, commit() falls back to onChange, which simply writes the draft value. As a result, the button looked actionable while doing no more than leaving the field already did. A control that promises an action it cannot actually perform is worse than no control.
  2. Visually it reads as a second search box competing with the sidebar's own search field right above it, once per filter row. It doesn't match how the rest of the filter rows look.

What it does now. The component keeps the plain antd Input it always used and reacts to onPressEnter instead: Enter applies immediately where the host exposes commit(), and behaves like leaving the field where it doesn't. The rendered markup is therefore unchanged in every host - no styling or selector shifts - and any sidebar can opt into immediate-apply later by passing onCommit.

One consequence worth stating plainly: the "search icon and full sidebar width" part of #354's expected behaviour is intentionally not implemented. Enter and the top search field cover the functional half; the per-row icon we're deliberately leaving out.

I hope this explains the reasoning behind the changes.

I will merge the PR soon.

@ValeriaMaltseva
ValeriaMaltseva merged commit dcd5681 into pimcore:2026.2 Sep 4, 2026
20 of 21 checks passed
@github-actions github-actions Bot locked and limited conversation to collaborators Sep 4, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants