refactor(web): adopt <DataState> in routine panels#1714
Conversation
Wrap the routine calendar skeleton/panel branch in
`apps/web/src/modules/routine/RoutineTimeline.tsx` with the unified
<DataState> wrapper so the habit-pending loading swap flows through the
same loading contract as finyk (PR 2.4), fizruk (PR 2.5) and nutrition
(PR 2.6) — initiative 0011 PR 2.7.
Visible behaviour is preserved across all four (mainTab, isHabitPending)
combinations:
- calendar + pending → 4x SkeletonHabitRow shimmer (exactly as before).
- calendar + idle → <RoutineCalendarPanel hidden={false} />.
- stats + pending → <RoutineCalendarPanel hidden={true} /> (panel
stays mounted, preserving its internal state).
- stats + idle → <RoutineCalendarPanel hidden={true} />.
Mapping: `calendarBusy = isHabitPending && mainTab === 'calendar'`,
`query.data = calendarBusy ? undefined : true` — DataState only
renders the skeleton slot when data is undefined, so the calendar panel
remains mounted on the stats tab even while a habit mutation is
pending, just like before. Stats branch is untouched.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthrough
ChangesCalendar Loading State Refactoring
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Review rate limit: 8/10 reviews remaining, refill in 9 minutes and 26 seconds. Comment |
⏱️ CI Pipeline Duration ReportBased on the last 50 successful runs on the default branch. Overall Pipeline
Trend (last 20 runs): Per-Job Breakdown
|
Update initiative 0011 to reflect Phase 2 progress through 2026-05-04: - Status header bumped to include the four open <DataState> consumer PRs: 2.4 #1703 (finyk), 2.5 #1709 (fizruk), 2.6 #1713 (nutrition), 2.7 #1714 (routine). Last-validated handle aligned with the actual initiative owner (@Skords-01). - Phase 2 table column 'Файли (приклад)' renamed to 'Файли (фактичні споживачі)' and ETA column replaced with Status (PR-link). Rows for 2.4–2.7 now point at the actual landed targets, not the initial guess names from the proposal draft (MonoTransactionsPanel, WorkoutHistoryPanel, NutritionMealsPanel, RoutineList, etc. — none of those components physically exist in the repo). - New explanatory note after the table records why the file list diverged from the original draft (real Skeleton-based loading sites per module) and documents the per-module finding for 2.6 / 2.7 (NutritionApp.tsx Menu plan branch; RoutineTimeline.tsx calendar branch — both modules have exactly one consumer of @shared/components/ui/Skeleton). Supersedes #1710 (single doc PR for 2.4 + 2.5 only); this combined update is the cleaner record because all four <DataState> consumer adoption PRs landed on the same day. Closes the doc-side of initiative 0011 PR 2.6 + 2.7.
Summary
Initiative
0011PR 2.7 — adopt the unified<DataState>wrapper insideapps/web/src/modules/routine/RoutineTimeline.tsxfor the routine calendar panel.The habit-pending skeleton (4×
SkeletonHabitRow) used to live in an inline ternary:It now flows through
<DataState query={calendarQuery} skeleton={calendarLoadingSkeleton}>— same shape as PR 2.4 (#1703), PR 2.5 (#1709), PR 2.6 (#1713). Visible behaviour is preserved across all four(mainTab, isHabitPending)combinations:mainTabisHabitPendingcalendartrueSkeletonHabitRowshimmerSkeletonHabitRowshimmer (via DataState)calendarfalse<RoutineCalendarPanel hidden={false}><RoutineCalendarPanel hidden={false}>statstrue<RoutineCalendarPanel hidden={true}><RoutineCalendarPanel hidden={true}>(panel stays mounted)statsfalse<RoutineCalendarPanel hidden={true}><RoutineCalendarPanel hidden={true}>Mapping:
calendarBusy = isHabitPending && mainTab === 'calendar',query.data = calendarBusy ? undefined : true. DataState only renders the skeleton slot whendata === undefined, so the calendar panel stays mounted on the stats tab even while a habit mutation is pending, just like before. The stats branch and pull-to-refresh wrapper are untouched.Scope rationale:
RoutineTimeline.tsxis the only consumer inapps/web/src/modules/routine/**that imports@shared/components/ui/Skeleton. Closes the routine slot of initiative0011Phase 2 —<DataState>adoption catalogue.Governing Skill
sergeant-web-uisergeant-feature-deliveryPlaybook
docs/initiatives/0011-foundation-adoption-and-process-discipline.mdPhase 2)Verification
Results:
typecheck: exit 0 (tsc -p tsconfig.json --noEmit && tsc -p tsconfig.sw.json --noEmit).eslint RoutineTimeline.tsx: no warnings, no errors.vitest src/modules/routine: 9 files, 106 / 106 tests passed.Additional checks:
Docs and Governance
AGENTS.mdneeded an update.Updated docs:
docs/initiatives/0011-foundation-adoption-and-process-discipline.md(mirrors the workflow from docs(docs): record 0011 PR 2.4 + 2.5 (DataState adoption) progress #1710 for 2.4 + 2.5).Risk and Rollout
<RoutineCalendarPanel hidden={...} />semantics. The truth-table above proves behaviour parity.main. No DB / config / env changes.Hard Rule #15
AGENTS.mdbefore coding.--no-verify.Reviewer Notes
data: true as constliteral is a deliberate sentinel: routine has no RQ data flowing through this branch (calendar panel reads from local-firstRoutineCalendarContext), so DataState'sdata !== undefinedcheck is the only signal we need.<DataState>{() => ...}doesn't read thetruevalue.<RoutineStatsPanel>outside the DataState wrap — it has no skeleton state in this file, only thehidden={mainTab !== "stats"}prop, and its internal mounting/unmounting policy is owned by the panel itself.main(markdown link checker, governance sync, serverapiV1.test.ts, mobilevite buildagainst@sergeant/db-schema/sqlite, Argos visual regression) are unrelated to this change — observed identically on PR 2.4 (refactor(web): adopt <DataState> in finyk Mono panels #1703), PR 2.5 (refactor(web): adopt <DataState> in fizruk Workouts journal #1709), PR 2.6 (refactor(web): adopt <DataState> in nutrition panels #1713).Summary by cubic
Adopted the unified
<DataState>wrapper inapps/web/src/modules/routine/RoutineTimeline.tsxfor the calendar panel to standardize loading behavior. No visible changes; the skeleton and panel render exactly as before, and the calendar stays mounted when viewing stats.<DataState>usingcalendarQueryandcalendarLoadingSkeleton(4×SkeletonHabitRowshimmer).calendarBusy = isHabitPending && mainTab === "calendar";query.data = calendarBusy ? undefined : true.RoutineStatsPanelas-is;RoutineCalendarPanelstill useshidden={mainTab !== "calendar"}and remains mounted.Written for commit bdab9f9. Summary will update on new commits.
Summary by CodeRabbit