Draw a leave period as one band, and make red days look red
A six-week summer used to render as a row of disconnected bars, because bars were derived per week row and grouped by parent and day type. They carried no identity and ignored pointer events, so there was nothing to click. Bands now group by the wish that produced them, bridge the weekends and red days inside a period, and round only the ends that are genuinely the first and last day. Each day still shows what pays for it, and a hand-edited day is marked as one the planner will leave alone. Sundays and public holidays now render red and Saturdays a neutral grey, following the printed almanacka people compare against, and a holiday's name is visible in the cell rather than hidden in a tooltip. This also explains the report that months looked unshaded: weekends had no styling at all, since the day component handled only red days and klämdagar. The year selector follows the range the calendar API actually serves instead of a hardcoded span.
This commit is contained in:
@@ -264,9 +264,14 @@ describe('Calendar', () => {
|
||||
expect(yearSelect.value).toBe('2026')
|
||||
})
|
||||
|
||||
it('year dropdown includes all supported years from 2026 to 2055', () => {
|
||||
it('year dropdown is derived from the calendar window\'s minYear/maxYear, not a hardcoded literal', () => {
|
||||
vi.mocked(useWorkspace).mockReturnValue(mockWorkspace)
|
||||
vi.mocked(usePlannedDays).mockReturnValue(mockPlannedDays)
|
||||
vi.mocked(useCalendarDays).mockReturnValue(
|
||||
makeCalendarDaysResult({
|
||||
data: makeCalendarWindow({ minYear: 2026, maxYear: 2055 }),
|
||||
}),
|
||||
)
|
||||
|
||||
render(<Calendar />)
|
||||
|
||||
@@ -275,12 +280,44 @@ describe('Calendar', () => {
|
||||
|
||||
const options = Array.from(yearSelect.options).map((opt) => parseInt(opt.value))
|
||||
|
||||
// Verify the range is correct
|
||||
// Verify the range comes from the API's reported bounds
|
||||
expect(Math.min(...options)).toBe(2026)
|
||||
expect(Math.max(...options)).toBe(2055)
|
||||
expect(options).toHaveLength(30) // 2026 to 2055 inclusive is 30 years
|
||||
})
|
||||
|
||||
it('year dropdown reflects a narrower calendar window when the API reports one', () => {
|
||||
vi.mocked(useWorkspace).mockReturnValue(mockWorkspace)
|
||||
vi.mocked(usePlannedDays).mockReturnValue(mockPlannedDays)
|
||||
// Default fixture window: minYear 2026, maxYear 2035 (see makeCalendarWindow).
|
||||
|
||||
render(<Calendar />)
|
||||
|
||||
const title = screen.getByRole('heading', { level: 2 })
|
||||
const yearSelect = title.querySelector('.calendar__year-select') as HTMLSelectElement
|
||||
const options = Array.from(yearSelect.options).map((opt) => parseInt(opt.value))
|
||||
|
||||
expect(Math.min(...options)).toBe(2026)
|
||||
expect(Math.max(...options)).toBe(2035)
|
||||
expect(options).toHaveLength(10)
|
||||
})
|
||||
|
||||
it('always includes the current year in the dropdown even before the calendar window has loaded', () => {
|
||||
vi.mocked(useWorkspace).mockReturnValue(mockWorkspace)
|
||||
vi.mocked(usePlannedDays).mockReturnValue(mockPlannedDays)
|
||||
vi.mocked(useCalendarDays).mockReturnValue(
|
||||
makeCalendarDaysResult({ data: null, isLoading: true }),
|
||||
)
|
||||
|
||||
render(<Calendar />)
|
||||
|
||||
const title = screen.getByRole('heading', { level: 2 })
|
||||
const yearSelect = title.querySelector('.calendar__year-select') as HTMLSelectElement
|
||||
const options = Array.from(yearSelect.options).map((opt) => parseInt(opt.value))
|
||||
|
||||
expect(options).toContain(new Date().getFullYear())
|
||||
})
|
||||
|
||||
it('month and year selects have proper accessibility labels', () => {
|
||||
vi.mocked(useWorkspace).mockReturnValue(mockWorkspace)
|
||||
vi.mocked(usePlannedDays).mockReturnValue(mockPlannedDays)
|
||||
|
||||
Reference in New Issue
Block a user