fix: default drafts/published tab so the empty-state create button isn't hidden - #471
Merged
Merged
Conversation
…n 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.
This was referenced Sep 22, 2026
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
navigationTab(the drafts/published filter on the Datasets, UseCases, and Collaboratives dashboard pages) started asnullon first paint, becauseuseQueryState('tab', parseAsString)had no default. Each page's empty-state branch only renders the "Add New X" button whennavigationTab === 'drafts'— so for any account whose default-filtered list has zero items, the button (and the visually-selected tab) just didn't render on first load. AuseEffectalready tried to self-correct by callingsetNavigationTab('drafts')when null, but effects run after first paint, so it's a race: the URL-update + re-render round-trip usually wins on a fast connection, and loses under real load or a slower query.Root cause trail
Found while investigating CivicDataSpace-test#103 (
test_prv_006/007flaky under concurrent CI load). That specific case turned out to be a real, separately-fixed backend bug (DataSpaceBackend#199/PR#203) — but chasing the same symptom class turned uptest_prv_011_org_create_collaborativetiming out the same way, deterministically, every run, concurrent or not, for an account with zero existing collaboratives. Not flakiness — a real zero-item edge case nobody hit before because the usual test accounts have hundreds of existing records.dataset/andusecases/pages share the byte-identical pattern (confirmed by inspection), so any account whose draft-filtered list happens to be empty hits the same wall there too.Fix
useQueryState('tab', parseAsString.withDefault('drafts'))— same pattern already used incharts/page.tsxand the dataset access page.navigationTabis synchronously'drafts'on first render, no race. Removed the now-dead null-check in each page'suseEffect(state can no longer be null); kept the refetch-on-tab-change behavior.Verification
tsc --noEmit: clean on all three files (10 pre-existing errors elsewhere, incharts/components/ChartsImage.tsx, untouched by this change).eslint: clean on all three files.test_prv_002/003/011go green against a dev deploy of this branch.