fix: prevent loading state flashes on page refresh#538
Conversation
Gate dashboard Outlet rendering on member context availability to prevent child routes from briefly showing AccessDenied while Convex WebSocket auth is still establishing after a hard reload. Switch approvals route loaders from non-blocking prefetchQuery to blocking ensureQueryData for count queries, ensuring skeleton rows display instead of the empty state during initial data load.
f3622fa to
16e7c02
Compare
Greptile SummaryPrevents loading state flashes during page refresh by gating dashboard content on authentication state and ensuring data is loaded before rendering.
Confidence Score: 5/5
|
| Filename | Overview |
|---|---|
| services/platform/app/routes/dashboard/$id.tsx | Gates Outlet rendering on memberContext.role to prevent flashing AccessDenied during auth initialization |
| services/platform/app/routes/dashboard/$id/approvals.tsx | Switches from non-blocking prefetchQuery to blocking ensureQueryData with Promise.all for count queries |
| services/platform/app/routes/dashboard/$id/approvals/$status.tsx | Switches from non-blocking prefetchQuery to blocking ensureQueryData for count queries |
Last reviewed commit: 16e7c02
📝 WalkthroughWalkthroughThe PR modifies dashboard route files to change data-loading behavior and role-based rendering. In the main dashboard route, it introduces a hasRole boolean to conditionally render the routed outlet based on user role presence. In the approvals subroutes, it replaces fire-and-forget prefetchQuery calls with explicit awaited ensureQueryData calls, both individually and combined via Promise.all for concurrent execution. These changes shift from background data prefetching to synchronous data hydration before proceeding. Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Tip Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
services/platform/app/routes/dashboard/$id/approvals/$status.tsx (1)
31-38: 🧹 Nitpick | 🔵 TrivialThe
isValidStatusguard in the loader is dead code.
beforeLoadalready throwsnotFound()for invalid statuses beforeloaderis invoked, soisValidStatus(params.status)is alwaystruehere.♻️ Simplify loader by removing the redundant guard
loader: async ({ context, params }) => { - if (isValidStatus(params.status)) { - await context.queryClient.ensureQueryData( - convexQuery(api.approvals.queries.approxCountApprovalsByStatus, { - organizationId: params.id, - status: params.status, - }), - ); - } + await context.queryClient.ensureQueryData( + convexQuery(api.approvals.queries.approxCountApprovalsByStatus, { + organizationId: params.id, + status: params.status as ValidStatus, + }), + ); },🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@services/platform/app/routes/dashboard/`$id/approvals/$status.tsx around lines 31 - 38, The isValidStatus guard in the loader is redundant because beforeLoad already throws notFound() for invalid statuses; remove the if (isValidStatus(params.status)) wrapper and always call context.queryClient.ensureQueryData(convexQuery(api.approvals.queries.approxCountApprovalsByStatus, { organizationId: params.id, status: params.status })); keep the same params and call but eliminate the dead isValidStatus check to simplify loader logic (refer to isValidStatus, beforeLoad, loader, context.queryClient.ensureQueryData, convexQuery, api.approvals.queries.approxCountApprovalsByStatus, params.status, params.id).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@services/platform/app/routes/dashboard/`$id/approvals/$status.tsx:
- Around line 31-38: The isValidStatus guard in the loader is redundant because
beforeLoad already throws notFound() for invalid statuses; remove the if
(isValidStatus(params.status)) wrapper and always call
context.queryClient.ensureQueryData(convexQuery(api.approvals.queries.approxCountApprovalsByStatus,
{ organizationId: params.id, status: params.status })); keep the same params and
call but eliminate the dead isValidStatus check to simplify loader logic (refer
to isValidStatus, beforeLoad, loader, context.queryClient.ensureQueryData,
convexQuery, api.approvals.queries.approxCountApprovalsByStatus, params.status,
params.id).
ℹ️ Review info
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (3)
services/platform/app/routes/dashboard/$id.tsxservices/platform/app/routes/dashboard/$id/approvals.tsxservices/platform/app/routes/dashboard/$id/approvals/$status.tsx
Summary by CodeRabbit
Release Notes