This commit is contained in:
mup 2025-10-17 14:25:18 +02:00
parent ca7746b0b6
commit 9a518eae42

View file

@ -102,9 +102,6 @@ export class TimeView implements Component<TimeViewAttributes> {
oncreate(vnode): any {
;(vnode.dom as HTMLElement).style.gridTemplateRows = `repeat(${subRowCount}, 1fr)`
},
// style: {
// "grid-template-columns": "repeat(8, 1fr)",
// }
},
[this.renderEvents(events, timeRange, subRowAsMinutes, subRowCount, timeScale, date, hasAnyConflict)],
)
@ -359,6 +356,15 @@ export class TimeView implements Component<TimeViewAttributes> {
* This ensures events that were blocked by shifted events can now expand properly
*/
private applyRetroactiveShifts(gridData: Map<Id, GridEventData>, allColumns: Array<ColumnData>): void {
// Cache conflict info to avoid redundant calculations
const conflictCache = new Map<
Id,
{
conflict: { distance: number; id: Id; gridStart: number } | undefined
sumOfSizes: number
}
>()
for (const [eventId, gridInfo] of gridData.entries()) {
const eventIndex = this.eventIdToOriginalColumnArrayIndex.get(eventId)
if (eventIndex == null) {
@ -367,14 +373,13 @@ export class TimeView implements Component<TimeViewAttributes> {
const expectedGridEnd = gridInfo.gridColumnStart + gridInfo.gridColumnEnd
let conflict:
| {
distance: number
id: string
gridStart: number
}
| undefined
// Check cache first to avoid redundant conflict finding
let cachedConflictInfo = conflictCache.get(eventId)
let conflict: { distance: number; id: Id; gridStart: number } | undefined
let sumOfSizes = 0
if (!cachedConflictInfo) {
// Find conflict and accumulate sizes - preserve original loop logic
for (let i = eventIndex + 1; i < allColumns.length; i++) {
const columnData = allColumns[i]
@ -390,14 +395,18 @@ export class TimeView implements Component<TimeViewAttributes> {
continue
}
for (const [conflictId, _] of overlappingEvents.entries()) {
// Optimization: Accumulate and find closest in single pass
for (const [conflictId] of overlappingEvents.entries()) {
const conflictInfo = gridData.get(conflictId)
if (!conflictInfo) {
continue
}
const distance = conflictInfo.gridColumnStart - expectedGridEnd
if (conflict?.distance == null || distance < conflict?.distance) {
sumOfSizes += conflictInfo.gridColumnEnd
// Find closest conflict (minimum distance)
if (!conflict || distance < conflict.distance) {
conflict = {
distance,
id: conflictId,
@ -407,24 +416,46 @@ export class TimeView implements Component<TimeViewAttributes> {
}
}
// Cache the result
cachedConflictInfo = { conflict, sumOfSizes }
conflictCache.set(eventId, cachedConflictInfo)
} else {
conflict = cachedConflictInfo.conflict
sumOfSizes = cachedConflictInfo.sumOfSizes
}
if (!conflict) {
// Maybe we should set to max here?
continue
}
if (expectedGridEnd < conflict.gridStart) {
const newSize = gridInfo.gridColumnEnd + conflict.distance
gridData.set(eventId, {
...gridInfo,
gridColumnEnd:
gridInfo.gridColumnStart + newSize > allColumns.length + 1
let newSize: number | null = null
// Case 1: Already exceeds grid bounds
if (gridInfo.gridColumnStart + gridInfo.gridColumnEnd > allColumns.length) {
newSize = Math.max(allColumns.length - gridInfo.gridColumnStart, BASE_EVENT_BUBBLE_SPAN_SIZE)
}
// Case 2: Can expand (no overlap)
else if (expectedGridEnd < conflict.gridStart) {
const expandedSize = gridInfo.gridColumnEnd + conflict.distance
newSize =
gridInfo.gridColumnStart + expandedSize > allColumns.length
? Math.max(allColumns.length - gridInfo.gridColumnStart, BASE_EVENT_BUBBLE_SPAN_SIZE)
: newSize,
})
} else if (expectedGridEnd > conflict.gridStart) {
: expandedSize
}
// Case 3: Must shrink (overlap detected)
else if (expectedGridEnd > conflict.gridStart) {
const shrinkSize = conflict.gridStart - 1
newSize =
gridInfo.gridColumnStart + shrinkSize + sumOfSizes > allColumns.length
? Math.max(allColumns.length - gridInfo.gridColumnStart, BASE_EVENT_BUBBLE_SPAN_SIZE)
: shrinkSize
}
// Only update if size changed
if (newSize !== null && newSize !== gridInfo.gridColumnEnd) {
gridData.set(eventId, {
...gridInfo,
gridColumnEnd: conflict.gridStart - 1,
gridColumnEnd: newSize,
})
}
}