refactor(spa): extract ChannelsScreen from App.tsx (#244, epic #243 phase 1) #249

Merged
timothy merged 1 commits from feat/244-channels-extract into main 2026-07-11 13:38:48 +02:00
Owner

What

Phase 1 of the App.tsx modularization epic #243: extract the Channels domain out of web/src/App.tsx into web/src/screens/ChannelsScreen.tsx with a colocated test file. Pure structural move — no API, route, CSS, or visual change. App.tsx retains only the import + the <ChannelsScreen /> dispatch clause.

Runs on top of merged PR #242 (#212 empty-lineup bare-create + #230 popstate guard), which #244 sequencing required to land first.

Changes

  • Move: 14 symbols (ChannelViewFilter → ChannelTableRow) → ChannelsScreen.tsx, zero-prop, mirroring the SchedulesScreen extraction. The Dashboard-owned progressFromNowPlaying is inlined into the moved progressFromChannelState (behavior-identical) so the screen has no import back into App.tsx.
  • Tests: 12 Channels behavior blocks → colocated ChannelsScreen.test.tsx with its own scoped window.fetch mock, rendering <ChannelsScreen /> directly (no mockDashboardApi). App.test.tsx keeps one thin nav-smoke test for the route. Three assertions adapted for direct-render (dropped App-TopBar heading assertion; refetch-count made relative; empty-lineup create-affordance count) — intent preserved.
  • App.tsx: block deleted, import added, 12 now-dead imports pruned (shared ChannelState/messageFromError/ApiError/useChannelsQuery verified still used, kept).
  • Docs (same PR): spa-conventions §6 (extracted-screen own-fetch-mock convention), decisions.md (single-file rationale — no web/src/channels/ sibling dir unlike Schedules; inlined helper; #238 deferral).

Deliberately out of scope

  • #238 (TopBar primaryAction dead button) left exactly as-is — it is #238's owned bug; the shell/action redesign is epic phase 4 (#247).
  • No web/src/channels/ helper dir — Channels' pure logic is ~30 lines, no itemRules.ts-class layer (decisions.md).

Verification

  • web vitest 587 passed (ChannelsScreen.test.tsx 12, App.test.tsx 116)
  • eslint clean · tsc + vite build clean · check:api no drift
  • Live E2E of the Channels screen to follow on this PR.

Closes #244.

🤖 Generated with Claude Code

## What Phase 1 of the App.tsx modularization epic #243: extract the **Channels** domain out of `web/src/App.tsx` into `web/src/screens/ChannelsScreen.tsx` with a colocated test file. **Pure structural move** — no API, route, CSS, or visual change. `App.tsx` retains only the import + the `<ChannelsScreen />` dispatch clause. Runs on top of merged PR #242 (#212 empty-lineup bare-create + #230 popstate guard), which #244 sequencing required to land first. ## Changes - **Move**: 14 symbols (`ChannelViewFilter` → `ChannelTableRow`) → `ChannelsScreen.tsx`, zero-prop, mirroring the SchedulesScreen extraction. The Dashboard-owned `progressFromNowPlaying` is **inlined** into the moved `progressFromChannelState` (behavior-identical) so the screen has no import back into App.tsx. - **Tests**: 12 Channels behavior blocks → colocated `ChannelsScreen.test.tsx` with its own scoped `window.fetch` mock, rendering `<ChannelsScreen />` directly (no `mockDashboardApi`). App.test.tsx keeps one thin nav-smoke test for the route. Three assertions adapted for direct-render (dropped App-TopBar heading assertion; refetch-count made relative; empty-lineup create-affordance count) — intent preserved. - **App.tsx**: block deleted, import added, 12 now-dead imports pruned (shared `ChannelState`/`messageFromError`/`ApiError`/`useChannelsQuery` verified still used, kept). - **Docs (same PR)**: spa-conventions §6 (extracted-screen own-fetch-mock convention), decisions.md (single-file rationale — no `web/src/channels/` sibling dir unlike Schedules; inlined helper; #238 deferral). ## Deliberately out of scope - **#238** (TopBar `primaryAction` dead button) left exactly as-is — it is #238's owned bug; the shell/action redesign is epic phase 4 (#247). - No `web/src/channels/` helper dir — Channels' pure logic is ~30 lines, no `itemRules.ts`-class layer (decisions.md). ## Verification - web vitest **587 passed** (ChannelsScreen.test.tsx 12, App.test.tsx 116) - eslint clean · tsc + vite build clean · `check:api` no drift - Live E2E of the Channels screen to follow on this PR. Closes #244. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
timothy added 1 commit 2026-07-11 13:29:00 +02:00
refactor(spa): extract ChannelsScreen from App.tsx (#244, epic #243 phase 1)
Build ErsatzTV Image / Docs update reminder (pull_request) Successful in 5s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 7m57s
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 9m3s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
f8390bb008
Move the Channels domain verbatim out of web/src/App.tsx into
web/src/screens/ChannelsScreen.tsx (zero-prop, self-sufficient, mirroring the
SchedulesScreen extraction). Pure structural move: no API, route, CSS, or
visual change. App.tsx retains only the import + the <ChannelsScreen /> dispatch.

- 14 symbols moved (ChannelViewFilter → ChannelTableRow); the Dashboard-owned
  progressFromNowPlaying is inlined into the moved progressFromChannelState so
  the screen has no import back into App.tsx (behavior-identical).
- 12 Channels behavior tests moved to a colocated ChannelsScreen.test.tsx with
  its own scoped fetch mock (renders <ChannelsScreen /> directly, no
  mockDashboardApi); App.test.tsx keeps one nav-smoke test for the route.
- Pruned 12 now-dead App.tsx imports; shared symbols (ChannelState,
  messageFromError, ApiError, useChannelsQuery) verified still used and kept.
- Docs: spa-conventions §6 (extracted-screen own-fetch-mock convention),
  decisions.md (single-file rationale; no web/src/channels/ sibling dir, unlike
  Schedules; inlined helper; #238 deferral).

Verified: web vitest 587 passed, eslint clean, tsc/vite build clean,
check:api no drift. #212 empty-lineup bare-create success+failure coverage
preserved. #238 TopBar dead-button left as-is (its owned bug; shell redesign
is epic phase 4 / #247).

refs #244 #243

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
timothy merged commit 533c6c1e9f into main 2026-07-11 13:38:48 +02:00
Sign in to join this conversation.