Calendar/src/utils/ColumnDetectionUtils.ts
Janus C. H. Knudsen d7867d4a9f Renders all-day events based on header data
Refactors all-day event rendering to use header column data.
This ensures events are rendered based on the actual visible
dates in the header, improving accuracy and responsiveness to view changes.

Removes direct dependency on week dates in `AllDayManager` and
`EventRenderingService`, instead, the all-day manager is instantiated
with event manager.

Updates `HeaderManager` to emit header bounds.
2025-10-01 21:27:13 +02:00

118 lines
No EOL
3.6 KiB
TypeScript

/**
* ColumnDetectionUtils - Shared utility for column detection and caching
* Used by both DragDropManager and AllDayManager for consistent column detection
*/
import { MousePosition } from "../types/DragDropTypes";
export interface ColumnBounds {
date: string;
left: number;
right: number;
boundingClientRect: DOMRect,
element : HTMLElement,
index: number
}
export class ColumnDetectionUtils {
private static columnBoundsCache: ColumnBounds[] = [];
/**
* Update column bounds cache for coordinate-based column detection
*/
public static updateColumnBoundsCache(): void {
// Reset cache
this.columnBoundsCache = [];
// Find alle kolonner
const columns = document.querySelectorAll('swp-day-column');
let index = 1;
// Cache hver kolonnes x-grænser
columns.forEach(column => {
const rect = column.getBoundingClientRect();
const date = (column as HTMLElement).dataset.date;
if (date) {
this.columnBoundsCache.push({
boundingClientRect : rect,
element: column as HTMLElement,
date,
left: rect.left,
right: rect.right,
index: index++
});
}
});
// Sorter efter x-position (fra venstre til højre)
this.columnBoundsCache.sort((a, b) => a.left - b.left);
}
/**
* Get column date from X coordinate using cached bounds
*/
public static getColumnBounds(position: MousePosition): ColumnBounds | null{
if (this.columnBoundsCache.length === 0) {
this.updateColumnBoundsCache();
}
// Find den kolonne hvor x-koordinaten er indenfor grænserne
let column = this.columnBoundsCache.find(col =>
position.x >= col.left && position.x <= col.right
);
if (column)
return column;
return null;
}
/**
* Get column bounds by Date
*/
public static getColumnBoundsByDate(date: Date): ColumnBounds | null {
if (this.columnBoundsCache.length === 0) {
this.updateColumnBoundsCache();
}
// Convert Date to YYYY-MM-DD format
var dateString = date.toISOString().split('T')[0];
// Find column that matches the date
var column = this.columnBoundsCache.find(col => col.date === dateString);
return column || null;
}
public static getColumns(): ColumnBounds[] {
return [...this.columnBoundsCache];
}
public static getHeaderColumns(): ColumnBounds[] {
let dayHeaders: ColumnBounds[] = [];
const dayColumns = document.querySelectorAll('swp-calendar-header swp-day-header');
let index = 1;
// Cache hver kolonnes x-grænser
dayColumns.forEach(column => {
const rect = column.getBoundingClientRect();
const date = (column as HTMLElement).dataset.date;
if (date) {
dayHeaders.push({
boundingClientRect : rect,
element: column as HTMLElement,
date,
left: rect.left,
right: rect.right,
index: index++
});
}
});
// Sorter efter x-position (fra venstre til højre)
dayHeaders.sort((a, b) => a.left - b.left);
return dayHeaders;
}
}