Skip to content

feature: filter redesign (PIN-7358)#77

Open
alten-dturus wants to merge 20 commits intodevelopfrom
feature/PIN-7358_filters-redesign
Open

feature: filter redesign (PIN-7358)#77
alten-dturus wants to merge 20 commits intodevelopfrom
feature/PIN-7358_filters-redesign

Conversation

@alten-dturus
Copy link
Copy Markdown
Collaborator

@alten-dturus alten-dturus commented Dec 23, 2025

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:

  • Added submit mode through hasSubmitButton so filters can be applied in batch instead of immediately.
  • Added onSetActiveFilters to apply all current field values at once.
  • Refactored filter handler types to separate single-field actions from bulk apply.
  • Updated filter state utilities to make defaults/initialization consistent, including autocomplete-single handling.
  • Updated Filters and FiltersFields components to support:
  • submit/reset actions
  • responsive field widths
  • Updated active filter chips behavior/styling and reset button visibility logic.
  • Updated stories, tests, and snapshots to reflect the new API and UI behavior.

@borgesis95 borgesis95 marked this pull request as ready for review March 26, 2026 11:16
Copilot AI review requested due to automatic review settings March 26, 2026 11:16
@borgesis95 borgesis95 requested a review from Alepazz as a code owner March 26, 2026 11:16
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

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 hasSubmitButton mode to the Filters UI, including submit/cancel buttons and updated field interactions.
  • Refactored useFilters and 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

  • AutocompleteSingleFilterField passes value through as value as FilterOption, but at runtime this can be undefined (when fieldsValues doesn't contain the key) or null (default). MUI Autocomplete expects a stable controlled value (typically null for empty), so normalize here (e.g., value ?? null) and/or ensure the parent always provides a key in fieldsValues.
    <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

  • AutocompleteBaseFilterField spreads props directly into MUI's <Autocomplete />, but props now includes non-Autocomplete keys (label, hasSubmitButton, and the custom onInputChange). 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.

Comment thread src/features/filters/components/Filters.tsx
Comment thread src/features/filters/filters.utils.ts Outdated
Comment thread src/features/filters/components/FiltersFields.tsx
Comment on lines +61 to +63
const handleSubmit = () => {
onSetActiveFilters(fields, fieldsValues)
}
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

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

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.

Copilot uses AI. Check for mistakes.
Comment thread src/features/pagination/__tests__/Pagination.test.tsx Outdated
Comment thread src/features/filters/hooks/useFilters.ts Outdated
Comment on lines +22 to +25
const cancelFiltersLabel = getLocalizedValue({
it: 'Annulla filtri',
en: 'Cancel filters',
})
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

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

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.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator

@Alepazz Alepazz left a comment

Choose a reason for hiding this comment

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

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 hasSubmitButton is 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)
)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

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

@borgesis95

)
} else {
const defaultValues = getFiltersFieldsDefaultValue(fields, hasSubmitButton)
handleFieldsValuesChange(filterKey, defaultValues[filterKey])
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

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.

@Alepazz
Copy link
Copy Markdown
Collaborator

Alepazz commented Mar 31, 2026

Similar issue with onResetActiveFilters: it only deletes filter-related params but does not reset offset. When the user is on page 3, clicks "Annulla filtri", the filters are cleared but pagination stays on page 3 of the now-unfiltered dataset.
Adding searchParams.delete('offset') here too would fix it.
Attaching a screen recording.

Registrazione.schermo.2026-03-31.alle.11.51.37.mov

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants