Conversation
…eld adding hasSubmitButton prop
…eld adding hasSubmitButton prop
There was a problem hiding this comment.
Pull request overview
This PR implements the “filter redesign” by introducing an optional submit-based filtering flow (hasSubmitButton) and refactoring the filters hook/types/components to support both “instant apply” and “apply on submit” behaviors.
Changes:
- Added
hasSubmitButtonmode to the Filters UI, including submit/cancel buttons and updated field interactions. - Refactored
useFiltersand types to distinguish single-filter updates (FilterHandler) vs bulk apply (onSetActiveFilters). - Updated filter field components/layout (grid widths, chips behavior, autocomplete label behavior) and adjusted snapshots/tests accordingly.
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| src/features/pagination/tests/Pagination.test.tsx | Minor test cleanup (adds spacing; leaves commented debug). |
| src/features/filters/stories/FiltersExample.tsx | Updates the Filters story labels/options and enables hasSubmitButton. |
| src/features/filters/hooks/useFilters.ts | Refactors URL param updates; adds onSetActiveFilters bulk apply handler. |
| src/features/filters/filters.utils.ts | Adds hasSubmitButton-aware defaults/initialization for filter field values. |
| src/features/filters/filters.types.ts | Splits handler types and adds field width + submit-mode support. |
| src/features/filters/components/NumericFilterField.tsx | Disables instant-apply affordances when hasSubmitButton is enabled. |
| src/features/filters/components/FreetextFilterField.tsx | Disables instant-apply affordances when hasSubmitButton is enabled. |
| src/features/filters/components/FiltersFields.tsx | Adds submit/cancel buttons and responsive grid sizing. |
| src/features/filters/components/Filters.tsx | Wires submit flow (onSetActiveFilters) and propagates hasSubmitButton. |
| src/features/filters/components/DatepickerFilterField.tsx | Disables instant-apply affordances when hasSubmitButton is enabled. |
| src/features/filters/components/AutocompleteSingleFilterField.tsx | Updates single autocomplete to support submit-mode state handling. |
| src/features/filters/components/AutocompleteMultipleFilterField.tsx | Skips debounce/apply when hasSubmitButton is enabled. |
| src/features/filters/components/AutocompleteBaseFilterField.tsx | Updates label/aria behavior for selected-count display in submit mode. |
| src/features/filters/components/ActiveFiltersChips.tsx | Adjusts chip keys/styles and reset button visibility for submit mode. |
| src/features/filters/tests/snapshots/Filters.test.tsx.snap | Snapshot updates for layout/button structure changes. |
| src/features/filters/tests/Filters.test.tsx | Updates tests to pass the new required onSetActiveFilters prop. |
Comments suppressed due to low confidence (2)
src/features/filters/components/AutocompleteSingleFilterField.tsx:33
AutocompleteSingleFilterFieldpassesvaluethrough asvalue as FilterOption, but at runtime this can beundefined(whenfieldsValuesdoesn't contain the key) ornull(default). MUI Autocomplete expects a stable controlled value (typicallynullfor empty), so normalize here (e.g.,value ?? null) and/or ensure the parent always provides a key infieldsValues.
<AutocompleteBaseFilterField<false>
label={field.label}
blurOnSelect
value={value as FilterOption}
options={field.options}
onInputChange={field?.onTextInputChange}
onChange={(_, data) => {
handleAutocompleteSingleChange(data)
src/features/filters/components/AutocompleteBaseFilterField.tsx:56
AutocompleteBaseFilterFieldspreadspropsdirectly into MUI's<Autocomplete />, butpropsnow includes non-Autocomplete keys (label,hasSubmitButton, and the customonInputChange). These will be forwarded to the underlying DOM and can trigger React warnings / invalid DOM attributes. Destructure custom props out before spreading the rest into<Autocomplete />.
return (
<Autocomplete<FilterOption, Multiple, true, false>
{...props}
onInputChange={(_, value) => props?.onInputChange?.(value)}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const handleSubmit = () => { | ||
| onSetActiveFilters(fields, fieldsValues) | ||
| } |
There was a problem hiding this comment.
The new submit-button flow (hasSubmitButton / onSetActiveFilters) introduces a different interaction model (filters applied only on submit, buttons enabled/disabled, autocomplete-single now stored in state). There are no tests covering this path (e.g., that onChangeActiveFilter is not called on typing/selecting when hasSubmitButton is true, and that onSetActiveFilters is called with the correct values on submit, including clearing filters). Add targeted tests for hasSubmitButton behavior to prevent regressions.
| const cancelFiltersLabel = getLocalizedValue({ | ||
| it: 'Annulla filtri', | ||
| en: 'Cancel filters', | ||
| }) |
There was a problem hiding this comment.
cancelFiltersLabel is computed at module load time via getLocalizedValue(), which reads document.documentElement.lang. If the app language can change at runtime, this label will not update. Compute the localized label inside the component render (as done elsewhere) so it reflects the current language.
Alepazz
left a comment
There was a problem hiding this comment.
The PR is missing the description template (Issue link, Description, List of changes, How to test).
I agree with Copilot's findings, especially the one about onSetActiveFilters not deleting offset when filters are cleared via submit (point 2 in Copilot's review) — this can leave pagination on a stale page.
The hasSubmitButton flow is the main feature of this PR but has no dedicated test coverage. There should be tests verifying that:
- filters are not applied immediately when
hasSubmitButtonis true - clicking "Filtra" applies all filters at once
- clicking "Annulla filtri" resets correctly
|
|
||
| const buttonDisabled = Object.entries(fieldsValues).every( | ||
| ([_, value]) => value === null || value === '' || (Array.isArray(value) && value.length === 0) | ||
| ) |
There was a problem hiding this comment.
buttonDisabled disables both "Filtra" and "Annulla filtri" when all fields are empty. But if there are active filters (chips visible) and the user clears the inputs to reset them, they can't click "Filtra" to apply the reset. Consider factoring in whether there are active filters — e.g. the buttons should remain enabled if there are active filter chips, even when the input fields are empty.
There was a problem hiding this comment.
I tested the hasSubmitButton flow and was able to reproduce the buttonDisabled issue I mentioned before. When a filter is active (chip visible) and the user clears the input field, both "Filtra" and "Annulla filtri" become disabled. Even though there is a difference between the current input state (empty) and the applied filters (chip still active). The user cannot click "Filtra" to apply the reset, and is forced to use the chip's X button instead. I think that this can be a UX problem (even "Annulla filtri" cannot be clicked, but there is an active filter).
Attaching a screen recording showing the issue.
Registrazione.schermo.2026-03-31.alle.11.38.06.mov
| ) | ||
| } else { | ||
| const defaultValues = getFiltersFieldsDefaultValue(fields, hasSubmitButton) | ||
| handleFieldsValuesChange(filterKey, defaultValues[filterKey]) |
There was a problem hiding this comment.
In the else branch, defaultValues[filterKey] can be undefined when hasSubmitButton is false and the field type is autocomplete-single, because getFiltersFieldsDefaultValue skips that key. This would set the field value to undefined, potentially causing controlled/uncontrolled warnings.
|
Similar issue with Registrazione.schermo.2026-03-31.alle.11.51.37.mov |
Issue
PIN-7358
Description/Context
This PR introduces the filter redesign by adding an optional submit-based filtering mode in the Filters feature.
Main updates:
hasSubmitButtonso filters can be applied in batch instead of immediately.onSetActiveFiltersto apply all current field values at once.