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:
@@ -11,7 +11,7 @@ import {
|
||||
import type { PlannedLeaveDay, CalendarDayEntry } from '@/types'
|
||||
import { Layout } from '@/components/layout/Layout'
|
||||
import { LoadingSpinner } from '@/components/common/LoadingSpinner'
|
||||
import { CalendarWeek } from '@/components/common/CalendarWeek'
|
||||
import { CalendarWeek, type BandClickInfo } from '@/components/common/CalendarWeek'
|
||||
import { PlannedDayModal } from '@/components/modals/PlannedDayModal'
|
||||
import { getColorForType } from '@/utils/leaveTypes'
|
||||
import { datesInRange } from '@/utils/dates'
|
||||
@@ -102,6 +102,17 @@ export function Calendar(): ReactNode {
|
||||
const year = currentMonth.getFullYear()
|
||||
const month = currentMonth.getMonth()
|
||||
|
||||
// The year <select> must cover the API's real supported range (from
|
||||
// `CalendarWindow.minYear`/`maxYear`, not a hardcoded literal), while
|
||||
// always including the currently-selected year even before the window has
|
||||
// loaded (or if it somehow falls outside the reported bounds).
|
||||
const yearRangeMin = Math.min(calendarWindow?.minYear ?? year, year)
|
||||
const yearRangeMax = Math.max(calendarWindow?.maxYear ?? year, year)
|
||||
const yearOptions = Array.from(
|
||||
{ length: yearRangeMax - yearRangeMin + 1 },
|
||||
(_, i) => yearRangeMin + i,
|
||||
)
|
||||
|
||||
const firstDay = new Date(year, month, 1)
|
||||
const lastDay = new Date(year, month + 1, 0)
|
||||
const daysInMonth = lastDay.getDate()
|
||||
@@ -283,6 +294,13 @@ export function Calendar(): ReactNode {
|
||||
}
|
||||
}
|
||||
|
||||
// Exposed cleanly for a later task: clicking a band (a planned period,
|
||||
// possibly spanning several weeks) will open a period editor. That editor
|
||||
// doesn't exist yet, so this is intentionally a no-op for now.
|
||||
const handleBandClick = (_info: BandClickInfo): void => {
|
||||
// TODO: open a period editor for this band once it exists.
|
||||
}
|
||||
|
||||
const defaultLeaveType = getLastLeaveType() ?? 'vacation'
|
||||
const firstSelectedDate = Array.from(selectedDates).sort()[0]
|
||||
|
||||
@@ -323,7 +341,7 @@ export function Calendar(): ReactNode {
|
||||
className="calendar__year-select"
|
||||
aria-label={t('calendar.selectYearAria')}
|
||||
>
|
||||
{Array.from({ length: 2055 - 2026 + 1 }, (_, i) => 2026 + i).map((y) => (
|
||||
{yearOptions.map((y) => (
|
||||
<option key={y} value={y}>
|
||||
{y}
|
||||
</option>
|
||||
@@ -364,7 +382,13 @@ export function Calendar(): ReactNode {
|
||||
{t(key)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Each week is its own small CSS Grid (see CalendarWeek.tsx/
|
||||
calendar.css) so a multi-day band can span several day columns as
|
||||
one element — that only works if each week is a separate grid,
|
||||
not a flat row of the header grid above. */}
|
||||
<div className="calendar__weeks">
|
||||
{weeks.map((week, weekIdx) => {
|
||||
const firstDate = week[0]
|
||||
const weekMonth = firstDate ? new Date(firstDate + 'T00:00:00Z').getMonth() : month
|
||||
@@ -382,6 +406,7 @@ export function Calendar(): ReactNode {
|
||||
onPointerDown={handlePointerDown}
|
||||
onPointerEnter={handlePointerEnter}
|
||||
calendarDaysByDate={calendarDaysByDate}
|
||||
onBandClick={handleBandClick}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
|
||||
Reference in New Issue
Block a user