fix(ui): re-integrate signalFilterChange into useUrlFilters and always reset page on filter change (#10028)

This commit is contained in:
Alejandro Bailo
2026-02-11 20:06:26 +01:00
committed by GitHub
parent bcd7b2d723
commit 02f3e77eaf
3 changed files with 16 additions and 21 deletions

View File

@@ -19,7 +19,7 @@ All notable changes to the **Prowler UI** are documented in this file.
- Filter navigations not coordinating with Suspense boundaries due to missing startTransition in ProviderTypeSelector, AccountsSelector, and muted findings checkbox [(#10013)](https://github.com/prowler-cloud/prowler/pull/10013)
- Scans page pagination not updating table data because ScansTableWithPolling kept stale state from initial mount [(#10013)](https://github.com/prowler-cloud/prowler/pull/10013)
- Duplicate `filter[search]` parameter in findings and scans API calls [(#10013)](https://github.com/prowler-cloud/prowler/pull/10013)
- All filters on `/findings` silently reverting on first click in production [(#10025)](https://github.com/prowler-cloud/prowler/pull/10025)
- All filters on `/findings` silently reverting on first click in production [(#10028)](https://github.com/prowler-cloud/prowler/pull/10028)
---

View File

@@ -43,12 +43,8 @@ interface FilterTransitionProviderProps {
/**
* Provides a shared pending state for filter changes.
*
* Filter components signal the start of navigation via signalFilterChange(),
* and use their own local useTransition() for the actual router.push().
* This avoids a known Next.js production bug where a shared useTransition()
* wrapping router.push() causes the navigation to be silently reverted.
*
* The pending state auto-resets when searchParams change (navigation completed).
* Filter navigation calls signalFilterChange() before router.push().
* The pending state auto-resets when searchParams change.
*/
export const FilterTransitionProvider = ({
children,

View File

@@ -2,6 +2,8 @@
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { useFilterTransitionOptional } from "@/contexts";
/**
* Custom hook to handle URL filters and automatically reset
* pagination when filters change.
@@ -13,11 +15,14 @@ export const useUrlFilters = () => {
const router = useRouter();
const searchParams = useSearchParams();
const pathname = usePathname();
const isPending = false;
const filterTransition = useFilterTransitionOptional();
const navigate = (params: URLSearchParams) => {
const queryString = params.toString();
if (queryString === searchParams.toString()) return;
const targetUrl = queryString ? `${pathname}?${queryString}` : pathname;
filterTransition?.signalFilterChange();
router.push(targetUrl, { scroll: false });
};
@@ -38,10 +43,9 @@ export const useUrlFilters = () => {
// If effective value is unchanged, do nothing (avoids redundant fetches)
if (currentValue === nextValue) return;
// Only reset page to 1 if page parameter already exists
if (params.has("page")) {
params.set("page", "1");
}
// Always reset to first page when filters change.
// This also guarantees a query-string change on page 1 (no existing page param).
params.set("page", "1");
if (nextValue === null) {
params.delete(filterKey);
@@ -58,10 +62,8 @@ export const useUrlFilters = () => {
params.delete(filterKey);
// Only reset page to 1 if page parameter already exists
if (params.has("page")) {
params.set("page", "1");
}
// Always reset to first page when filters change.
params.set("page", "1");
navigate(params);
};
@@ -96,10 +98,8 @@ export const useUrlFilters = () => {
const params = new URLSearchParams(searchParams.toString());
modifier(params);
// Only reset page to 1 if page parameter already exists
if (params.has("page")) {
params.set("page", "1");
}
// Always reset to first page when filters change.
params.set("page", "1");
navigate(params);
};
@@ -109,7 +109,6 @@ export const useUrlFilters = () => {
clearFilter,
clearAllFilters,
hasFilters,
isPending,
navigateWithParams,
};
};