-
Notifications
You must be signed in to change notification settings - Fork 2.2k
/
eventLevels.js
113 lines (97 loc) · 2.98 KB
/
eventLevels.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import findIndex from 'lodash/findIndex'
export function endOfRange({ dateRange, unit = 'day', localizer }) {
return {
first: dateRange[0],
last: localizer.add(dateRange[dateRange.length - 1], 1, unit),
}
}
// properly calculating segments requires working with dates in
// the timezone we're working with, so we use the localizer
export function eventSegments(event, range, accessors, localizer) {
let { first, last } = endOfRange({ dateRange: range, localizer })
let slots = localizer.diff(first, last, 'day')
let start = localizer.max(
localizer.startOf(accessors.start(event), 'day'),
first
)
let end = localizer.min(localizer.ceil(accessors.end(event), 'day'), last)
let padding = findIndex(range, (x) => localizer.isSameDate(x, start))
let span = localizer.diff(start, end, 'day')
span = Math.min(span, slots)
// The segmentOffset is necessary when adjusting for timezones
// ahead of the browser timezone
span = Math.max(span - localizer.segmentOffset, 1)
return {
event,
span,
left: padding + 1,
right: Math.max(padding + span, 1),
}
}
export function eventLevels(rowSegments, limit = Infinity) {
let i,
j,
seg,
levels = [],
extra = []
for (i = 0; i < rowSegments.length; i++) {
seg = rowSegments[i]
for (j = 0; j < levels.length; j++) if (!segsOverlap(seg, levels[j])) break
if (j >= limit) {
extra.push(seg)
} else {
;(levels[j] || (levels[j] = [])).push(seg)
}
}
for (i = 0; i < levels.length; i++) {
levels[i].sort((a, b) => a.left - b.left) //eslint-disable-line
}
return { levels, extra }
}
export function inRange(e, start, end, accessors, localizer) {
const event = {
start: accessors.start(e),
end: accessors.end(e),
}
const range = { start, end }
return localizer.inEventRange({ event, range })
}
export function segsOverlap(seg, otherSegs) {
return otherSegs.some(
(otherSeg) => otherSeg.left <= seg.right && otherSeg.right >= seg.left
)
}
export function sortWeekEvents(events, accessors, localizer) {
const base = [...events]
const multiDayEvents = []
const standardEvents = []
base.forEach((event) => {
const startCheck = accessors.start(event)
const endCheck = accessors.end(event)
if (localizer.daySpan(startCheck, endCheck) > 1) {
multiDayEvents.push(event)
} else {
standardEvents.push(event)
}
})
const multiSorted = multiDayEvents.sort((a, b) =>
sortEvents(a, b, accessors, localizer)
)
const standardSorted = standardEvents.sort((a, b) =>
sortEvents(a, b, accessors, localizer)
)
return [...multiSorted, ...standardSorted]
}
export function sortEvents(eventA, eventB, accessors, localizer) {
const evtA = {
start: accessors.start(eventA),
end: accessors.end(eventA),
allDay: accessors.allDay(eventA),
}
const evtB = {
start: accessors.start(eventB),
end: accessors.end(eventB),
allDay: accessors.allDay(eventB),
}
return localizer.sortEvents({ evtA, evtB })
}