diff --git a/components/Timetable.vue b/components/Timetable.vue
index da17b6a..21a5a15 100644
--- a/components/Timetable.vue
+++ b/components/Timetable.vue
@@ -68,6 +68,20 @@
+
+ |
+
+
+ |
+
{{ location.name }} |
@@ -364,7 +378,8 @@ function tableElementsFromStretches(
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[] }[] = [];
+ type ColumnGroup = { start: number, end: number, width: number, className?: string, cols: Col[] };
+ const columnGroups: ColumnGroup[] = [];
const dayHeaders: DayHead[] = [];
const hourHeaders: HourHead[]= [];
const locationRows = new Map([...locations.keys()].map(id => [id, []]));
@@ -373,8 +388,8 @@ function tableElementsFromStretches(
const shiftBySlotId = new Map([...shifts.values()].flatMap?.(shift => [...shift.slots.values()].map(slot =>[slot.id, shift])));
let totalColumns = 0;
- function startColumnGroup(className?: string) {
- columnGroups.push({ className, cols: []})
+ function startColumnGroup(start: number, end: number, width: number, className?: string) {
+ columnGroups.push({ start, end, width, className, cols: []})
}
function startDay(isBreak: boolean, content?: string) {
dayHeaders.push({ span: 0, isBreak, content })
@@ -414,13 +429,12 @@ function tableElementsFromStretches(
}
}
- let first = true;
+ let lastStretch: Stretch | undefined;
for (let stretch of stretches) {
stretch = padStretch(stretch, timezone);
const startDate = DateTime.fromMillis(stretch.start, { zone: timezone, locale: accountStore.activeLocale });
- if (first) {
- first = false;
- startColumnGroup();
+ if (!lastStretch) {
+ startColumnGroup(stretch.start, stretch.end, (stretch.end - stretch.start) / oneHourMs);
startDay(false, startDate.toFormat("yyyy-LL-dd"));
startHour(false, startDate.toFormat("HH:mm"));
for(const location of locations.values()) {
@@ -430,7 +444,7 @@ function tableElementsFromStretches(
startRole(role.id);
}
} else {
- startColumnGroup("break");
+ startColumnGroup(lastStretch.end, stretch.start, 1, "break");
const dayName = startDate.toFormat("yyyy-LL-dd");
const lastDayHeader = dayHeaders[dayHeaders.length - 1]
const sameDay = dayName === lastDayHeader.content && lastDayHeader.span;
@@ -445,7 +459,7 @@ function tableElementsFromStretches(
}
pushColumn();
- startColumnGroup();
+ startColumnGroup(stretch.start, stretch.end, (stretch.end - stretch.start) / oneHourMs);
if (!sameDay)
startDay(false, dayName);
startHour(false, startDate.toFormat("HH:mm"));
@@ -499,6 +513,8 @@ function tableElementsFromStretches(
}
}
}
+
+ lastStretch = stretch;
}
return {
@@ -565,6 +581,28 @@ const dayHeaders = computed(() => elements.value.dayHeaders);
const hourHeaders = computed(() => elements.value.hourHeaders);
const locationRows = computed(() => elements.value.locationRows);
const roleRows = computed(() => elements.value.roleRows);
+
+const now = useState(() => Math.round(Date.now() / oneMinMs) * oneMinMs);
+const interval = ref();
+onMounted(() => {
+ interval.value = setInterval(() => {
+ const newNow = Math.round(Date.now() / oneMinMs) * oneMinMs;
+ if (now.value !== newNow)
+ now.value = newNow;
+ }, 1000);
+});
+onUnmounted(() => {
+ clearInterval(interval.value);
+});
+const nowOffset = computed(() => {
+ let offset = 0;
+ for (let group of columnGroups.value) {
+ if (group.start <= now.value && now.value < group.end) {
+ return offset + (now.value - group.start) / (group.end - group.start) * group.width;
+ }
+ offset += group.width;
+ }
+});