From 2a432a9437271c476de6ea8c4c1fd80c83732e32 Mon Sep 17 00:00:00 2001 From: Saqib Date: Mon, 21 Sep 2026 19:42:54 +0530 Subject: [PATCH] fix: default the drafts/published tab so the empty-state create button isn't hidden navigationTab was 'null' on first paint (useQueryState with no default), so the empty-state branch's 'navigationTab === '\''drafts'\''' check failed on the very first render whenever the current filter had zero items -- the Add New button (and the visual tab selection) just didn't render. A useEffect already tried to self-correct by calling setNavigationTab('drafts') when null, but that runs after first paint, so it only closed the gap once the URL update + re-render round-tripped -- a race that mostly won on a fast/idle connection and mostly lost under real load or a slow list query. Root-caused via CivicDataSpace-test#103: test_prv_011_org_create_collaborative timed out waiting for a button that was never there for an account with zero existing collaboratives, on every run, concurrent or not -- not flakiness, a deterministic zero-item edge case. dataset/ and usecases/ pages share the identical pattern (confirmed by inspection) and would hit the same bug for any account whose default-filtered list is empty. Fix: useQueryState('tab', parseAsString.withDefault('drafts')), the same pattern already used in charts/page.tsx and the access page -- navigationTab is now synchronously 'drafts' on first render, no round-trip needed. Removed the now-dead null-check in each page's useEffect (the state can no longer be null) but kept the refetch-on-tab-change behavior. Verified: tsc --noEmit and eslint clean on all three files, zero new errors (10 pre-existing errors elsewhere, in charts/components/ChartsImage.tsx, untouched by this change). Not verified against a live running instance -- that needs local Keycloak/NextAuth setup out of scope for this change; next step is confirming test_prv_011/002/003 actually go green against a dev deploy of this. --- .../[entityType]/[entitySlug]/collaboratives/page.tsx | 9 +++++---- .../dashboard/[entityType]/[entitySlug]/dataset/page.tsx | 9 +++++---- .../[entityType]/[entitySlug]/usecases/page.tsx | 9 +++++---- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/app/[locale]/dashboard/[entityType]/[entitySlug]/collaboratives/page.tsx b/app/[locale]/dashboard/[entityType]/[entitySlug]/collaboratives/page.tsx index 2c9bab54..ca1aa781 100644 --- a/app/[locale]/dashboard/[entityType]/[entitySlug]/collaboratives/page.tsx +++ b/app/[locale]/dashboard/[entityType]/[entitySlug]/collaboratives/page.tsx @@ -89,7 +89,10 @@ export default function CollaborativePage() { ? { [entityType]: entitySlug } : null; - const [navigationTab, setNavigationTab] = useQueryState('tab', parseAsString); + const [navigationTab, setNavigationTab] = useQueryState( + 'tab', + parseAsString.withDefault('drafts') + ); const AllCollaboratives = useQuery( @@ -110,12 +113,10 @@ export default function CollaborativePage() { ); useEffect(() => { - if (navigationTab === null || navigationTab === undefined) - setNavigationTab('drafts'); if (isValidParams) { AllCollaboratives.refetch(); } - }, [navigationTab, isValidParams, AllCollaboratives, setNavigationTab]); + }, [navigationTab, isValidParams, AllCollaboratives]); const COLLAB_LIST_TOAST_ID = 'collaboratives-list-toast'; diff --git a/app/[locale]/dashboard/[entityType]/[entitySlug]/dataset/page.tsx b/app/[locale]/dashboard/[entityType]/[entitySlug]/dataset/page.tsx index f80a4dd6..21c90f70 100644 --- a/app/[locale]/dashboard/[entityType]/[entitySlug]/dataset/page.tsx +++ b/app/[locale]/dashboard/[entityType]/[entitySlug]/dataset/page.tsx @@ -87,7 +87,10 @@ export default function DatasetPage() { ? { [entityType]: entitySlug } : null; - const [navigationTab, setNavigationTab] = useQueryState('tab', parseAsString); + const [navigationTab, setNavigationTab] = useQueryState( + 'tab', + parseAsString.withDefault('drafts') + ); const [isTypeModalOpen, setIsTypeModalOpen] = useState(false); const AllDatasetsQuery = useQuery( @@ -111,12 +114,10 @@ export default function DatasetPage() { ); useEffect(() => { - if (navigationTab === null || navigationTab === undefined) - setNavigationTab('drafts'); if (isValidParams) { AllDatasetsQuery.refetch(); } - }, [navigationTab, isValidParams, AllDatasetsQuery, setNavigationTab]); + }, [navigationTab, isValidParams, AllDatasetsQuery]); const DeleteDatasetMutation = useMutation( [`delete_dataset`], diff --git a/app/[locale]/dashboard/[entityType]/[entitySlug]/usecases/page.tsx b/app/[locale]/dashboard/[entityType]/[entitySlug]/usecases/page.tsx index 5a5285c0..548b9ec5 100644 --- a/app/[locale]/dashboard/[entityType]/[entitySlug]/usecases/page.tsx +++ b/app/[locale]/dashboard/[entityType]/[entitySlug]/usecases/page.tsx @@ -86,7 +86,10 @@ export default function DatasetPage() { ? { [entityType]: entitySlug } : null; - const [navigationTab, setNavigationTab] = useQueryState('tab', parseAsString); + const [navigationTab, setNavigationTab] = useQueryState( + 'tab', + parseAsString.withDefault('drafts') + ); const AllUseCases = useQuery( [`fetch_UseCases`, entityType, entitySlug, navigationTab ?? 'drafts'], @@ -105,12 +108,10 @@ export default function DatasetPage() { ); useEffect(() => { - if (navigationTab === null || navigationTab === undefined) - setNavigationTab('drafts'); if (isValidParams) { AllUseCases.refetch(); } - }, [navigationTab, isValidParams, setNavigationTab, AllUseCases]); + }, [navigationTab, isValidParams, AllUseCases]); const DeleteUseCaseMutation = useMutation( [`delete_Usecase`],