Dedicated ChannelEditScreen (hydrate-then-PUT on GET/PUT /api/channels/{id}, no backend changes) replacing the dead /app/new-channel?edit= pencil link. Scope call (builder hydration rejected) documented on the issue.
Full ChannelEditor.razor field parity across a 6-section rail: identity, playout source/mode + mirror conditionals, streaming/FFmpeg profile/watermark (HLS-Direct lock), stream selector default/custom branch, music video credits, logo preview+upload, fallback filler.
New getChannelById/updateChannel API clients + tests; screen tests (hydration, PUT body, 404 state).
Skipped per scope: ExternalLogoUrl (absent from the JSON contract), /channels/numbers drag-reorder (existing Renumber toolbar accepted as parity — see issue comment).
Live E2E: real server, PUT/GET round-trip + 404 path verified, data reverted.
151 web tests green; tsc, eslint, vite build clean.
Closes #146 (#91 blocker).
Dedicated `ChannelEditScreen` (hydrate-then-PUT on `GET`/`PUT /api/channels/{id}`, no backend changes) replacing the dead `/app/new-channel?edit=` pencil link. Scope call (builder hydration rejected) documented on the issue.
- Full `ChannelEditor.razor` field parity across a 6-section rail: identity, playout source/mode + mirror conditionals, streaming/FFmpeg profile/watermark (HLS-Direct lock), stream selector default/custom branch, music video credits, logo preview+upload, fallback filler.
- New `getChannelById`/`updateChannel` API clients + tests; screen tests (hydration, PUT body, 404 state).
- Skipped per scope: `ExternalLogoUrl` (absent from the JSON contract), `/channels/numbers` drag-reorder (existing Renumber toolbar accepted as parity — see issue comment).
- Live E2E: real server, PUT/GET round-trip + 404 path verified, data reverted.
- 151 web tests green; tsc, eslint, vite build clean.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Add a full ChannelEditScreen so the SPA can edit an existing channel
(the list/builder could only create). Mirrors the Blazor ChannelEditor
field set via hydrate-then-PUT against GET/PUT /api/channels/{id}.
- api/channels.ts: getChannelById + updateChannel (typed from generated
ChannelViewModel / UpdateChannelRequest).
- screens/ChannelEditScreen.tsx: section-rail form (General, Playout,
Streaming, Stream selection, Music video, Branding) following the
SettingsScreen draft/saved dirtiness + floating save bar pattern. Logo
upload reuses uploadArtwork; option data via existing pickers clients.
- App.tsx: /app/edit-channel/{id} route (allowSubPaths, screen parses the
id); repoint the channel-table edit pencil at it.
- Tests: API-client GET/PUT + screen hydrate/edit-save/404 coverage.
Deferred per scope: ExternalLogoUrl (backend contract gap), and the
/channels/numbers bulk renumber (existing Renumber toolbar = parity).
Language codes / stream selector / credits template are free-text inputs
(no enumeration endpoints exist); mirror-source list can't filter to
Generated-only (ChannelResponseModel omits playoutSource).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Closes #146 (#91 blocker).
Dedicated
ChannelEditScreen(hydrate-then-PUT onGET/PUT /api/channels/{id}, no backend changes) replacing the dead/app/new-channel?edit=pencil link. Scope call (builder hydration rejected) documented on the issue.ChannelEditor.razorfield parity across a 6-section rail: identity, playout source/mode + mirror conditionals, streaming/FFmpeg profile/watermark (HLS-Direct lock), stream selector default/custom branch, music video credits, logo preview+upload, fallback filler.getChannelById/updateChannelAPI clients + tests; screen tests (hydration, PUT body, 404 state).ExternalLogoUrl(absent from the JSON contract),/channels/numbersdrag-reorder (existing Renumber toolbar accepted as parity — see issue comment).🤖 Generated with Claude Code
Add a full ChannelEditScreen so the SPA can edit an existing channel (the list/builder could only create). Mirrors the Blazor ChannelEditor field set via hydrate-then-PUT against GET/PUT /api/channels/{id}. - api/channels.ts: getChannelById + updateChannel (typed from generated ChannelViewModel / UpdateChannelRequest). - screens/ChannelEditScreen.tsx: section-rail form (General, Playout, Streaming, Stream selection, Music video, Branding) following the SettingsScreen draft/saved dirtiness + floating save bar pattern. Logo upload reuses uploadArtwork; option data via existing pickers clients. - App.tsx: /app/edit-channel/{id} route (allowSubPaths, screen parses the id); repoint the channel-table edit pencil at it. - Tests: API-client GET/PUT + screen hydrate/edit-save/404 coverage. Deferred per scope: ExternalLogoUrl (backend contract gap), and the /channels/numbers bulk renumber (existing Renumber toolbar = parity). Language codes / stream selector / credits template are free-text inputs (no enumeration endpoints exist); mirror-source list can't filter to Generated-only (ChannelResponseModel omits playoutSource). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>