Context
Follow-up to #444 / PR #479. In the schedule list view, set-level filters (type, vote, time-of-day) that leave a day with zero matching sets make that whole day group disappear. This is confusing — the user can't tell "no matches this day" from "this day doesn't exist" — and because each sticky day header hosts its own copy of the filter sheet, the open sheet unmounts mid-interaction when its host day group filters away (this is what originally timed out CI on PR #479; the e2e test now works around it by opening the sheet from a surviving day group).
What to build
In src/routes/festivals/$festivalSlug/editions/$editionSlug/schedule/list.tsx, day groups are currently built only from time slots that survive filtering, so emptied days drop out entirely. Instead, build one group per day from filterScheduleDays's output — its contract already keeps non-matching days with empty stages (see the doc comment in src/lib/scheduleFilter.ts) — and give ListDayGroup (src/pages/EditionView/tabs/ScheduleTab/list/ListDayGroup.tsx) an empty state: render the sticky day header as usual plus a small "No sets match your filters" line when slots is empty.
Behavior rules:
- The day filter still narrows to the selected day — do not render empty headers for deselected days (the user explicitly chose one day).
- Set-level filters (type, vote, time-of-day) keep every day's header visible, with the empty state for days they empty.
- When every day is empty, keep the per-day headers with their empty states instead of swapping to the current global "No scheduled sets found" screen, so the filter trigger stays in place. Keep the global empty screen only for editions with no scheduled sets at all.
- The timeline view and the pre-reveal lineup views are out of scope — different layouts, leave their current behavior.
Acceptance criteria
Size estimate
Small-to-medium: two files (list.tsx, ListDayGroup.tsx), roughly 40 lines, plus e2e updates.
Context
Follow-up to #444 / PR #479. In the schedule list view, set-level filters (type, vote, time-of-day) that leave a day with zero matching sets make that whole day group disappear. This is confusing — the user can't tell "no matches this day" from "this day doesn't exist" — and because each sticky day header hosts its own copy of the filter sheet, the open sheet unmounts mid-interaction when its host day group filters away (this is what originally timed out CI on PR #479; the e2e test now works around it by opening the sheet from a surviving day group).
What to build
In
src/routes/festivals/$festivalSlug/editions/$editionSlug/schedule/list.tsx, day groups are currently built only from time slots that survive filtering, so emptied days drop out entirely. Instead, build one group per day fromfilterScheduleDays's output — its contract already keeps non-matching days with empty stages (see the doc comment insrc/lib/scheduleFilter.ts) — and giveListDayGroup(src/pages/EditionView/tabs/ScheduleTab/list/ListDayGroup.tsx) an empty state: render the sticky day header as usual plus a small "No sets match your filters" line whenslotsis empty.Behavior rules:
Acceptance criteria
tests/e2e/schedule-type-filter.spec.ts: revert the workaround so the sheet is opened from the Jul 12 day group, filter to workshops, and assert the sheet stays open and Jul 12 shows the empty state (seed data: the only workshop, "Morning Yoga Workshop", is on Jul 13)Size estimate
Small-to-medium: two files (
list.tsx,ListDayGroup.tsx), roughly 40 lines, plus e2e updates.