From ca3fe0c87b31d46e7338e01e475e4a644979e34e Mon Sep 17 00:00:00 2001 From: Timothy Date: Tue, 7 Jul 2026 20:29:40 +0200 Subject: [PATCH] feat(web): playout alternate-schedule and template editors on the REST API (#144 S6 (#162)) Adds two sub-path editors under the Playouts screen: - /app/playouts/{id}/alternate-schedules (Classic playouts) - /app/playouts/{id}/templates (Block playouts) Each has a reorderable priority table (up/down/delete) plus a selected-row detail panel: schedule or template+deco-template pickers, a limit-to-date-range toggle gating month/day/year selects, and day-of-week / day-of-month / month multi-select chips with Weekdays/Weekends helpers. Entry points on the playout card are kind-gated. The Block playout card also gets a default-deco select wired to PUT /api/playouts/{id}/deco, using the new decoName read field. DayOfWeek is overridden to day-name strings in the API client (the wire format is Newtonsoft StringEnumConverter, though the OpenAPI schema types it as number). Deviations from Blazor: chip multi-select instead of MudSelect, flat grouped template pickers instead of a group->item cascade, a shorter year range, and the template calendar preview is omitted. Co-Authored-By: Claude Fable 5 --- web/src/App.tsx | 110 ++- web/src/api/playouts.test.ts | 102 +- web/src/api/playouts.ts | 82 ++ web/src/routing.ts | 28 + .../screens/PlayoutScheduleEditors.test.tsx | 196 ++++ web/src/screens/PlayoutScheduleEditors.tsx | 889 ++++++++++++++++++ web/src/shell.css | 23 + 7 files changed, 1427 insertions(+), 3 deletions(-) create mode 100644 web/src/screens/PlayoutScheduleEditors.test.tsx create mode 100644 web/src/screens/PlayoutScheduleEditors.tsx diff --git a/web/src/App.tsx b/web/src/App.tsx index f697bd3fb..9274a81c9 100644 --- a/web/src/App.tsx +++ b/web/src/App.tsx @@ -78,7 +78,11 @@ import { BlocksScreen } from './screens/BlocksScreen'; import { DecosScreen } from './screens/DecosScreen'; import { DecoTemplatesScreen } from './screens/DecoTemplatesScreen'; import { TemplatesScreen } from './screens/TemplatesScreen'; -import { navigateToPath } from './routing'; +import { + PlayoutAlternateSchedulesScreen, + PlayoutTemplatesEditorScreen +} from './screens/PlayoutScheduleEditors'; +import { navigateToPath, parsePlayoutSubRoute } from './routing'; import { Badge, Button, @@ -106,12 +110,14 @@ import { bulkRenumberChannels, createPlayout, deleteChannel, + getDecos, messageFromError, addScheduleItem, deleteScheduleItem, getSchedules, resetAllPlayouts, replaceScheduleItems, + updatePlayoutDefaultDeco, updatePlayoutDetails, usePlayoutsScreenQuery, useScheduleScreenQuery, @@ -128,6 +134,7 @@ import { type ChannelGuideProgramme, type CreatePlayoutRequest, type DashboardChannel, + type DecoListItem, type SchedulePickerData, type DashboardChannelState, type DashboardHealthQueryState, @@ -315,6 +322,8 @@ const routes: ScreenRoute[] = [ allowSubPaths: true }, { + // The alternate-schedules / templates editors live at sub-paths + // (/app/playouts/{id}/alternate-schedules, /app/playouts/{id}/templates). id: 'playouts', path: '/app/playouts', label: 'Playouts', @@ -324,7 +333,8 @@ const routes: ScreenRoute[] = [ icon: