125 lines
4.3 KiB
JavaScript
125 lines
4.3 KiB
JavaScript
import calendarUtil from "../calendarUtil.js"
|
|
import "../Week/SpacerCell.js"
|
|
import "../Week/TimedLabelsColumn.js"
|
|
import "../Week/TimedWeekGrid.js"
|
|
import "./DayHeaderRow.js"
|
|
|
|
css(`
|
|
dayview- {
|
|
scrollbar-width: none;
|
|
-ms-overflow-style: none;
|
|
}
|
|
|
|
dayview- .VStack::-webkit-scrollbar {
|
|
display: none;
|
|
width: 0px;
|
|
height: 0px;
|
|
}
|
|
|
|
dayview- .VStack::-webkit-scrollbar-thumb {
|
|
background: transparent;
|
|
}
|
|
|
|
dayview- .VStack::-webkit-scrollbar-track {
|
|
background: transparent;
|
|
}
|
|
`)
|
|
|
|
let _saved = null;
|
|
|
|
class DayView extends Shadow {
|
|
constructor(calendars, events, currentDate, onSlotTap = null, isCenter = false) {
|
|
super()
|
|
this.calendars = calendars;
|
|
this.events = events;
|
|
this.currentDate = currentDate;
|
|
this.onSlotTap = onSlotTap;
|
|
this.isCenter = isCenter;
|
|
this.slots = calendarUtil.generateTimeSlots({ stepMinutes: 30 });
|
|
this.slotHeight = 2;
|
|
this.sidebarWidth = 3;
|
|
}
|
|
|
|
render() {
|
|
ZStack(() => {
|
|
const filteredEvents = this.filterEventsForDay(this.events);
|
|
const groupedDay = this.groupEventsForDay(filteredEvents);
|
|
const weekNumber = calendarUtil.getWeekNumber(this.currentDate);
|
|
|
|
VStack(() => {
|
|
HStack(() => {
|
|
SpacerCell(weekNumber, this.sidebarWidth)
|
|
DayHeaderRow(groupedDay, this.calendars)
|
|
})
|
|
.boxSizing("border-box")
|
|
.position("sticky")
|
|
.top(0)
|
|
.width(100, pct)
|
|
.zIndex(2)
|
|
|
|
HStack(() => {
|
|
TimedLabelsColumn(this.slots, this.slotHeight, this.sidebarWidth)
|
|
TimedWeekGrid([groupedDay], this.slots, [groupedDay], this.calendars, this.slotHeight, "day", this.onSlotTap)
|
|
})
|
|
.boxSizing("border-box")
|
|
.onAppear(() => {
|
|
this.scrollToEight();
|
|
})
|
|
})
|
|
})
|
|
.position("relative")
|
|
.gap(1, em)
|
|
.boxSizing("border-box")
|
|
.width(100, pct)
|
|
.height(100, pct)
|
|
.fontSize(0.9, em)
|
|
.overscrollBehavior("none")
|
|
.overflowY("scroll")
|
|
.display("block")
|
|
}
|
|
|
|
filterEventsForDay(events) {
|
|
const dayStart = calendarUtil.startOfDay(this.currentDate);
|
|
const dayEnd = calendarUtil.endOfDay(this.currentDate);
|
|
const expanded = calendarUtil.expandRecurringEvents(events, dayStart, dayEnd);
|
|
return expanded.filter(event => {
|
|
const end = event.all_day ? calendarUtil.endOfDay(event.time_end) : calendarUtil.timedEnd(event);
|
|
return calendarUtil.rangesOverlap(event.time_start, end, dayStart, dayEnd)
|
|
&& this.calendars.some(c => event.calendars.some(c2 => c2 === c.id));
|
|
});
|
|
}
|
|
|
|
groupEventsForDay(events) {
|
|
const dayStart = calendarUtil.startOfDay(this.currentDate);
|
|
const dayEnd = calendarUtil.endOfDay(this.currentDate);
|
|
return {
|
|
day: this.currentDate,
|
|
allDay: events.filter(event => {
|
|
if (!event.all_day) return false;
|
|
const end = calendarUtil.endOfDay(event.time_end);
|
|
return calendarUtil.rangesOverlap(event.time_start, end, dayStart, dayEnd);
|
|
}),
|
|
timed: events.filter(event => {
|
|
return !event.all_day && calendarUtil.rangesOverlap(event.time_start, calendarUtil.timedEnd(event), dayStart, dayEnd);
|
|
})
|
|
};
|
|
}
|
|
|
|
scrollToEight() {
|
|
requestAnimationFrame(() => {
|
|
const fs = parseFloat(getComputedStyle(this).fontSize);
|
|
const slotsBeforeEight = this.slots.findIndex(s => s.hour24 === 8 && s.minute === 0);
|
|
const defaultTarget = slotsBeforeEight * this.slotHeight * fs;
|
|
if (this.isCenter) {
|
|
const dateKey = calendarUtil.toDateInput(this.currentDate);
|
|
this.scrollTop = (_saved?.dateKey === dateKey) ? _saved.scrollTop : defaultTarget;
|
|
this.addEventListener('scroll', () => { _saved = { dateKey, scrollTop: this.scrollTop }; }, { passive: true });
|
|
} else {
|
|
this.scrollTop = defaultTarget;
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
register(DayView)
|