Skip to content

Comments

refactor: monitor fields filters [ENG-2450]#7411

Open
speaker-ender wants to merge 9 commits intomainfrom
refactor/monitor-fields-filters
Open

refactor: monitor fields filters [ENG-2450]#7411
speaker-ender wants to merge 9 commits intomainfrom
refactor/monitor-fields-filters

Conversation

@speaker-ender
Copy link
Contributor

@speaker-ender speaker-ender commented Feb 18, 2026

Ticket ENG-2450

Description Of Changes

Refactoring the search filters on the monitor fields screen to be dropdowns instead of using the tree filter component

Code Changes

  • Improved the useSearchForm hook to have better types
  • Added a new search filter component for the monitor fields screen

Steps to Confirm

  1. Visit the Action Center screen
  2. Confirm that all of the filters function as expected and update the url
  3. Click on an available Datastore monitor type
  4. Confirm that the filters are now matching the new select/filter bar style
  5. Verify that there are no regressions in the filtering functionality (updating results, updating url, refreshing available filters)

Pre-Merge Checklist

  • Issue requirements met
  • All CI pipelines succeeded
  • CHANGELOG.md updated
    • Add a db-migration This indicates that a change includes a database migration label to the entry if your change includes a DB migration
    • Add a high-risk This issue suggests changes that have a high-probability of breaking existing code label to the entry if your change includes a high-risk change (i.e. potential for performance impact or unexpected regression) that should be flagged
    • Updates unreleased work already in Changelog, no new entry necessary
  • UX feedback:
    • All UX related changes have been reviewed by a designer
    • No UX review needed
  • Followup issues:
    • Followup issues created
    • No followup issues
  • Database migrations:
    • Ensure that your downrev is up to date with the latest revision on main
    • Ensure that your downgrade() migration is correct and works
      • If a downgrade migration is not possible for this change, please call this out in the PR description!
    • No migrations
  • Documentation:
    • Documentation complete, PR opened in fidesdocs
    • Documentation issue created in fidesdocs
    • If there are any new client scopes created as part of the pull request, remember to update public-facing documentation that references our scope registry
    • No documentation updates required

@vercel
Copy link
Contributor

vercel bot commented Feb 18, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
fides-plus-nightly Ready Ready Preview, Comment Feb 20, 2026 3:15pm
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
fides-privacy-center Ignored Ignored Feb 20, 2026 3:15pm

Request Review

Comment on lines +38 to +43
export type MonitorFieldSearchForm =
v.InferOutput<typeof MonitorFieldSearchFormQuerySchema> extends Values<
typeof MonitorFieldSearchFormQueryState
>
? v.InferOutput<typeof MonitorFieldSearchFormQuerySchema>
: never;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Temporary method of handling schema type checking between nuqs and valibot.
Future type handling should also bind valibot to ant forms for better interop.

Copy link
Contributor

Choose a reason for hiding this comment

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

consider adding this explanation as a comment in the code

form.submit();

const onFinish: FormProps<FormType>["onFinish"] = (values) => {
const { success, output } = safeParse(schema, values);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Better than what we had previously.
Ideally the parse success/fail handling should match ant.
This can be done by either injecting/overriding ant's validator (preferred) or by syncing ant's settings with valibot.

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 18, 2026

Greptile Summary

This PR refactors the monitor fields screen filters from a tree-based Filter component to dropdown Select components, introducing valibot for schema validation alongside the existing nuqs URL state management. The useSearchForm hook is updated to support valibot schemas and a form submission flow (onFieldsChangeform.submit()onFinish with validation). The old MonitorFieldFilters (406 lines) and useMonitorFieldsFilters hook are replaced by the new MonitorFieldsSearchForm component and MonitorFieldSearchForm.util.ts.

  • Adds valibot as a new dependency and bumps nuqs from ^2.4.3 to ^2.8.8
  • Adds "Datastore Filters" RTK Query cache tag with proper invalidation across multiple mutation endpoints
  • Removes trailing ellipsis from status labels (e.g., "Classifying...""Classifying") for cleaner dropdown display
  • The useFilters.ts file is no longer imported anywhere but was not deleted — it should be cleaned up
  • The data-testid="monitor-type-filter" on the status dropdown appears to be a copy-paste error from MonitorListSearchForm
  • requestData from useSearchForm is destructured but unused in page.tsx, while filter values are read imperatively via form.getFieldValue() — consider using the reactive requestData instead

Confidence Score: 3/5

  • Generally safe refactor with minor issues that should be addressed before merge.
  • The core refactoring logic is sound — replacing the tree filter with dropdowns and adding valibot validation. However, there are a few issues: a misleading data-testid that could break or confuse tests, redundant filtering logic, an orphaned useFilters.ts file, and the use of imperative form reads instead of reactive state for query parameters. None of these are showstoppers, but they represent code quality concerns worth addressing.
  • Pay close attention to fields/page.tsx (imperative form reads for query construction) and MonitorFieldsSearchForm.tsx (incorrect data-testid, redundant filter logic).

Important Files Changed

Filename Overview
clients/admin-ui/src/features/data-discovery-and-detection/action-center/hooks/useSearchForm.ts Refactored to use valibot schema validation and form submission pattern instead of inline value translation. Minor typo in comment.
clients/admin-ui/src/features/data-discovery-and-detection/action-center/forms/MonitorFieldsSearchForm.tsx New search form component with dropdown filters. Has redundant filter logic in data category options builder and a copy-pasted data-testid that misidentifies the element.
clients/admin-ui/src/features/data-discovery-and-detection/action-center/forms/MonitorFieldSearchForm.util.ts New utility defining valibot schema, nuqs query state, and type for the monitor field search form. Clean separation of concerns.
clients/admin-ui/src/features/data-discovery-and-detection/action-center/fields/page.tsx Replaced old filter component and search with new form-based approach. Uses imperative form.getFieldValue() instead of reactive state for query construction; requestData is unused.
clients/admin-ui/src/features/data-discovery-and-detection/action-center/fields/MonitorFields.const.ts Removed trailing ellipsis from status labels (e.g., "Classifying..." → "Classifying"). Consistent update across all mappings.
clients/admin-ui/src/features/data-discovery-and-detection/action-center/MonitorList.const.ts Added valibot schema and type for the monitor search form. Changed search default from empty string to parseAsString (nullable).
clients/admin-ui/src/features/data-discovery-and-detection/action-center/MonitorList.tsx Updated to use new schema-based useSearchForm pattern and onFinish-based pagination reset.
clients/admin-ui/src/features/data-discovery-and-detection/discovery-detection.slice.ts Added "Datastore Filters" invalidation tag to multiple mutation endpoints for automatic filter refresh.

Last reviewed commit: ac052af

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

15 files reviewed, 4 comments

Edit Code Review Agent Settings | Greptile

};

// Unfortunate need for effect due to current routing strategy
// Unfortunate need for effect due to current routin strategy
Copy link
Contributor

Choose a reason for hiding this comment

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

Typo: "routin" → "routing"

Suggested change
// Unfortunate need for effect due to current routin strategy
// Unfortunate need for effect due to current routing strategy

Comment on lines 99 to 112
const baseMonitorFilters = {
path: {
monitor_config_id: monitorId,
},
query: {
staged_resource_urn: selectedNodeKeys.map((key) => key.toString()),
search: search.searchProps.value,
diff_status: resourceStatus
? resourceStatus.flatMap(intoDiffStatus)
: undefined,
confidence_bucket: confidenceBucket || undefined,
data_category: dataCategory || undefined,
search: form.getFieldValue("search"),
diff_status:
form.getFieldValue("resource_status")?.flatMap(intoDiffStatus) ||
undefined,
confidence_bucket: form.getFieldValue("confidence_bucket") || undefined,
data_category: form.getFieldValue("data_category") || undefined,
},
};
Copy link
Contributor

Choose a reason for hiding this comment

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

form.getFieldValue is not reactive

baseMonitorFilters reads filter values via form.getFieldValue(), which is an imperative read of Ant Design's form store. Unlike the previous implementation which used reactive state from useMonitorFieldsFilters, these calls only return the value at render time and don't subscribe to changes. The object will only update when something else triggers a re-render (e.g., nuqs state update propagating back).

Since useSearchForm already returns requestData (which is derived from the reactive nuqs searchForm state), consider using requestData here instead of form.getFieldValue() to ensure filter values are always in sync with the URL state. Currently requestData is destructured on line 84 but never used.

Copy link
Contributor

@gilluminate gilluminate left a comment

Choose a reason for hiding this comment

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

Greptile's feedback seems legit, and I agree with those. Three nitpicks of my own to add to that.

Comment on lines +38 to +43
export type MonitorFieldSearchForm =
v.InferOutput<typeof MonitorFieldSearchFormQuerySchema> extends Values<
typeof MonitorFieldSearchFormQueryState
>
? v.InferOutput<typeof MonitorFieldSearchFormQuerySchema>
: never;
Copy link
Contributor

Choose a reason for hiding this comment

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

consider adding this explanation as a comment in the code

wip: ehhhh

wip: finally something somewhat better

chore: clean ups

fix: minor styles

fix: last of the issues

chore: update changelog

fix: autofocus

fix: filter data categories

lint and format

fix: datastore filter refresh
path: { monitor_config_id: monitorId },
query: {
confidence_bucket: query.confidence_bucket ?? undefined,
data_category: query.confidence_bucket ?? undefined,
Copy link
Contributor

Choose a reason for hiding this comment

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

copy/paste error?

Suggested change
data_category: query.confidence_bucket ?? undefined,
data_category: query.data_category ?? undefined,

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.

2 participants