fix(trustlab): list loading progress + restore filter controls from URL#1494
Conversation
Adds useListData (keepPreviousData, no auto focus/reconnect revalidation, isBusy only for new-key fetches) and a shared buildQueryString; the four list hooks adopt it and drop their duplicated fetcher/buildQueryString.
… from URL Filters is now controlled by the parent's URL-synced params: a thin LinearProgress shows while fetching a new query (keepPreviousData holds results in place), and the dropdowns/chips, sort, and search restore from bookmarked URLs. Fixes the unfiltered-flash, the tab-focus/first-load flicker, and filters being dropped on first interaction.
|
@codex review |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
@claude review |
|
Claude finished @kilemensi's task in 3m 23s —— View job Code Review
Overall this is well-structured work. The
|
| Severity | Issue |
|---|---|
| Medium | ReportsList param init doesn't match OpportunitiesList — filter controls flash empty on bookmarked URLs |
| Low | useToolkits dead code in second return branch |
| Low | Stale "controls not restored" comment in PlaybooksList/ToolkitList |
| Low | hasFilters dead prop passed to Filters |
| Low | [router.isReady] effects lack eslint-disable comments |
| Nit | generateYearOptions calls new Date() on every render |
The core architecture — useListData, isBusy narrowed to key-change fetches, keepPreviousData, controlled Filters — is solid. The medium item about ReportsList lazy init is the one I'd flag before merging, the rest can be addressed in a follow-up.
Match OpportunitiesList: initialise params from router.query in the useState initialiser so client-side navigation to a filtered URL renders the filter bar with its selections (no one-render gap). The router.isReady effect still handles hard loads, where SSR query is empty until ready.
Year/month dropdown options are static; compute them once at module load instead of in the processedFilters memo, avoiding a new Date() call whenever the filters config changes.
|
On:
@claude review |
|
Claude finished @kilemensi's task in 2m 50s —— View job Code Review (follow-up)
Responses to your clarifications, one by one: 1.
|
| # | Status | Finding |
|---|---|---|
| 1 | ✓ Accepted your correction | ReportsList lazy init is correct; flash claim was wrong |
| 2 | Still flagged (low) | useToolkits second return has unreachable initialToolkits branch |
| 3 | Partially accepted (nit) | Comment text "not restored — out of scope" is stale regardless of filter UI scope |
| 4 | ✓ Accepted | No eslint-disable needed |
| 5 | ✓ Fixed | YEAR_OPTIONS IIFE |
Nothing blocking. The core of the PR (useListData, keepPreviousData, controlled Filters) is solid.
|
On:
@claude review |
|
Claude finished @kilemensi's task in 51s —— View job Code Review (follow-up 2)
On stale comments — your correction is correctYou're right. Both // PlaybooksList.js:107
{hasFilters ? (
<Section>
<Filters selectedValues={params} ... />
</Section>
) : null}
// ToolkitList.js:104
{hasFilters && (
<Section>
<Filters selectedValues={params} ... />
</Section>
)}When Summary (all threads closed)
The only remaining open item is the low-severity dead code in |
Description
What & why
Follow-up to the list-filter fixes (#1493). Improves the UX of the filterable list views — opportunities, reports, toolkits, playbooks — and centralises their data-fetching.
Three problems addressed:
?year=…&sort=…&search=…filtered the results but the dropdowns/chips/sort/search showed nothing, and changing one filter dropped the others.Changes
refactor: centralise list data-fetching in a useListData hookuseListData(insrc/hooks/): one place for the SWR policy —keepPreviousData, no focus/reconnect revalidation, andisBusythat fires only for new-key (user-driven) fetches, not mount/background revalidation (so progress never shows on first load while ISR freshness still revalidates silently).buildQueryStringmoved intoqueryParams; the four list hooks adoptuseListDataand drop their duplicatedfetcher/buildQueryString.fix: show list loading progress and restore filter controls from URLLinearProgressin the sharedFiltersbar shows while a new query is fetching;keepPreviousDataholds the current results in place (no flash).Filtersis now controlled by the parent's URL-syncedparams: filter dropdowns/chips, sort, and search all restore from a bookmarked URL. Fixes filters being dropped on first interaction.defaultSortis treated as "not a user selection" for the clear-state.Verification
pnpm jest --filter=trustlab— 177 passingpnpm lint:check/pnpm format:check— cleanpnpm --filter=trustlab build(next build) — compiles; pages-router routes intact; no phantom*.testroutesKnown follow-ups
Type of change
Screenshots
Checklist: