diff --git a/components/Timetable.vue b/components/Timetable.vue index 45d57fd..da17b6a 100644 --- a/components/Timetable.vue +++ b/components/Timetable.vue @@ -44,14 +44,26 @@ - + {{ day.content }} - + Location - - {{ hour.content }} + +
+ {{ hour.content }} +
@@ -348,8 +360,8 @@ function tableElementsFromStretches( timezone: string, ) { type Col = { minutes?: number }; - type DayHead = { span: number, content?: string } - type HourHead = { span: number, content?: string } + type DayHead = { span: number, isBreak: boolean, content?: string } + type HourHead = { span: number, isBreak: boolean, isDayShift: boolean, content?: string } type LocationCell = { span: number, slots: Set, title: string, crew?: boolean } type RoleCell = { span: number, slots: Set, title: string }; const columnGroups: { className?: string, cols: Col[] }[] = []; @@ -364,11 +376,11 @@ function tableElementsFromStretches( function startColumnGroup(className?: string) { columnGroups.push({ className, cols: []}) } - function startDay(content?: string) { - dayHeaders.push({ span: 0, content }) + function startDay(isBreak: boolean, content?: string) { + dayHeaders.push({ span: 0, isBreak, content }) } - function startHour(content?: string) { - hourHeaders.push({ span: 0, content }) + function startHour(isBreak: boolean, content?: string, isDayShift = false) { + hourHeaders.push({ span: 0, isBreak, isDayShift, content }) } function startLocation(id: number, slots = new Set()) { const rows = locationRows.get(id)!; @@ -409,8 +421,8 @@ function tableElementsFromStretches( if (first) { first = false; startColumnGroup(); - startDay(startDate.toFormat("yyyy-LL-dd")); - startHour(startDate.toFormat("HH:mm")); + startDay(false, startDate.toFormat("yyyy-LL-dd")); + startHour(false, startDate.toFormat("HH:mm")); for(const location of locations.values()) { startLocation(location.id); } @@ -423,8 +435,8 @@ function tableElementsFromStretches( const lastDayHeader = dayHeaders[dayHeaders.length - 1] const sameDay = dayName === lastDayHeader.content && lastDayHeader.span; if (!sameDay) - startDay(); - startHour("break"); + startDay(true); + startHour(true, "break"); for(const location of locations.values()) { startLocation(location.id); } @@ -435,8 +447,8 @@ function tableElementsFromStretches( startColumnGroup(); if (!sameDay) - startDay(dayName); - startHour(startDate.toFormat("HH:mm")); + startDay(false, dayName); + startHour(false, startDate.toFormat("HH:mm")); for(const location of locations.values()) { startLocation(location.id); } @@ -469,16 +481,20 @@ function tableElementsFromStretches( pushColumn(durationMs / oneMinMs); const endDate = DateTime.fromMillis(end, { zone: timezone, locale: accountStore.activeLocale }); - if (end === endDate.startOf("day").toMillis()) { + const isDayShift = end === endDate.startOf("day").toMillis(); + if (isDayShift) { startDay( + false, DateTime.fromMillis(cutSpan.end.ts, { zone: timezone, locale: accountStore.activeLocale }) .toFormat("yyyy-LL-dd") ); } if (end === endDate.startOf("hour").toMillis()) { startHour( + false, DateTime.fromMillis(cutSpan.end.ts, { zone: timezone, locale: accountStore.activeLocale }) - .toFormat("HH:mm") + .toFormat("HH:mm"), + isDayShift, ); } } @@ -594,10 +610,33 @@ const roleRows = computed(() => elements.value.roleRows); border-bottom: 1px solid var(--foreground); } -.break { +colgroup.break { background-color: color-mix(in oklab, var(--background), rgb(50, 50, 255) 60%); } +tr.hours>th:is(.break, :first-child) + th div { + visibility: hidden; +} + +tr.hours>th:first-child { + z-index: 1; +} +tr.hours>th + th:not(.break) { + overflow: visible; + padding-top: 0; + vertical-align: top; +} +tr.hours>th + th:not(.break) div { + font-variant-numeric: tabular-nums; + padding-top: 0.2rem; + background-color: Canvas; + translate: calc(-0.5 * var(--cell-size)) 0; +} +tr.hours>th + th.dayShift div { + padding-top: 0; + margin-top: 0.2rem; +} + .event, .shift { background-color: color-mix(in oklab, var(--background), rgb(255, 125, 50) 60%); }