feat(dashboard): wire TanStack loaders, typed URL search, and barrel cleanup#69
Merged
pratyush618 merged 11 commits intomasterfrom Apr 24, 2026
Merged
Conversation
- Lift QueryClient into a shared module (lib/query-client.ts) and pass it through both QueryProvider and TanStack Router context so loaders can call ensureQueryData against the same cache the components read from. - Type the router context via createRootRouteWithContext. - Add lib/errors.ts (isBackendUnreachable: TypeError fetch + 502/503/504) and a BackendOffline page with actionable steps + router.invalidate() retry. Root errorComponent delegates to it for connection failures; generic errors keep the existing screen.
- jobs/search-schema.ts: jobListSearchSchema + jobFiltersSchema with page-size clamped to [10, 200]. JobListQuery/JobFilters now inferred from the schemas so runtime validator and compile-time type stay in lock-step. - logs/search-schema.ts and metrics/search-schema.ts define the URL contracts for those routes (task/level for /logs, range/task for /metrics) plus their default constants. - parseJobListSearch keeps its silent-drop semantics so a malformed deep link never blanks the page; the final v.parse asserts the normalized shape against the schema to catch drift between the two.
Adds queryOptions factories across feature hook modules and wires route-level loaders that prefetch via the query client, eliminating post-navigation fetch waterfalls. Replaces vite's default proxy error handler with a throttled one (one warning per 30s) so an offline backend no longer floods the dev terminal, while still returning 503 so BackendOffline renders.
Updates the observability dashboard guide to describe the React + Vite + TanStack stack and the bundled-asset delivery model, and documents the new pool/app kwargs on arun_worker.
Marks PRs inactive for 7 days as stale and closes them after 3 additional days (10 total) with a closing comment.
Switches four layout consumers (command-palette, refresh-control, theme-toggle, header) to import from '@/providers' instead of the individual provider modules. Toaster keeps its deep import because the providers barrel imports Toaster, so routing it through the barrel would create a cycle.
Six layout files (app-shell, command-palette, header, mobile-menu, route-error-boundary, theme-toggle) now import from '@/components/ui' instead of per-file paths, matching the pattern used in route files. routes/jobs/index.tsx had three separate '@/features/jobs/*' imports despite already using the feature barrel; collapses JobFilters and JobListQuery type imports into the existing barrel import. providers/index.tsx keeps its '@/components/ui/toaster' deep import to keep the providers shell lean. routes/logs.tsx and routes/metrics.tsx keep theirs per file-level comments (bundle-splitting: the non-lazy route must not pull Recharts or virtualized-log components).
v3 is deprecated in December 2026 and its Node.js 20 runtime hits end-of-life before then. v4 runs on Node.js 24 and clears the CodeQL warnings surfaced on PR #68.
pnpm/action-setup v4 -> v5 and actions/upload-artifact v5 -> v7. Both v4/v5 were still on Node.js 20, which GitHub Actions is sunsetting; the newer majors run on Node.js 24. Also aligns upload-artifact with the v7 pin used in publish.yml.
- astral-sh/setup-uv v5/v7 -> v8.1.0 (v8 removed floating major tags for supply-chain hardening, so pin the full tag) - actions/upload-pages-artifact v3 -> v5.0.0 - actions/deploy-pages v4 -> v5.0.0 - actions/labeler v5 -> v6.0.1 - actions/stale v9 -> v10.2.0 - amannn/action-semantic-pull-request v5 -> v6.1.1 All v5->v6 and v9->v10 jumps are Node.js 20 -> 24 runtime bumps with no config-breaking changes. upload-pages-artifact v4 excludes dotfiles from the artifact by default, which does not affect our zensical-built site.
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.
Summary
Completes the dashboard rewrite cycle with route-level loaders, typed URL search schemas, quieter dev ergonomics, and import cleanup. Also adds a stale-PR automation workflow.
Dashboard
jobListSearchSchema,logsSearchSchema,metricsSearchSchemaback each route'svalidateSearch;JobListQuery/JobFiltersare inferred from the schema so the runtime validator and compile-time type stay in lock-step.parseJobListSearchkeeps silent-drop semantics so a malformed deep link doesn't blank the page.queryClientis plumbed throughRouterProvidercontext;BackendOfflineerror page renders when the app detects the backend is unreachable (isBackendUnreachablehelper inlib/errors.ts).*Query/queryOptionsfactories on every feature'shooks.ts. Routes prefetch viaqueryClient.ensureQueryData(...)so navigation lands on warm data and eliminates the post-navigation fetch waterfall.useJobs/useJob/ etc. now spread the factory and layer onrefetchInterval.503soBackendOfflinetriggers.command-palette,refresh-control,theme-toggle,header,app-shell,mobile-menu,route-error-boundary) now use@/providersand@/components/uibarrels to match the pattern used in routes.providers/index.tsxandcomponents/ui/toaster.tsxkeep their direct imports to avoid aproviders ↔ toastercycle;routes/logs.tsxandroutes/metrics.tsxkeep theirs per inline comments (bundle-splitting: the non-lazy routes must not pull Recharts or virtualized-log components into the main chunk).Docs
py_src/taskito/static/dashboard/).arun_workernow documents thepoolandappkwargs.CI
.github/workflows/stale.ymlmarks PRs inactive for 7 days asstale, closes them after 3 more days (10 total), and posts a closing comment. Daily cron at 02:00 UTC, manual dispatch supported. Exemptspinned/security/work-in-progress. Issues opt-out.Test plan
pnpm run typecheck(dashboard): 153 files, cleanpnpm exec biome check src/: cleanpnpm run test --run: 34/34 passingtaskito dashboard --app ...:queueand confirm Jobs/Logs/Metrics/Queues/Workers/Resources/System/Dead-Letters/Circuit-Breakers/Overview render with loader-prefetched data/jobs?task=foo&page=2&pageSize=50and confirm filters + pagination survive reload; deep-link with invalid params and confirm silent dropBackendOfflinerenders and the vite dev terminal shows a single throttled warning (not a stack trace flood)