Skip to content

fix(web): settings shows on first load + global DemoProvider#1

Merged
offendingcommit merged 4 commits intomainfrom
fix/web-settings-and-demo-provider
May 3, 2026
Merged

fix(web): settings shows on first load + global DemoProvider#1
offendingcommit merged 4 commits intomainfrom
fix/web-settings-and-demo-provider

Conversation

@offendingcommit
Copy link
Copy Markdown
Owner

Summary

Two bugs in packages/web:

Bug 1 — Blank screen on first load

__root.tsx called loadConfig() synchronously, returned null if no config existed, and only fired router.navigate({ to: '/settings' }) from a useEffect. The first paint was empty until the effect ran (and on StrictMode double-invoke + scheduling, often required a manual refresh to surface the settings page).

Fix: moved the redirect into the root route's beforeLoad, so the redirect resolves synchronously during route loading and the settings form is the first thing rendered.

Bug 2 — DemoProvider not globally available

<DemoProvider> was mounted inside RootLayout after the if (!config) return null early return and only on the non-settings branch. Any consumer of useDemo() outside that branch would throw useDemoContext must be used within DemoProvider.

Fix: hoisted <DemoProvider> up into main.tsx so the context wraps the entire app (settings route included).

Tests

Added packages/web/vitest.config.ts, jsdom setup, and src/test/app.test.tsx:

  • first load with no config > renders the settings form on first paint when no config exists — fails before the fix (empty body), passes after.
  • Sidebar/useDemo availability across routes > does not throw when a useDemo consumer mounts alongside the routed app — guards the global-provider wiring.

Confirmed both tests fail for the right reason on the unfixed code, then pass after the fix.

Test plan

  • pnpm --filter @openconcho/web test
  • pnpm --filter @openconcho/web typecheck
  • pnpm --filter @openconcho/web build
  • Manual: clear localStorage, reload / → settings form visible immediately, no refresh needed.
  • Manual: save config, navigate to /settings, no useDemoContext console error.

Notes

  • pnpm lint is broken on main due to a pre-existing biome config / version mismatch (biome.json uses 2.x keys, installed biome is 1.9.4). Not addressed here to keep the PR scoped — flag for follow-up.
  • Playwright e2e was not added; the workspace has no existing playwright setup and adding it expanded scope beyond the bug fixes. The unit tests cover the regressions.

Bug 1: On a fresh load with no saved config, RootLayout returned `null`
while a useEffect-driven `router.navigate()` fired, leaving a blank screen
until the user manually refreshed. Move the redirect into the root route's
`beforeLoad` so it happens synchronously during route resolution and the
settings form renders on first paint.

Bug 2: `DemoProvider` was mounted inside `RootLayout` only on the
non-settings branch, so any component reading `useDemo()` outside that
branch would throw "useDemoContext must be used within DemoProvider".
Hoist `<DemoProvider>` to `main.tsx` so the context is available app-wide.

Adds vitest + RTL setup with regression tests for both behaviours.
Settings page was rendering Outlet directly, omitting the Sidebar nav.
Adds a playwright e2e test asserting sidebar visibility on both
dashboard and settings routes.
- Promote @playwright/test to the workspace catalog
- Add test:e2e turbo task (uncached)
- Add root pnpm test:e2e script
- Vitest scopes to src/**/*.{test,spec} and excludes e2e/
@offendingcommit offendingcommit merged commit 2c848d6 into main May 3, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant