Refactors all-day event layout calculation
Simplifies all-day event rendering by streamlining the layout calculation and event placement process, using the AllDayLayoutEngine to determine the grid positions. This removes deprecated methods and improves overall code clarity.
This commit is contained in:
parent
9dfd4574d8
commit
4141bffca4
7 changed files with 76 additions and 321 deletions
|
|
@ -1,7 +1,7 @@
|
|||
import { CalendarEvent } from '../types/CalendarTypes';
|
||||
|
||||
export interface EventLayout {
|
||||
id: string;
|
||||
calenderEvent: CalendarEvent;
|
||||
gridArea: string; // "row-start / col-start / row-end / col-end"
|
||||
startColumn: number;
|
||||
endColumn: number;
|
||||
|
|
@ -21,42 +21,38 @@ export class AllDayLayoutEngine {
|
|||
/**
|
||||
* Calculate layout for all events using clean day-based logic
|
||||
*/
|
||||
public calculateLayout(events: CalendarEvent[]): Map<string, EventLayout> {
|
||||
const layouts = new Map<string, EventLayout>();
|
||||
|
||||
if (this.weekDates.length === 0) {
|
||||
return layouts;
|
||||
}
|
||||
public calculateLayout(events: CalendarEvent[]): EventLayout[] {
|
||||
|
||||
let layouts: EventLayout[] = [];
|
||||
// Reset tracks for new calculation
|
||||
this.tracks = [new Array(this.weekDates.length).fill(false)];
|
||||
|
||||
|
||||
// Filter to only visible events
|
||||
const visibleEvents = events.filter(event => this.isEventVisible(event));
|
||||
|
||||
|
||||
// Process events in input order (no sorting)
|
||||
for (const event of visibleEvents) {
|
||||
const startDay = this.getEventStartDay(event);
|
||||
const endDay = this.getEventEndDay(event);
|
||||
|
||||
|
||||
if (startDay > 0 && endDay > 0) {
|
||||
const track = this.findAvailableTrack(startDay - 1, endDay - 1); // Convert to 0-based for tracks
|
||||
|
||||
|
||||
// Mark days as occupied
|
||||
for (let day = startDay - 1; day <= endDay - 1; day++) {
|
||||
this.tracks[track][day] = true;
|
||||
}
|
||||
|
||||
|
||||
const layout: EventLayout = {
|
||||
id: event.id,
|
||||
calenderEvent: event,
|
||||
gridArea: `${track + 1} / ${startDay} / ${track + 2} / ${endDay + 1}`,
|
||||
startColumn: startDay,
|
||||
endColumn: endDay,
|
||||
row: track + 1,
|
||||
columnSpan: endDay - startDay + 1
|
||||
};
|
||||
|
||||
layouts.set(event.id, layout);
|
||||
layouts.push(layout);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -72,7 +68,7 @@ export class AllDayLayoutEngine {
|
|||
return trackIndex;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Create new track if none available
|
||||
this.tracks.push(new Array(this.weekDates.length).fill(false));
|
||||
return this.tracks.length - 1;
|
||||
|
|
@ -96,10 +92,10 @@ export class AllDayLayoutEngine {
|
|||
private getEventStartDay(event: CalendarEvent): number {
|
||||
const eventStartDate = this.formatDate(event.start);
|
||||
const firstVisibleDate = this.weekDates[0];
|
||||
|
||||
|
||||
// If event starts before visible range, clip to first visible day
|
||||
const clippedStartDate = eventStartDate < firstVisibleDate ? firstVisibleDate : eventStartDate;
|
||||
|
||||
|
||||
const dayIndex = this.weekDates.indexOf(clippedStartDate);
|
||||
return dayIndex >= 0 ? dayIndex + 1 : 0;
|
||||
}
|
||||
|
|
@ -110,10 +106,10 @@ export class AllDayLayoutEngine {
|
|||
private getEventEndDay(event: CalendarEvent): number {
|
||||
const eventEndDate = this.formatDate(event.end);
|
||||
const lastVisibleDate = this.weekDates[this.weekDates.length - 1];
|
||||
|
||||
|
||||
// If event ends after visible range, clip to last visible day
|
||||
const clippedEndDate = eventEndDate > lastVisibleDate ? lastVisibleDate : eventEndDate;
|
||||
|
||||
|
||||
const dayIndex = this.weekDates.indexOf(clippedEndDate);
|
||||
return dayIndex >= 0 ? dayIndex + 1 : 0;
|
||||
}
|
||||
|
|
@ -123,12 +119,12 @@ export class AllDayLayoutEngine {
|
|||
*/
|
||||
private isEventVisible(event: CalendarEvent): boolean {
|
||||
if (this.weekDates.length === 0) return false;
|
||||
|
||||
|
||||
const eventStartDate = this.formatDate(event.start);
|
||||
const eventEndDate = this.formatDate(event.end);
|
||||
const firstVisibleDate = this.weekDates[0];
|
||||
const lastVisibleDate = this.weekDates[this.weekDates.length - 1];
|
||||
|
||||
|
||||
// Event overlaps if it doesn't end before visible range starts
|
||||
// AND doesn't start after visible range ends
|
||||
return !(eventEndDate < firstVisibleDate || eventStartDate > lastVisibleDate);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue