From d0f207704a406d4fbc65e89ef37f19bacfa0deef Mon Sep 17 00:00:00 2001 From: Peter Stone Date: Mon, 13 Jul 2026 18:10:10 +0000 Subject: feat(web): show multi-day calendar events on every day they span TimelineItemView wraps a TimelineItem with a per-render-day MultiDayVariant (starts/ends/spans/none). HandleTimeline's bucketing now places a multi-day event into both TodayItems and TomorrowItems when it touches both, instead of only the list matching its start day. --- internal/handlers/timeline_logic_test.go | 41 +++++++++++++++++++------------- 1 file changed, 25 insertions(+), 16 deletions(-) (limited to 'internal/handlers/timeline_logic_test.go') diff --git a/internal/handlers/timeline_logic_test.go b/internal/handlers/timeline_logic_test.go index 01ad814..89581a3 100644 --- a/internal/handlers/timeline_logic_test.go +++ b/internal/handlers/timeline_logic_test.go @@ -172,22 +172,22 @@ func TestBuildTimeline(t *testing.T) { func TestCalcCalendarBounds(t *testing.T) { tests := []struct { name string - items []models.TimelineItem + items []TimelineItemView currentHour int wantStart int wantEnd int }{ { name: "no timed events returns default", - items: []models.TimelineItem{}, + items: []TimelineItemView{}, currentHour: -1, wantStart: 8, wantEnd: 18, }, { name: "single event at 10am", - items: []models.TimelineItem{ - {Time: time.Date(2023, 1, 1, 10, 0, 0, 0, time.UTC)}, + items: []TimelineItemView{ + {TimelineItem: models.TimelineItem{Time: time.Date(2023, 1, 1, 10, 0, 0, 0, time.UTC)}}, }, currentHour: -1, wantStart: 9, // 1 hour buffer before @@ -195,8 +195,8 @@ func TestCalcCalendarBounds(t *testing.T) { }, { name: "includes current hour", - items: []models.TimelineItem{ - {Time: time.Date(2023, 1, 1, 10, 0, 0, 0, time.UTC)}, + items: []TimelineItemView{ + {TimelineItem: models.TimelineItem{Time: time.Date(2023, 1, 1, 10, 0, 0, 0, time.UTC)}}, }, currentHour: 8, wantStart: 7, // 1 hour before 8am @@ -204,11 +204,11 @@ func TestCalcCalendarBounds(t *testing.T) { }, { name: "event with end time extends range", - items: []models.TimelineItem{ - { + items: []TimelineItemView{ + {TimelineItem: models.TimelineItem{ Time: time.Date(2023, 1, 1, 10, 0, 0, 0, time.UTC), EndTime: timePtr(time.Date(2023, 1, 1, 14, 0, 0, 0, time.UTC)), - }, + }}, }, currentHour: -1, wantStart: 9, // 1 hour before 10am @@ -216,8 +216,8 @@ func TestCalcCalendarBounds(t *testing.T) { }, { name: "all-day events are skipped", - items: []models.TimelineItem{ - {Time: time.Date(2023, 1, 1, 0, 0, 0, 0, time.UTC), IsAllDay: true}, + items: []TimelineItemView{ + {TimelineItem: models.TimelineItem{Time: time.Date(2023, 1, 1, 0, 0, 0, 0, time.UTC), IsAllDay: true}}, }, currentHour: -1, wantStart: 8, @@ -225,8 +225,8 @@ func TestCalcCalendarBounds(t *testing.T) { }, { name: "overdue events are skipped", - items: []models.TimelineItem{ - {Time: time.Date(2023, 1, 1, 10, 0, 0, 0, time.UTC), IsOverdue: true}, + items: []TimelineItemView{ + {TimelineItem: models.TimelineItem{Time: time.Date(2023, 1, 1, 10, 0, 0, 0, time.UTC), IsOverdue: true}}, }, currentHour: -1, wantStart: 8, @@ -234,14 +234,23 @@ func TestCalcCalendarBounds(t *testing.T) { }, { name: "clamps to 0-23 range", - items: []models.TimelineItem{ - {Time: time.Date(2023, 1, 1, 0, 30, 0, 0, time.UTC)}, - {Time: time.Date(2023, 1, 1, 23, 0, 0, 0, time.UTC)}, + items: []TimelineItemView{ + {TimelineItem: models.TimelineItem{Time: time.Date(2023, 1, 1, 0, 30, 0, 0, time.UTC)}}, + {TimelineItem: models.TimelineItem{Time: time.Date(2023, 1, 1, 23, 0, 0, 0, time.UTC)}}, }, currentHour: -1, wantStart: 0, // Can't go below 0 wantEnd: 23, // Can't go above 23 }, + { + name: "multi-day rows are skipped like all-day events", + items: []TimelineItemView{ + {TimelineItem: models.TimelineItem{Time: time.Date(2023, 1, 1, 17, 0, 0, 0, time.UTC)}, MultiDayVariant: "starts"}, + }, + currentHour: -1, + wantStart: 8, + wantEnd: 18, + }, } for _, tc := range tests { -- cgit v1.2.3