init
This commit is contained in:
142
calendar/Week/WeekView.js
Normal file
142
calendar/Week/WeekView.js
Normal file
@@ -0,0 +1,142 @@
|
||||
import calendarUtil from "../calendarUtil.js"
|
||||
import "./SpacerCell.js"
|
||||
import "./TimedLabelsColumn.js"
|
||||
import "./TimedWeekGrid.js"
|
||||
import "./WeekHeaderRow.js"
|
||||
|
||||
css(`
|
||||
weekview- {
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
}
|
||||
|
||||
weekview- .VStack::-webkit-scrollbar {
|
||||
display: none;
|
||||
width: 0px;
|
||||
height: 0px;
|
||||
}
|
||||
|
||||
weekview- .VStack::-webkit-scrollbar-thumb {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
weekview- .VStack::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
`)
|
||||
|
||||
let _saved = null;
|
||||
|
||||
class WeekView extends Shadow {
|
||||
constructor(calendars, events, currentDate, weekStartsOn = 0, onSlotTap = null, onDayTap = null, isCenter = false) {
|
||||
super()
|
||||
this.calendars = calendars;
|
||||
this.events = events;
|
||||
this.currentDate = currentDate;
|
||||
this.weekStartsOn = weekStartsOn;
|
||||
this.onSlotTap = onSlotTap;
|
||||
this.onDayTap = onDayTap;
|
||||
this.isCenter = isCenter;
|
||||
this.slots = calendarUtil.generateTimeSlots({ stepMinutes: 30 });
|
||||
this.slotHeight = 2;
|
||||
this.sidebarWidth = 3;
|
||||
}
|
||||
|
||||
render() {
|
||||
ZStack(() => {
|
||||
const visibleWeekStart = calendarUtil.startOfWeek(this.currentDate, this.weekStartsOn);
|
||||
const weekDays = this.getWeekDays(visibleWeekStart);
|
||||
const groupedDays = this.groupEventsByWeekDay(
|
||||
this.filterEventsForWeek(this.events, weekDays),
|
||||
weekDays
|
||||
);
|
||||
const weekNumber = calendarUtil.getWeekNumber(visibleWeekStart);
|
||||
|
||||
VStack(() => {
|
||||
HStack(() => {
|
||||
SpacerCell(weekNumber, this.sidebarWidth)
|
||||
WeekHeaderRow(groupedDays, this.calendars, this.onDayTap)
|
||||
})
|
||||
.boxSizing("border-box")
|
||||
.position("sticky")
|
||||
.top(0)
|
||||
.width(100, pct)
|
||||
.zIndex(2)
|
||||
|
||||
HStack(() => {
|
||||
TimedLabelsColumn(this.slots, this.slotHeight, this.sidebarWidth)
|
||||
TimedWeekGrid(weekDays, this.slots, groupedDays, this.calendars, this.slotHeight, "week", this.onSlotTap)
|
||||
})
|
||||
.boxSizing("border-box")
|
||||
.onAppear(() => {
|
||||
// console.log("groupedDays:", groupedDays)
|
||||
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")
|
||||
}
|
||||
|
||||
getWeekDays(weekStart) {
|
||||
return Array.from({ length: 7 }, (_, i) => calendarUtil.addDays(weekStart, i));
|
||||
}
|
||||
|
||||
filterEventsForWeek(events, weekDays) {
|
||||
const rangeStart = calendarUtil.startOfDay(weekDays[0]);
|
||||
const rangeEnd = calendarUtil.endOfDay(weekDays[6]);
|
||||
const expanded = calendarUtil.expandRecurringEvents(events, rangeStart, rangeEnd);
|
||||
return expanded.filter(event => {
|
||||
const end = event.all_day ? calendarUtil.endOfDay(event.time_end) : calendarUtil.timedEnd(event);
|
||||
return weekDays.some(day => calendarUtil.rangesOverlap(
|
||||
event.time_start,
|
||||
end,
|
||||
calendarUtil.startOfDay(day),
|
||||
calendarUtil.endOfDay(day)
|
||||
) && this.calendars.some(c => event.calendars?.some(id => id === c.id)));
|
||||
});
|
||||
}
|
||||
|
||||
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(calendarUtil.startOfWeek(this.currentDate, this.weekStartsOn));
|
||||
this.scrollTop = (_saved?.dateKey === dateKey) ? _saved.scrollTop : defaultTarget;
|
||||
this.addEventListener('scroll', () => { _saved = { dateKey, scrollTop: this.scrollTop }; }, { passive: true });
|
||||
} else {
|
||||
this.scrollTop = defaultTarget;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
groupEventsByWeekDay(events, weekDays) {
|
||||
return weekDays.map(day => {
|
||||
const dayStart = calendarUtil.startOfDay(day);
|
||||
const dayEnd = calendarUtil.endOfDay(day)
|
||||
|
||||
return {
|
||||
day,
|
||||
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);
|
||||
})
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
register(WeekView)
|
||||
Reference in New Issue
Block a user