提交 | 用户 | 时间
|
71e81e
|
1 |
/*! |
懒 |
2 |
FullCalendar Time Grid Plugin v4.3.0 |
|
3 |
Docs & License: https://fullcalendar.io/ |
|
4 |
(c) 2019 Adam Shaw |
|
5 |
*/ |
|
6 |
|
|
7 |
(function (global, factory) { |
|
8 |
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@fullcalendar/core'), require('@fullcalendar/daygrid')) : |
|
9 |
typeof define === 'function' && define.amd ? define(['exports', '@fullcalendar/core', '@fullcalendar/daygrid'], factory) : |
|
10 |
(global = global || self, factory(global.FullCalendarTimeGrid = {}, global.FullCalendar, global.FullCalendarDayGrid)); |
|
11 |
}(this, function (exports, core, daygrid) { 'use strict'; |
|
12 |
|
|
13 |
/*! ***************************************************************************** |
|
14 |
Copyright (c) Microsoft Corporation. All rights reserved. |
|
15 |
Licensed under the Apache License, Version 2.0 (the "License"); you may not use |
|
16 |
this file except in compliance with the License. You may obtain a copy of the |
|
17 |
License at http://www.apache.org/licenses/LICENSE-2.0 |
|
18 |
|
|
19 |
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
|
20 |
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED |
|
21 |
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, |
|
22 |
MERCHANTABLITY OR NON-INFRINGEMENT. |
|
23 |
|
|
24 |
See the Apache Version 2.0 License for specific language governing permissions |
|
25 |
and limitations under the License. |
|
26 |
***************************************************************************** */ |
|
27 |
/* global Reflect, Promise */ |
|
28 |
|
|
29 |
var extendStatics = function(d, b) { |
|
30 |
extendStatics = Object.setPrototypeOf || |
|
31 |
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || |
|
32 |
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; |
|
33 |
return extendStatics(d, b); |
|
34 |
}; |
|
35 |
|
|
36 |
function __extends(d, b) { |
|
37 |
extendStatics(d, b); |
|
38 |
function __() { this.constructor = d; } |
|
39 |
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); |
|
40 |
} |
|
41 |
|
|
42 |
var __assign = function() { |
|
43 |
__assign = Object.assign || function __assign(t) { |
|
44 |
for (var s, i = 1, n = arguments.length; i < n; i++) { |
|
45 |
s = arguments[i]; |
|
46 |
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; |
|
47 |
} |
|
48 |
return t; |
|
49 |
}; |
|
50 |
return __assign.apply(this, arguments); |
|
51 |
}; |
|
52 |
|
|
53 |
/* |
|
54 |
Only handles foreground segs. |
|
55 |
Does not own rendering. Use for low-level util methods by TimeGrid. |
|
56 |
*/ |
|
57 |
var TimeGridEventRenderer = /** @class */ (function (_super) { |
|
58 |
__extends(TimeGridEventRenderer, _super); |
|
59 |
function TimeGridEventRenderer(timeGrid) { |
|
60 |
var _this = _super.call(this, timeGrid.context) || this; |
|
61 |
_this.timeGrid = timeGrid; |
|
62 |
_this.fullTimeFormat = core.createFormatter({ |
|
63 |
hour: 'numeric', |
|
64 |
minute: '2-digit', |
|
65 |
separator: _this.context.options.defaultRangeSeparator |
|
66 |
}); |
|
67 |
return _this; |
|
68 |
} |
|
69 |
// Given an array of foreground segments, render a DOM element for each, computes position, |
|
70 |
// and attaches to the column inner-container elements. |
|
71 |
TimeGridEventRenderer.prototype.attachSegs = function (segs, mirrorInfo) { |
|
72 |
var segsByCol = this.timeGrid.groupSegsByCol(segs); |
|
73 |
// order the segs within each column |
|
74 |
// TODO: have groupSegsByCol do this? |
|
75 |
for (var col = 0; col < segsByCol.length; col++) { |
|
76 |
segsByCol[col] = this.sortEventSegs(segsByCol[col]); |
|
77 |
} |
|
78 |
this.segsByCol = segsByCol; |
|
79 |
this.timeGrid.attachSegsByCol(segsByCol, this.timeGrid.fgContainerEls); |
|
80 |
}; |
|
81 |
TimeGridEventRenderer.prototype.detachSegs = function (segs) { |
|
82 |
segs.forEach(function (seg) { |
|
83 |
core.removeElement(seg.el); |
|
84 |
}); |
|
85 |
this.segsByCol = null; |
|
86 |
}; |
|
87 |
TimeGridEventRenderer.prototype.computeSegSizes = function (allSegs) { |
|
88 |
var _a = this, timeGrid = _a.timeGrid, segsByCol = _a.segsByCol; |
|
89 |
var colCnt = timeGrid.colCnt; |
|
90 |
timeGrid.computeSegVerticals(allSegs); // horizontals relies on this |
|
91 |
if (segsByCol) { |
|
92 |
for (var col = 0; col < colCnt; col++) { |
|
93 |
this.computeSegHorizontals(segsByCol[col]); // compute horizontal coordinates, z-index's, and reorder the array |
|
94 |
} |
|
95 |
} |
|
96 |
}; |
|
97 |
TimeGridEventRenderer.prototype.assignSegSizes = function (allSegs) { |
|
98 |
var _a = this, timeGrid = _a.timeGrid, segsByCol = _a.segsByCol; |
|
99 |
var colCnt = timeGrid.colCnt; |
|
100 |
timeGrid.assignSegVerticals(allSegs); // horizontals relies on this |
|
101 |
if (segsByCol) { |
|
102 |
for (var col = 0; col < colCnt; col++) { |
|
103 |
this.assignSegCss(segsByCol[col]); |
|
104 |
} |
|
105 |
} |
|
106 |
}; |
|
107 |
// Computes a default event time formatting string if `eventTimeFormat` is not explicitly defined |
|
108 |
TimeGridEventRenderer.prototype.computeEventTimeFormat = function () { |
|
109 |
return { |
|
110 |
hour: 'numeric', |
|
111 |
minute: '2-digit', |
|
112 |
meridiem: false |
|
113 |
}; |
|
114 |
}; |
|
115 |
// Computes a default `displayEventEnd` value if one is not expliclty defined |
|
116 |
TimeGridEventRenderer.prototype.computeDisplayEventEnd = function () { |
|
117 |
return true; |
|
118 |
}; |
|
119 |
// Renders the HTML for a single event segment's default rendering |
|
120 |
TimeGridEventRenderer.prototype.renderSegHtml = function (seg, mirrorInfo) { |
|
121 |
var view = this.context.view; |
|
122 |
var eventRange = seg.eventRange; |
|
123 |
var eventDef = eventRange.def; |
|
124 |
var eventUi = eventRange.ui; |
|
125 |
var allDay = eventDef.allDay; |
|
126 |
var isDraggable = view.computeEventDraggable(eventDef, eventUi); |
|
127 |
var isResizableFromStart = seg.isStart && view.computeEventStartResizable(eventDef, eventUi); |
|
128 |
var isResizableFromEnd = seg.isEnd && view.computeEventEndResizable(eventDef, eventUi); |
|
129 |
var classes = this.getSegClasses(seg, isDraggable, isResizableFromStart || isResizableFromEnd, mirrorInfo); |
|
130 |
var skinCss = core.cssToStr(this.getSkinCss(eventUi)); |
|
131 |
var timeText; |
|
132 |
var fullTimeText; // more verbose time text. for the print stylesheet |
|
133 |
var startTimeText; // just the start time text |
|
134 |
classes.unshift('fc-time-grid-event'); |
|
135 |
// if the event appears to span more than one day... |
|
136 |
if (core.isMultiDayRange(eventRange.range)) { |
|
137 |
// Don't display time text on segments that run entirely through a day. |
|
138 |
// That would appear as midnight-midnight and would look dumb. |
|
139 |
// Otherwise, display the time text for the *segment's* times (like 6pm-midnight or midnight-10am) |
|
140 |
if (seg.isStart || seg.isEnd) { |
|
141 |
var unzonedStart = seg.start; |
|
142 |
var unzonedEnd = seg.end; |
|
143 |
timeText = this._getTimeText(unzonedStart, unzonedEnd, allDay); // TODO: give the timezones |
|
144 |
fullTimeText = this._getTimeText(unzonedStart, unzonedEnd, allDay, this.fullTimeFormat); |
|
145 |
startTimeText = this._getTimeText(unzonedStart, unzonedEnd, allDay, null, false); // displayEnd=false |
|
146 |
} |
|
147 |
} |
|
148 |
else { |
|
149 |
// Display the normal time text for the *event's* times |
|
150 |
timeText = this.getTimeText(eventRange); |
|
151 |
fullTimeText = this.getTimeText(eventRange, this.fullTimeFormat); |
|
152 |
startTimeText = this.getTimeText(eventRange, null, false); // displayEnd=false |
|
153 |
} |
|
154 |
return '<a class="' + classes.join(' ') + '"' + |
|
155 |
(eventDef.url ? |
|
156 |
' href="' + core.htmlEscape(eventDef.url) + '"' : |
|
157 |
'') + |
|
158 |
(skinCss ? |
|
159 |
' style="' + skinCss + '"' : |
|
160 |
'') + |
|
161 |
'>' + |
|
162 |
'<div class="fc-content">' + |
|
163 |
(timeText ? |
|
164 |
'<div class="fc-time"' + |
|
165 |
' data-start="' + core.htmlEscape(startTimeText) + '"' + |
|
166 |
' data-full="' + core.htmlEscape(fullTimeText) + '"' + |
|
167 |
'>' + |
|
168 |
'<span>' + core.htmlEscape(timeText) + '</span>' + |
|
169 |
'</div>' : |
|
170 |
'') + |
|
171 |
(eventDef.title ? |
|
172 |
'<div class="fc-title">' + |
|
173 |
core.htmlEscape(eventDef.title) + |
|
174 |
'</div>' : |
|
175 |
'') + |
|
176 |
'</div>' + |
|
177 |
/* TODO: write CSS for this |
|
178 |
(isResizableFromStart ? |
|
179 |
'<div class="fc-resizer fc-start-resizer"></div>' : |
|
180 |
'' |
|
181 |
) + |
|
182 |
*/ |
|
183 |
(isResizableFromEnd ? |
|
184 |
'<div class="fc-resizer fc-end-resizer"></div>' : |
|
185 |
'') + |
|
186 |
'</a>'; |
|
187 |
}; |
|
188 |
// Given an array of segments that are all in the same column, sets the backwardCoord and forwardCoord on each. |
|
189 |
// Assumed the segs are already ordered. |
|
190 |
// NOTE: Also reorders the given array by date! |
|
191 |
TimeGridEventRenderer.prototype.computeSegHorizontals = function (segs) { |
|
192 |
var levels; |
|
193 |
var level0; |
|
194 |
var i; |
|
195 |
levels = buildSlotSegLevels(segs); |
|
196 |
computeForwardSlotSegs(levels); |
|
197 |
if ((level0 = levels[0])) { |
|
198 |
for (i = 0; i < level0.length; i++) { |
|
199 |
computeSlotSegPressures(level0[i]); |
|
200 |
} |
|
201 |
for (i = 0; i < level0.length; i++) { |
|
202 |
this.computeSegForwardBack(level0[i], 0, 0); |
|
203 |
} |
|
204 |
} |
|
205 |
}; |
|
206 |
// Calculate seg.forwardCoord and seg.backwardCoord for the segment, where both values range |
|
207 |
// from 0 to 1. If the calendar is left-to-right, the seg.backwardCoord maps to "left" and |
|
208 |
// seg.forwardCoord maps to "right" (via percentage). Vice-versa if the calendar is right-to-left. |
|
209 |
// |
|
210 |
// The segment might be part of a "series", which means consecutive segments with the same pressure |
|
211 |
// who's width is unknown until an edge has been hit. `seriesBackwardPressure` is the number of |
|
212 |
// segments behind this one in the current series, and `seriesBackwardCoord` is the starting |
|
213 |
// coordinate of the first segment in the series. |
|
214 |
TimeGridEventRenderer.prototype.computeSegForwardBack = function (seg, seriesBackwardPressure, seriesBackwardCoord) { |
|
215 |
var forwardSegs = seg.forwardSegs; |
|
216 |
var i; |
|
217 |
if (seg.forwardCoord === undefined) { // not already computed |
|
218 |
if (!forwardSegs.length) { |
|
219 |
// if there are no forward segments, this segment should butt up against the edge |
|
220 |
seg.forwardCoord = 1; |
|
221 |
} |
|
222 |
else { |
|
223 |
// sort highest pressure first |
|
224 |
this.sortForwardSegs(forwardSegs); |
|
225 |
// this segment's forwardCoord will be calculated from the backwardCoord of the |
|
226 |
// highest-pressure forward segment. |
|
227 |
this.computeSegForwardBack(forwardSegs[0], seriesBackwardPressure + 1, seriesBackwardCoord); |
|
228 |
seg.forwardCoord = forwardSegs[0].backwardCoord; |
|
229 |
} |
|
230 |
// calculate the backwardCoord from the forwardCoord. consider the series |
|
231 |
seg.backwardCoord = seg.forwardCoord - |
|
232 |
(seg.forwardCoord - seriesBackwardCoord) / // available width for series |
|
233 |
(seriesBackwardPressure + 1); // # of segments in the series |
|
234 |
// use this segment's coordinates to computed the coordinates of the less-pressurized |
|
235 |
// forward segments |
|
236 |
for (i = 0; i < forwardSegs.length; i++) { |
|
237 |
this.computeSegForwardBack(forwardSegs[i], 0, seg.forwardCoord); |
|
238 |
} |
|
239 |
} |
|
240 |
}; |
|
241 |
TimeGridEventRenderer.prototype.sortForwardSegs = function (forwardSegs) { |
|
242 |
var objs = forwardSegs.map(buildTimeGridSegCompareObj); |
|
243 |
var specs = [ |
|
244 |
// put higher-pressure first |
|
245 |
{ field: 'forwardPressure', order: -1 }, |
|
246 |
// put segments that are closer to initial edge first (and favor ones with no coords yet) |
|
247 |
{ field: 'backwardCoord', order: 1 } |
|
248 |
].concat(this.context.view.eventOrderSpecs); |
|
249 |
objs.sort(function (obj0, obj1) { |
|
250 |
return core.compareByFieldSpecs(obj0, obj1, specs); |
|
251 |
}); |
|
252 |
return objs.map(function (c) { |
|
253 |
return c._seg; |
|
254 |
}); |
|
255 |
}; |
|
256 |
// Given foreground event segments that have already had their position coordinates computed, |
|
257 |
// assigns position-related CSS values to their elements. |
|
258 |
TimeGridEventRenderer.prototype.assignSegCss = function (segs) { |
|
259 |
for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) { |
|
260 |
var seg = segs_1[_i]; |
|
261 |
core.applyStyle(seg.el, this.generateSegCss(seg)); |
|
262 |
if (seg.level > 0) { |
|
263 |
seg.el.classList.add('fc-time-grid-event-inset'); |
|
264 |
} |
|
265 |
// if the event is short that the title will be cut off, |
|
266 |
// attach a className that condenses the title into the time area. |
|
267 |
if (seg.eventRange.def.title && seg.bottom - seg.top < 30) { |
|
268 |
seg.el.classList.add('fc-short'); // TODO: "condensed" is a better name |
|
269 |
} |
|
270 |
} |
|
271 |
}; |
|
272 |
// Generates an object with CSS properties/values that should be applied to an event segment element. |
|
273 |
// Contains important positioning-related properties that should be applied to any event element, customized or not. |
|
274 |
TimeGridEventRenderer.prototype.generateSegCss = function (seg) { |
|
275 |
var shouldOverlap = this.context.options.slotEventOverlap; |
|
276 |
var backwardCoord = seg.backwardCoord; // the left side if LTR. the right side if RTL. floating-point |
|
277 |
var forwardCoord = seg.forwardCoord; // the right side if LTR. the left side if RTL. floating-point |
|
278 |
var props = this.timeGrid.generateSegVerticalCss(seg); // get top/bottom first |
|
279 |
var isRtl = this.timeGrid.isRtl; |
|
280 |
var left; // amount of space from left edge, a fraction of the total width |
|
281 |
var right; // amount of space from right edge, a fraction of the total width |
|
282 |
if (shouldOverlap) { |
|
283 |
// double the width, but don't go beyond the maximum forward coordinate (1.0) |
|
284 |
forwardCoord = Math.min(1, backwardCoord + (forwardCoord - backwardCoord) * 2); |
|
285 |
} |
|
286 |
if (isRtl) { |
|
287 |
left = 1 - forwardCoord; |
|
288 |
right = backwardCoord; |
|
289 |
} |
|
290 |
else { |
|
291 |
left = backwardCoord; |
|
292 |
right = 1 - forwardCoord; |
|
293 |
} |
|
294 |
props.zIndex = seg.level + 1; // convert from 0-base to 1-based |
|
295 |
props.left = left * 100 + '%'; |
|
296 |
props.right = right * 100 + '%'; |
|
297 |
if (shouldOverlap && seg.forwardPressure) { |
|
298 |
// add padding to the edge so that forward stacked events don't cover the resizer's icon |
|
299 |
props[isRtl ? 'marginLeft' : 'marginRight'] = 10 * 2; // 10 is a guesstimate of the icon's width |
|
300 |
} |
|
301 |
return props; |
|
302 |
}; |
|
303 |
return TimeGridEventRenderer; |
|
304 |
}(core.FgEventRenderer)); |
|
305 |
// Builds an array of segments "levels". The first level will be the leftmost tier of segments if the calendar is |
|
306 |
// left-to-right, or the rightmost if the calendar is right-to-left. Assumes the segments are already ordered by date. |
|
307 |
function buildSlotSegLevels(segs) { |
|
308 |
var levels = []; |
|
309 |
var i; |
|
310 |
var seg; |
|
311 |
var j; |
|
312 |
for (i = 0; i < segs.length; i++) { |
|
313 |
seg = segs[i]; |
|
314 |
// go through all the levels and stop on the first level where there are no collisions |
|
315 |
for (j = 0; j < levels.length; j++) { |
|
316 |
if (!computeSlotSegCollisions(seg, levels[j]).length) { |
|
317 |
break; |
|
318 |
} |
|
319 |
} |
|
320 |
seg.level = j; |
|
321 |
(levels[j] || (levels[j] = [])).push(seg); |
|
322 |
} |
|
323 |
return levels; |
|
324 |
} |
|
325 |
// For every segment, figure out the other segments that are in subsequent |
|
326 |
// levels that also occupy the same vertical space. Accumulate in seg.forwardSegs |
|
327 |
function computeForwardSlotSegs(levels) { |
|
328 |
var i; |
|
329 |
var level; |
|
330 |
var j; |
|
331 |
var seg; |
|
332 |
var k; |
|
333 |
for (i = 0; i < levels.length; i++) { |
|
334 |
level = levels[i]; |
|
335 |
for (j = 0; j < level.length; j++) { |
|
336 |
seg = level[j]; |
|
337 |
seg.forwardSegs = []; |
|
338 |
for (k = i + 1; k < levels.length; k++) { |
|
339 |
computeSlotSegCollisions(seg, levels[k], seg.forwardSegs); |
|
340 |
} |
|
341 |
} |
|
342 |
} |
|
343 |
} |
|
344 |
// Figure out which path forward (via seg.forwardSegs) results in the longest path until |
|
345 |
// the furthest edge is reached. The number of segments in this path will be seg.forwardPressure |
|
346 |
function computeSlotSegPressures(seg) { |
|
347 |
var forwardSegs = seg.forwardSegs; |
|
348 |
var forwardPressure = 0; |
|
349 |
var i; |
|
350 |
var forwardSeg; |
|
351 |
if (seg.forwardPressure === undefined) { // not already computed |
|
352 |
for (i = 0; i < forwardSegs.length; i++) { |
|
353 |
forwardSeg = forwardSegs[i]; |
|
354 |
// figure out the child's maximum forward path |
|
355 |
computeSlotSegPressures(forwardSeg); |
|
356 |
// either use the existing maximum, or use the child's forward pressure |
|
357 |
// plus one (for the forwardSeg itself) |
|
358 |
forwardPressure = Math.max(forwardPressure, 1 + forwardSeg.forwardPressure); |
|
359 |
} |
|
360 |
seg.forwardPressure = forwardPressure; |
|
361 |
} |
|
362 |
} |
|
363 |
// Find all the segments in `otherSegs` that vertically collide with `seg`. |
|
364 |
// Append into an optionally-supplied `results` array and return. |
|
365 |
function computeSlotSegCollisions(seg, otherSegs, results) { |
|
366 |
if (results === void 0) { results = []; } |
|
367 |
for (var i = 0; i < otherSegs.length; i++) { |
|
368 |
if (isSlotSegCollision(seg, otherSegs[i])) { |
|
369 |
results.push(otherSegs[i]); |
|
370 |
} |
|
371 |
} |
|
372 |
return results; |
|
373 |
} |
|
374 |
// Do these segments occupy the same vertical space? |
|
375 |
function isSlotSegCollision(seg1, seg2) { |
|
376 |
return seg1.bottom > seg2.top && seg1.top < seg2.bottom; |
|
377 |
} |
|
378 |
function buildTimeGridSegCompareObj(seg) { |
|
379 |
var obj = core.buildSegCompareObj(seg); |
|
380 |
obj.forwardPressure = seg.forwardPressure; |
|
381 |
obj.backwardCoord = seg.backwardCoord; |
|
382 |
return obj; |
|
383 |
} |
|
384 |
|
|
385 |
var TimeGridMirrorRenderer = /** @class */ (function (_super) { |
|
386 |
__extends(TimeGridMirrorRenderer, _super); |
|
387 |
function TimeGridMirrorRenderer() { |
|
388 |
return _super !== null && _super.apply(this, arguments) || this; |
|
389 |
} |
|
390 |
TimeGridMirrorRenderer.prototype.attachSegs = function (segs, mirrorInfo) { |
|
391 |
this.segsByCol = this.timeGrid.groupSegsByCol(segs); |
|
392 |
this.timeGrid.attachSegsByCol(this.segsByCol, this.timeGrid.mirrorContainerEls); |
|
393 |
this.sourceSeg = mirrorInfo.sourceSeg; |
|
394 |
}; |
|
395 |
TimeGridMirrorRenderer.prototype.generateSegCss = function (seg) { |
|
396 |
var props = _super.prototype.generateSegCss.call(this, seg); |
|
397 |
var sourceSeg = this.sourceSeg; |
|
398 |
if (sourceSeg && sourceSeg.col === seg.col) { |
|
399 |
var sourceSegProps = _super.prototype.generateSegCss.call(this, sourceSeg); |
|
400 |
props.left = sourceSegProps.left; |
|
401 |
props.right = sourceSegProps.right; |
|
402 |
props.marginLeft = sourceSegProps.marginLeft; |
|
403 |
props.marginRight = sourceSegProps.marginRight; |
|
404 |
} |
|
405 |
return props; |
|
406 |
}; |
|
407 |
return TimeGridMirrorRenderer; |
|
408 |
}(TimeGridEventRenderer)); |
|
409 |
|
|
410 |
var TimeGridFillRenderer = /** @class */ (function (_super) { |
|
411 |
__extends(TimeGridFillRenderer, _super); |
|
412 |
function TimeGridFillRenderer(timeGrid) { |
|
413 |
var _this = _super.call(this, timeGrid.context) || this; |
|
414 |
_this.timeGrid = timeGrid; |
|
415 |
return _this; |
|
416 |
} |
|
417 |
TimeGridFillRenderer.prototype.attachSegs = function (type, segs) { |
|
418 |
var timeGrid = this.timeGrid; |
|
419 |
var containerEls; |
|
420 |
// TODO: more efficient lookup |
|
421 |
if (type === 'bgEvent') { |
|
422 |
containerEls = timeGrid.bgContainerEls; |
|
423 |
} |
|
424 |
else if (type === 'businessHours') { |
|
425 |
containerEls = timeGrid.businessContainerEls; |
|
426 |
} |
|
427 |
else if (type === 'highlight') { |
|
428 |
containerEls = timeGrid.highlightContainerEls; |
|
429 |
} |
|
430 |
timeGrid.attachSegsByCol(timeGrid.groupSegsByCol(segs), containerEls); |
|
431 |
return segs.map(function (seg) { |
|
432 |
return seg.el; |
|
433 |
}); |
|
434 |
}; |
|
435 |
TimeGridFillRenderer.prototype.computeSegSizes = function (segs) { |
|
436 |
this.timeGrid.computeSegVerticals(segs); |
|
437 |
}; |
|
438 |
TimeGridFillRenderer.prototype.assignSegSizes = function (segs) { |
|
439 |
this.timeGrid.assignSegVerticals(segs); |
|
440 |
}; |
|
441 |
return TimeGridFillRenderer; |
|
442 |
}(core.FillRenderer)); |
|
443 |
|
|
444 |
/* A component that renders one or more columns of vertical time slots |
|
445 |
----------------------------------------------------------------------------------------------------------------------*/ |
|
446 |
// potential nice values for the slot-duration and interval-duration |
|
447 |
// from largest to smallest |
|
448 |
var AGENDA_STOCK_SUB_DURATIONS = [ |
|
449 |
{ hours: 1 }, |
|
450 |
{ minutes: 30 }, |
|
451 |
{ minutes: 15 }, |
|
452 |
{ seconds: 30 }, |
|
453 |
{ seconds: 15 } |
|
454 |
]; |
|
455 |
var TimeGrid = /** @class */ (function (_super) { |
|
456 |
__extends(TimeGrid, _super); |
|
457 |
function TimeGrid(context, el, renderProps) { |
|
458 |
var _this = _super.call(this, context, el) || this; |
|
459 |
_this.isSlatSizesDirty = false; |
|
460 |
_this.isColSizesDirty = false; |
|
461 |
_this.renderSlats = core.memoizeRendering(_this._renderSlats); |
|
462 |
var eventRenderer = _this.eventRenderer = new TimeGridEventRenderer(_this); |
|
463 |
var fillRenderer = _this.fillRenderer = new TimeGridFillRenderer(_this); |
|
464 |
_this.mirrorRenderer = new TimeGridMirrorRenderer(_this); |
|
465 |
var renderColumns = _this.renderColumns = core.memoizeRendering(_this._renderColumns, _this._unrenderColumns); |
|
466 |
_this.renderBusinessHours = core.memoizeRendering(fillRenderer.renderSegs.bind(fillRenderer, 'businessHours'), fillRenderer.unrender.bind(fillRenderer, 'businessHours'), [renderColumns]); |
|
467 |
_this.renderDateSelection = core.memoizeRendering(_this._renderDateSelection, _this._unrenderDateSelection, [renderColumns]); |
|
468 |
_this.renderFgEvents = core.memoizeRendering(eventRenderer.renderSegs.bind(eventRenderer), eventRenderer.unrender.bind(eventRenderer), [renderColumns]); |
|
469 |
_this.renderBgEvents = core.memoizeRendering(fillRenderer.renderSegs.bind(fillRenderer, 'bgEvent'), fillRenderer.unrender.bind(fillRenderer, 'bgEvent'), [renderColumns]); |
|
470 |
_this.renderEventSelection = core.memoizeRendering(eventRenderer.selectByInstanceId.bind(eventRenderer), eventRenderer.unselectByInstanceId.bind(eventRenderer), [_this.renderFgEvents]); |
|
471 |
_this.renderEventDrag = core.memoizeRendering(_this._renderEventDrag, _this._unrenderEventDrag, [renderColumns]); |
|
472 |
_this.renderEventResize = core.memoizeRendering(_this._renderEventResize, _this._unrenderEventResize, [renderColumns]); |
|
473 |
_this.processOptions(); |
|
474 |
el.innerHTML = |
|
475 |
'<div class="fc-bg"></div>' + |
|
476 |
'<div class="fc-slats"></div>' + |
|
477 |
'<hr class="fc-divider ' + _this.theme.getClass('widgetHeader') + '" style="display:none" />'; |
|
478 |
_this.rootBgContainerEl = el.querySelector('.fc-bg'); |
|
479 |
_this.slatContainerEl = el.querySelector('.fc-slats'); |
|
480 |
_this.bottomRuleEl = el.querySelector('.fc-divider'); |
|
481 |
_this.renderProps = renderProps; |
|
482 |
return _this; |
|
483 |
} |
|
484 |
/* Options |
|
485 |
------------------------------------------------------------------------------------------------------------------*/ |
|
486 |
// Parses various options into properties of this object |
|
487 |
TimeGrid.prototype.processOptions = function () { |
|
488 |
var slotDuration = this.opt('slotDuration'); |
|
489 |
var snapDuration = this.opt('snapDuration'); |
|
490 |
var snapsPerSlot; |
|
491 |
var input; |
|
492 |
slotDuration = core.createDuration(slotDuration); |
|
493 |
snapDuration = snapDuration ? core.createDuration(snapDuration) : slotDuration; |
|
494 |
snapsPerSlot = core.wholeDivideDurations(slotDuration, snapDuration); |
|
495 |
if (snapsPerSlot === null) { |
|
496 |
snapDuration = slotDuration; |
|
497 |
snapsPerSlot = 1; |
|
498 |
// TODO: say warning? |
|
499 |
} |
|
500 |
this.slotDuration = slotDuration; |
|
501 |
this.snapDuration = snapDuration; |
|
502 |
this.snapsPerSlot = snapsPerSlot; |
|
503 |
// might be an array value (for TimelineView). |
|
504 |
// if so, getting the most granular entry (the last one probably). |
|
505 |
input = this.opt('slotLabelFormat'); |
|
506 |
if (Array.isArray(input)) { |
|
507 |
input = input[input.length - 1]; |
|
508 |
} |
|
509 |
this.labelFormat = core.createFormatter(input || { |
|
510 |
hour: 'numeric', |
|
511 |
minute: '2-digit', |
|
512 |
omitZeroMinute: true, |
|
513 |
meridiem: 'short' |
|
514 |
}); |
|
515 |
input = this.opt('slotLabelInterval'); |
|
516 |
this.labelInterval = input ? |
|
517 |
core.createDuration(input) : |
|
518 |
this.computeLabelInterval(slotDuration); |
|
519 |
}; |
|
520 |
// Computes an automatic value for slotLabelInterval |
|
521 |
TimeGrid.prototype.computeLabelInterval = function (slotDuration) { |
|
522 |
var i; |
|
523 |
var labelInterval; |
|
524 |
var slotsPerLabel; |
|
525 |
// find the smallest stock label interval that results in more than one slots-per-label |
|
526 |
for (i = AGENDA_STOCK_SUB_DURATIONS.length - 1; i >= 0; i--) { |
|
527 |
labelInterval = core.createDuration(AGENDA_STOCK_SUB_DURATIONS[i]); |
|
528 |
slotsPerLabel = core.wholeDivideDurations(labelInterval, slotDuration); |
|
529 |
if (slotsPerLabel !== null && slotsPerLabel > 1) { |
|
530 |
return labelInterval; |
|
531 |
} |
|
532 |
} |
|
533 |
return slotDuration; // fall back |
|
534 |
}; |
|
535 |
/* Rendering |
|
536 |
------------------------------------------------------------------------------------------------------------------*/ |
|
537 |
TimeGrid.prototype.render = function (props) { |
|
538 |
var cells = props.cells; |
|
539 |
this.colCnt = cells.length; |
|
540 |
this.renderSlats(props.dateProfile); |
|
541 |
this.renderColumns(props.cells, props.dateProfile); |
|
542 |
this.renderBusinessHours(props.businessHourSegs); |
|
543 |
this.renderDateSelection(props.dateSelectionSegs); |
|
544 |
this.renderFgEvents(props.fgEventSegs); |
|
545 |
this.renderBgEvents(props.bgEventSegs); |
|
546 |
this.renderEventSelection(props.eventSelection); |
|
547 |
this.renderEventDrag(props.eventDrag); |
|
548 |
this.renderEventResize(props.eventResize); |
|
549 |
}; |
|
550 |
TimeGrid.prototype.destroy = function () { |
|
551 |
_super.prototype.destroy.call(this); |
|
552 |
// should unrender everything else too |
|
553 |
this.renderSlats.unrender(); |
|
554 |
this.renderColumns.unrender(); |
|
555 |
}; |
|
556 |
TimeGrid.prototype.updateSize = function (isResize) { |
|
557 |
var _a = this, fillRenderer = _a.fillRenderer, eventRenderer = _a.eventRenderer, mirrorRenderer = _a.mirrorRenderer; |
|
558 |
if (isResize || this.isSlatSizesDirty) { |
|
559 |
this.buildSlatPositions(); |
|
560 |
this.isSlatSizesDirty = false; |
|
561 |
} |
|
562 |
if (isResize || this.isColSizesDirty) { |
|
563 |
this.buildColPositions(); |
|
564 |
this.isColSizesDirty = false; |
|
565 |
} |
|
566 |
fillRenderer.computeSizes(isResize); |
|
567 |
eventRenderer.computeSizes(isResize); |
|
568 |
mirrorRenderer.computeSizes(isResize); |
|
569 |
fillRenderer.assignSizes(isResize); |
|
570 |
eventRenderer.assignSizes(isResize); |
|
571 |
mirrorRenderer.assignSizes(isResize); |
|
572 |
}; |
|
573 |
TimeGrid.prototype._renderSlats = function (dateProfile) { |
|
574 |
var theme = this.theme; |
|
575 |
this.slatContainerEl.innerHTML = |
|
576 |
'<table class="' + theme.getClass('tableGrid') + '">' + |
|
577 |
this.renderSlatRowHtml(dateProfile) + |
|
578 |
'</table>'; |
|
579 |
this.slatEls = core.findElements(this.slatContainerEl, 'tr'); |
|
580 |
this.slatPositions = new core.PositionCache(this.el, this.slatEls, false, true // vertical |
|
581 |
); |
|
582 |
this.isSlatSizesDirty = true; |
|
583 |
}; |
|
584 |
// Generates the HTML for the horizontal "slats" that run width-wise. Has a time axis on a side. Depends on RTL. |
|
585 |
TimeGrid.prototype.renderSlatRowHtml = function (dateProfile) { |
|
586 |
var _a = this, dateEnv = _a.dateEnv, theme = _a.theme, isRtl = _a.isRtl; |
|
587 |
var html = ''; |
|
588 |
var dayStart = core.startOfDay(dateProfile.renderRange.start); |
|
589 |
var slotTime = dateProfile.minTime; |
|
590 |
var slotIterator = core.createDuration(0); |
|
591 |
var slotDate; // will be on the view's first day, but we only care about its time |
|
592 |
var isLabeled; |
|
593 |
var axisHtml; |
|
594 |
// Calculate the time for each slot |
|
595 |
while (core.asRoughMs(slotTime) < core.asRoughMs(dateProfile.maxTime)) { |
|
596 |
slotDate = dateEnv.add(dayStart, slotTime); |
|
597 |
isLabeled = core.wholeDivideDurations(slotIterator, this.labelInterval) !== null; |
|
598 |
axisHtml = |
|
599 |
'<td class="fc-axis fc-time ' + theme.getClass('widgetContent') + '">' + |
|
600 |
(isLabeled ? |
|
601 |
'<span>' + // for matchCellWidths |
|
602 |
core.htmlEscape(dateEnv.format(slotDate, this.labelFormat)) + |
|
603 |
'</span>' : |
|
604 |
'') + |
|
605 |
'</td>'; |
|
606 |
html += |
|
607 |
'<tr data-time="' + core.formatIsoTimeString(slotDate) + '"' + |
|
608 |
(isLabeled ? '' : ' class="fc-minor"') + |
|
609 |
'>' + |
|
610 |
(!isRtl ? axisHtml : '') + |
|
611 |
'<td class="' + theme.getClass('widgetContent') + '"></td>' + |
|
612 |
(isRtl ? axisHtml : '') + |
|
613 |
'</tr>'; |
|
614 |
slotTime = core.addDurations(slotTime, this.slotDuration); |
|
615 |
slotIterator = core.addDurations(slotIterator, this.slotDuration); |
|
616 |
} |
|
617 |
return html; |
|
618 |
}; |
|
619 |
TimeGrid.prototype._renderColumns = function (cells, dateProfile) { |
|
620 |
var _a = this, theme = _a.theme, dateEnv = _a.dateEnv, view = _a.view; |
|
621 |
var bgRow = new daygrid.DayBgRow(this.context); |
|
622 |
this.rootBgContainerEl.innerHTML = |
|
623 |
'<table class="' + theme.getClass('tableGrid') + '">' + |
|
624 |
bgRow.renderHtml({ |
|
625 |
cells: cells, |
|
626 |
dateProfile: dateProfile, |
|
627 |
renderIntroHtml: this.renderProps.renderBgIntroHtml |
|
628 |
}) + |
|
629 |
'</table>'; |
|
630 |
this.colEls = core.findElements(this.el, '.fc-day, .fc-disabled-day'); |
|
631 |
for (var col = 0; col < this.colCnt; col++) { |
|
632 |
this.publiclyTrigger('dayRender', [ |
|
633 |
{ |
|
634 |
date: dateEnv.toDate(cells[col].date), |
|
635 |
el: this.colEls[col], |
|
636 |
view: view |
|
637 |
} |
|
638 |
]); |
|
639 |
} |
|
640 |
if (this.isRtl) { |
|
641 |
this.colEls.reverse(); |
|
642 |
} |
|
643 |
this.colPositions = new core.PositionCache(this.el, this.colEls, true, // horizontal |
|
644 |
false); |
|
645 |
this.renderContentSkeleton(); |
|
646 |
this.isColSizesDirty = true; |
|
647 |
}; |
|
648 |
TimeGrid.prototype._unrenderColumns = function () { |
|
649 |
this.unrenderContentSkeleton(); |
|
650 |
}; |
|
651 |
/* Content Skeleton |
|
652 |
------------------------------------------------------------------------------------------------------------------*/ |
|
653 |
// Renders the DOM that the view's content will live in |
|
654 |
TimeGrid.prototype.renderContentSkeleton = function () { |
|
655 |
var parts = []; |
|
656 |
var skeletonEl; |
|
657 |
parts.push(this.renderProps.renderIntroHtml()); |
|
658 |
for (var i = 0; i < this.colCnt; i++) { |
|
659 |
parts.push('<td>' + |
|
660 |
'<div class="fc-content-col">' + |
|
661 |
'<div class="fc-event-container fc-mirror-container"></div>' + |
|
662 |
'<div class="fc-event-container"></div>' + |
|
663 |
'<div class="fc-highlight-container"></div>' + |
|
664 |
'<div class="fc-bgevent-container"></div>' + |
|
665 |
'<div class="fc-business-container"></div>' + |
|
666 |
'</div>' + |
|
667 |
'</td>'); |
|
668 |
} |
|
669 |
if (this.isRtl) { |
|
670 |
parts.reverse(); |
|
671 |
} |
|
672 |
skeletonEl = this.contentSkeletonEl = core.htmlToElement('<div class="fc-content-skeleton">' + |
|
673 |
'<table>' + |
|
674 |
'<tr>' + parts.join('') + '</tr>' + |
|
675 |
'</table>' + |
|
676 |
'</div>'); |
|
677 |
this.colContainerEls = core.findElements(skeletonEl, '.fc-content-col'); |
|
678 |
this.mirrorContainerEls = core.findElements(skeletonEl, '.fc-mirror-container'); |
|
679 |
this.fgContainerEls = core.findElements(skeletonEl, '.fc-event-container:not(.fc-mirror-container)'); |
|
680 |
this.bgContainerEls = core.findElements(skeletonEl, '.fc-bgevent-container'); |
|
681 |
this.highlightContainerEls = core.findElements(skeletonEl, '.fc-highlight-container'); |
|
682 |
this.businessContainerEls = core.findElements(skeletonEl, '.fc-business-container'); |
|
683 |
if (this.isRtl) { |
|
684 |
this.colContainerEls.reverse(); |
|
685 |
this.mirrorContainerEls.reverse(); |
|
686 |
this.fgContainerEls.reverse(); |
|
687 |
this.bgContainerEls.reverse(); |
|
688 |
this.highlightContainerEls.reverse(); |
|
689 |
this.businessContainerEls.reverse(); |
|
690 |
} |
|
691 |
this.el.appendChild(skeletonEl); |
|
692 |
}; |
|
693 |
TimeGrid.prototype.unrenderContentSkeleton = function () { |
|
694 |
core.removeElement(this.contentSkeletonEl); |
|
695 |
}; |
|
696 |
// Given a flat array of segments, return an array of sub-arrays, grouped by each segment's col |
|
697 |
TimeGrid.prototype.groupSegsByCol = function (segs) { |
|
698 |
var segsByCol = []; |
|
699 |
var i; |
|
700 |
for (i = 0; i < this.colCnt; i++) { |
|
701 |
segsByCol.push([]); |
|
702 |
} |
|
703 |
for (i = 0; i < segs.length; i++) { |
|
704 |
segsByCol[segs[i].col].push(segs[i]); |
|
705 |
} |
|
706 |
return segsByCol; |
|
707 |
}; |
|
708 |
// Given segments grouped by column, insert the segments' elements into a parallel array of container |
|
709 |
// elements, each living within a column. |
|
710 |
TimeGrid.prototype.attachSegsByCol = function (segsByCol, containerEls) { |
|
711 |
var col; |
|
712 |
var segs; |
|
713 |
var i; |
|
714 |
for (col = 0; col < this.colCnt; col++) { // iterate each column grouping |
|
715 |
segs = segsByCol[col]; |
|
716 |
for (i = 0; i < segs.length; i++) { |
|
717 |
containerEls[col].appendChild(segs[i].el); |
|
718 |
} |
|
719 |
} |
|
720 |
}; |
|
721 |
/* Now Indicator |
|
722 |
------------------------------------------------------------------------------------------------------------------*/ |
|
723 |
TimeGrid.prototype.getNowIndicatorUnit = function () { |
|
724 |
return 'minute'; // will refresh on the minute |
|
725 |
}; |
|
726 |
TimeGrid.prototype.renderNowIndicator = function (segs, date) { |
|
727 |
// HACK: if date columns not ready for some reason (scheduler) |
|
728 |
if (!this.colContainerEls) { |
|
729 |
return; |
|
730 |
} |
|
731 |
var top = this.computeDateTop(date); |
|
732 |
var nodes = []; |
|
733 |
var i; |
|
734 |
// render lines within the columns |
|
735 |
for (i = 0; i < segs.length; i++) { |
|
736 |
var lineEl = core.createElement('div', { className: 'fc-now-indicator fc-now-indicator-line' }); |
|
737 |
lineEl.style.top = top + 'px'; |
|
738 |
this.colContainerEls[segs[i].col].appendChild(lineEl); |
|
739 |
nodes.push(lineEl); |
|
740 |
} |
|
741 |
// render an arrow over the axis |
|
742 |
if (segs.length > 0) { // is the current time in view? |
|
743 |
var arrowEl = core.createElement('div', { className: 'fc-now-indicator fc-now-indicator-arrow' }); |
|
744 |
arrowEl.style.top = top + 'px'; |
|
745 |
this.contentSkeletonEl.appendChild(arrowEl); |
|
746 |
nodes.push(arrowEl); |
|
747 |
} |
|
748 |
this.nowIndicatorEls = nodes; |
|
749 |
}; |
|
750 |
TimeGrid.prototype.unrenderNowIndicator = function () { |
|
751 |
if (this.nowIndicatorEls) { |
|
752 |
this.nowIndicatorEls.forEach(core.removeElement); |
|
753 |
this.nowIndicatorEls = null; |
|
754 |
} |
|
755 |
}; |
|
756 |
/* Coordinates |
|
757 |
------------------------------------------------------------------------------------------------------------------*/ |
|
758 |
TimeGrid.prototype.getTotalSlatHeight = function () { |
|
759 |
return this.slatContainerEl.getBoundingClientRect().height; |
|
760 |
}; |
|
761 |
// Computes the top coordinate, relative to the bounds of the grid, of the given date. |
|
762 |
// A `startOfDayDate` must be given for avoiding ambiguity over how to treat midnight. |
|
763 |
TimeGrid.prototype.computeDateTop = function (when, startOfDayDate) { |
|
764 |
if (!startOfDayDate) { |
|
765 |
startOfDayDate = core.startOfDay(when); |
|
766 |
} |
|
767 |
return this.computeTimeTop(core.createDuration(when.valueOf() - startOfDayDate.valueOf())); |
|
768 |
}; |
|
769 |
// Computes the top coordinate, relative to the bounds of the grid, of the given time (a Duration). |
|
770 |
TimeGrid.prototype.computeTimeTop = function (duration) { |
|
771 |
var len = this.slatEls.length; |
|
772 |
var dateProfile = this.props.dateProfile; |
|
773 |
var slatCoverage = (duration.milliseconds - core.asRoughMs(dateProfile.minTime)) / core.asRoughMs(this.slotDuration); // floating-point value of # of slots covered |
|
774 |
var slatIndex; |
|
775 |
var slatRemainder; |
|
776 |
// compute a floating-point number for how many slats should be progressed through. |
|
777 |
// from 0 to number of slats (inclusive) |
|
778 |
// constrained because minTime/maxTime might be customized. |
|
779 |
slatCoverage = Math.max(0, slatCoverage); |
|
780 |
slatCoverage = Math.min(len, slatCoverage); |
|
781 |
// an integer index of the furthest whole slat |
|
782 |
// from 0 to number slats (*exclusive*, so len-1) |
|
783 |
slatIndex = Math.floor(slatCoverage); |
|
784 |
slatIndex = Math.min(slatIndex, len - 1); |
|
785 |
// how much further through the slatIndex slat (from 0.0-1.0) must be covered in addition. |
|
786 |
// could be 1.0 if slatCoverage is covering *all* the slots |
|
787 |
slatRemainder = slatCoverage - slatIndex; |
|
788 |
return this.slatPositions.tops[slatIndex] + |
|
789 |
this.slatPositions.getHeight(slatIndex) * slatRemainder; |
|
790 |
}; |
|
791 |
// For each segment in an array, computes and assigns its top and bottom properties |
|
792 |
TimeGrid.prototype.computeSegVerticals = function (segs) { |
|
793 |
var eventMinHeight = this.opt('timeGridEventMinHeight'); |
|
794 |
var i; |
|
795 |
var seg; |
|
796 |
var dayDate; |
|
797 |
for (i = 0; i < segs.length; i++) { |
|
798 |
seg = segs[i]; |
|
799 |
dayDate = this.props.cells[seg.col].date; |
|
800 |
seg.top = this.computeDateTop(seg.start, dayDate); |
|
801 |
seg.bottom = Math.max(seg.top + eventMinHeight, this.computeDateTop(seg.end, dayDate)); |
|
802 |
} |
|
803 |
}; |
|
804 |
// Given segments that already have their top/bottom properties computed, applies those values to |
|
805 |
// the segments' elements. |
|
806 |
TimeGrid.prototype.assignSegVerticals = function (segs) { |
|
807 |
var i; |
|
808 |
var seg; |
|
809 |
for (i = 0; i < segs.length; i++) { |
|
810 |
seg = segs[i]; |
|
811 |
core.applyStyle(seg.el, this.generateSegVerticalCss(seg)); |
|
812 |
} |
|
813 |
}; |
|
814 |
// Generates an object with CSS properties for the top/bottom coordinates of a segment element |
|
815 |
TimeGrid.prototype.generateSegVerticalCss = function (seg) { |
|
816 |
return { |
|
817 |
top: seg.top, |
|
818 |
bottom: -seg.bottom // flipped because needs to be space beyond bottom edge of event container |
|
819 |
}; |
|
820 |
}; |
|
821 |
/* Sizing |
|
822 |
------------------------------------------------------------------------------------------------------------------*/ |
|
823 |
TimeGrid.prototype.buildPositionCaches = function () { |
|
824 |
this.buildColPositions(); |
|
825 |
this.buildSlatPositions(); |
|
826 |
}; |
|
827 |
TimeGrid.prototype.buildColPositions = function () { |
|
828 |
this.colPositions.build(); |
|
829 |
}; |
|
830 |
TimeGrid.prototype.buildSlatPositions = function () { |
|
831 |
this.slatPositions.build(); |
|
832 |
}; |
|
833 |
/* Hit System |
|
834 |
------------------------------------------------------------------------------------------------------------------*/ |
|
835 |
TimeGrid.prototype.positionToHit = function (positionLeft, positionTop) { |
|
836 |
var _a = this, dateEnv = _a.dateEnv, snapsPerSlot = _a.snapsPerSlot, slatPositions = _a.slatPositions, colPositions = _a.colPositions; |
|
837 |
var colIndex = colPositions.leftToIndex(positionLeft); |
|
838 |
var slatIndex = slatPositions.topToIndex(positionTop); |
|
839 |
if (colIndex != null && slatIndex != null) { |
|
840 |
var slatTop = slatPositions.tops[slatIndex]; |
|
841 |
var slatHeight = slatPositions.getHeight(slatIndex); |
|
842 |
var partial = (positionTop - slatTop) / slatHeight; // floating point number between 0 and 1 |
|
843 |
var localSnapIndex = Math.floor(partial * snapsPerSlot); // the snap # relative to start of slat |
|
844 |
var snapIndex = slatIndex * snapsPerSlot + localSnapIndex; |
|
845 |
var dayDate = this.props.cells[colIndex].date; |
|
846 |
var time = core.addDurations(this.props.dateProfile.minTime, core.multiplyDuration(this.snapDuration, snapIndex)); |
|
847 |
var start = dateEnv.add(dayDate, time); |
|
848 |
var end = dateEnv.add(start, this.snapDuration); |
|
849 |
return { |
|
850 |
col: colIndex, |
|
851 |
dateSpan: { |
|
852 |
range: { start: start, end: end }, |
|
853 |
allDay: false |
|
854 |
}, |
|
855 |
dayEl: this.colEls[colIndex], |
|
856 |
relativeRect: { |
|
857 |
left: colPositions.lefts[colIndex], |
|
858 |
right: colPositions.rights[colIndex], |
|
859 |
top: slatTop, |
|
860 |
bottom: slatTop + slatHeight |
|
861 |
} |
|
862 |
}; |
|
863 |
} |
|
864 |
}; |
|
865 |
/* Event Drag Visualization |
|
866 |
------------------------------------------------------------------------------------------------------------------*/ |
|
867 |
TimeGrid.prototype._renderEventDrag = function (state) { |
|
868 |
if (state) { |
|
869 |
this.eventRenderer.hideByHash(state.affectedInstances); |
|
870 |
if (state.isEvent) { |
|
871 |
this.mirrorRenderer.renderSegs(state.segs, { isDragging: true, sourceSeg: state.sourceSeg }); |
|
872 |
} |
|
873 |
else { |
|
874 |
this.fillRenderer.renderSegs('highlight', state.segs); |
|
875 |
} |
|
876 |
} |
|
877 |
}; |
|
878 |
TimeGrid.prototype._unrenderEventDrag = function (state) { |
|
879 |
if (state) { |
|
880 |
this.eventRenderer.showByHash(state.affectedInstances); |
|
881 |
this.mirrorRenderer.unrender(state.segs, { isDragging: true, sourceSeg: state.sourceSeg }); |
|
882 |
this.fillRenderer.unrender('highlight'); |
|
883 |
} |
|
884 |
}; |
|
885 |
/* Event Resize Visualization |
|
886 |
------------------------------------------------------------------------------------------------------------------*/ |
|
887 |
TimeGrid.prototype._renderEventResize = function (state) { |
|
888 |
if (state) { |
|
889 |
this.eventRenderer.hideByHash(state.affectedInstances); |
|
890 |
this.mirrorRenderer.renderSegs(state.segs, { isResizing: true, sourceSeg: state.sourceSeg }); |
|
891 |
} |
|
892 |
}; |
|
893 |
TimeGrid.prototype._unrenderEventResize = function (state) { |
|
894 |
if (state) { |
|
895 |
this.eventRenderer.showByHash(state.affectedInstances); |
|
896 |
this.mirrorRenderer.unrender(state.segs, { isResizing: true, sourceSeg: state.sourceSeg }); |
|
897 |
} |
|
898 |
}; |
|
899 |
/* Selection |
|
900 |
------------------------------------------------------------------------------------------------------------------*/ |
|
901 |
// Renders a visual indication of a selection. Overrides the default, which was to simply render a highlight. |
|
902 |
TimeGrid.prototype._renderDateSelection = function (segs) { |
|
903 |
if (segs) { |
|
904 |
if (this.opt('selectMirror')) { |
|
905 |
this.mirrorRenderer.renderSegs(segs, { isSelecting: true }); |
|
906 |
} |
|
907 |
else { |
|
908 |
this.fillRenderer.renderSegs('highlight', segs); |
|
909 |
} |
|
910 |
} |
|
911 |
}; |
|
912 |
TimeGrid.prototype._unrenderDateSelection = function (segs) { |
|
913 |
this.mirrorRenderer.unrender(segs, { isSelecting: true }); |
|
914 |
this.fillRenderer.unrender('highlight'); |
|
915 |
}; |
|
916 |
return TimeGrid; |
|
917 |
}(core.DateComponent)); |
|
918 |
|
|
919 |
var AllDaySplitter = /** @class */ (function (_super) { |
|
920 |
__extends(AllDaySplitter, _super); |
|
921 |
function AllDaySplitter() { |
|
922 |
return _super !== null && _super.apply(this, arguments) || this; |
|
923 |
} |
|
924 |
AllDaySplitter.prototype.getKeyInfo = function () { |
|
925 |
return { |
|
926 |
allDay: {}, |
|
927 |
timed: {} |
|
928 |
}; |
|
929 |
}; |
|
930 |
AllDaySplitter.prototype.getKeysForDateSpan = function (dateSpan) { |
|
931 |
if (dateSpan.allDay) { |
|
932 |
return ['allDay']; |
|
933 |
} |
|
934 |
else { |
|
935 |
return ['timed']; |
|
936 |
} |
|
937 |
}; |
|
938 |
AllDaySplitter.prototype.getKeysForEventDef = function (eventDef) { |
|
939 |
if (!eventDef.allDay) { |
|
940 |
return ['timed']; |
|
941 |
} |
|
942 |
else if (core.hasBgRendering(eventDef)) { |
|
943 |
return ['timed', 'allDay']; |
|
944 |
} |
|
945 |
else { |
|
946 |
return ['allDay']; |
|
947 |
} |
|
948 |
}; |
|
949 |
return AllDaySplitter; |
|
950 |
}(core.Splitter)); |
|
951 |
|
|
952 |
var TIMEGRID_ALL_DAY_EVENT_LIMIT = 5; |
|
953 |
var WEEK_HEADER_FORMAT = core.createFormatter({ week: 'short' }); |
|
954 |
/* An abstract class for all timegrid-related views. Displays one more columns with time slots running vertically. |
|
955 |
----------------------------------------------------------------------------------------------------------------------*/ |
|
956 |
// Is a manager for the TimeGrid subcomponent and possibly the DayGrid subcomponent (if allDaySlot is on). |
|
957 |
// Responsible for managing width/height. |
|
958 |
var TimeGridView = /** @class */ (function (_super) { |
|
959 |
__extends(TimeGridView, _super); |
|
960 |
function TimeGridView(context, viewSpec, dateProfileGenerator, parentEl) { |
|
961 |
var _this = _super.call(this, context, viewSpec, dateProfileGenerator, parentEl) || this; |
|
962 |
_this.splitter = new AllDaySplitter(); |
|
963 |
/* Header Render Methods |
|
964 |
------------------------------------------------------------------------------------------------------------------*/ |
|
965 |
// Generates the HTML that will go before the day-of week header cells |
|
966 |
_this.renderHeadIntroHtml = function () { |
|
967 |
var _a = _this, theme = _a.theme, dateEnv = _a.dateEnv; |
|
968 |
var range = _this.props.dateProfile.renderRange; |
|
969 |
var dayCnt = core.diffDays(range.start, range.end); |
|
970 |
var weekText; |
|
971 |
if (_this.opt('weekNumbers')) { |
|
972 |
weekText = dateEnv.format(range.start, WEEK_HEADER_FORMAT); |
|
973 |
return '' + |
|
974 |
'<th class="fc-axis fc-week-number ' + theme.getClass('widgetHeader') + '" ' + _this.axisStyleAttr() + '>' + |
|
975 |
core.buildGotoAnchorHtml(// aside from link, important for matchCellWidths |
|
976 |
_this, { date: range.start, type: 'week', forceOff: dayCnt > 1 }, core.htmlEscape(weekText) // inner HTML |
|
977 |
) + |
|
978 |
'</th>'; |
|
979 |
} |
|
980 |
else { |
|
981 |
return '<th class="fc-axis ' + theme.getClass('widgetHeader') + '" ' + _this.axisStyleAttr() + '></th>'; |
|
982 |
} |
|
983 |
}; |
|
984 |
/* Time Grid Render Methods |
|
985 |
------------------------------------------------------------------------------------------------------------------*/ |
|
986 |
// Generates the HTML that goes before the bg of the TimeGrid slot area. Long vertical column. |
|
987 |
_this.renderTimeGridBgIntroHtml = function () { |
|
988 |
var theme = _this.theme; |
|
989 |
return '<td class="fc-axis ' + theme.getClass('widgetContent') + '" ' + _this.axisStyleAttr() + '></td>'; |
|
990 |
}; |
|
991 |
// Generates the HTML that goes before all other types of cells. |
|
992 |
// Affects content-skeleton, mirror-skeleton, highlight-skeleton for both the time-grid and day-grid. |
|
993 |
_this.renderTimeGridIntroHtml = function () { |
|
994 |
return '<td class="fc-axis" ' + _this.axisStyleAttr() + '></td>'; |
|
995 |
}; |
|
996 |
/* Day Grid Render Methods |
|
997 |
------------------------------------------------------------------------------------------------------------------*/ |
|
998 |
// Generates the HTML that goes before the all-day cells |
|
999 |
_this.renderDayGridBgIntroHtml = function () { |
|
1000 |
var theme = _this.theme; |
|
1001 |
return '' + |
|
1002 |
'<td class="fc-axis ' + theme.getClass('widgetContent') + '" ' + _this.axisStyleAttr() + '>' + |
|
1003 |
'<span>' + // needed for matchCellWidths |
|
1004 |
core.getAllDayHtml(_this) + |
|
1005 |
'</span>' + |
|
1006 |
'</td>'; |
|
1007 |
}; |
|
1008 |
// Generates the HTML that goes before all other types of cells. |
|
1009 |
// Affects content-skeleton, mirror-skeleton, highlight-skeleton for both the time-grid and day-grid. |
|
1010 |
_this.renderDayGridIntroHtml = function () { |
|
1011 |
return '<td class="fc-axis" ' + _this.axisStyleAttr() + '></td>'; |
|
1012 |
}; |
|
1013 |
_this.el.classList.add('fc-timeGrid-view'); |
|
1014 |
_this.el.innerHTML = _this.renderSkeletonHtml(); |
|
1015 |
_this.scroller = new core.ScrollComponent('hidden', // overflow x |
|
1016 |
'auto' // overflow y |
|
1017 |
); |
|
1018 |
var timeGridWrapEl = _this.scroller.el; |
|
1019 |
_this.el.querySelector('.fc-body > tr > td').appendChild(timeGridWrapEl); |
|
1020 |
timeGridWrapEl.classList.add('fc-time-grid-container'); |
|
1021 |
var timeGridEl = core.createElement('div', { className: 'fc-time-grid' }); |
|
1022 |
timeGridWrapEl.appendChild(timeGridEl); |
|
1023 |
_this.timeGrid = new TimeGrid(_this.context, timeGridEl, { |
|
1024 |
renderBgIntroHtml: _this.renderTimeGridBgIntroHtml, |
|
1025 |
renderIntroHtml: _this.renderTimeGridIntroHtml |
|
1026 |
}); |
|
1027 |
if (_this.opt('allDaySlot')) { // should we display the "all-day" area? |
|
1028 |
_this.dayGrid = new daygrid.DayGrid(// the all-day subcomponent of this view |
|
1029 |
_this.context, _this.el.querySelector('.fc-day-grid'), { |
|
1030 |
renderNumberIntroHtml: _this.renderDayGridIntroHtml, |
|
1031 |
renderBgIntroHtml: _this.renderDayGridBgIntroHtml, |
|
1032 |
renderIntroHtml: _this.renderDayGridIntroHtml, |
|
1033 |
colWeekNumbersVisible: false, |
|
1034 |
cellWeekNumbersVisible: false |
|
1035 |
}); |
|
1036 |
// have the day-grid extend it's coordinate area over the <hr> dividing the two grids |
|
1037 |
var dividerEl = _this.el.querySelector('.fc-divider'); |
|
1038 |
_this.dayGrid.bottomCoordPadding = dividerEl.getBoundingClientRect().height; |
|
1039 |
} |
|
1040 |
return _this; |
|
1041 |
} |
|
1042 |
TimeGridView.prototype.destroy = function () { |
|
1043 |
_super.prototype.destroy.call(this); |
|
1044 |
this.timeGrid.destroy(); |
|
1045 |
if (this.dayGrid) { |
|
1046 |
this.dayGrid.destroy(); |
|
1047 |
} |
|
1048 |
this.scroller.destroy(); |
|
1049 |
}; |
|
1050 |
/* Rendering |
|
1051 |
------------------------------------------------------------------------------------------------------------------*/ |
|
1052 |
// Builds the HTML skeleton for the view. |
|
1053 |
// The day-grid and time-grid components will render inside containers defined by this HTML. |
|
1054 |
TimeGridView.prototype.renderSkeletonHtml = function () { |
|
1055 |
var theme = this.theme; |
|
1056 |
return '' + |
|
1057 |
'<table class="' + theme.getClass('tableGrid') + '">' + |
|
1058 |
(this.opt('columnHeader') ? |
|
1059 |
'<thead class="fc-head">' + |
|
1060 |
'<tr>' + |
|
1061 |
'<td class="fc-head-container ' + theme.getClass('widgetHeader') + '"> </td>' + |
|
1062 |
'</tr>' + |
|
1063 |
'</thead>' : |
|
1064 |
'') + |
|
1065 |
'<tbody class="fc-body">' + |
|
1066 |
'<tr>' + |
|
1067 |
'<td class="' + theme.getClass('widgetContent') + '">' + |
|
1068 |
(this.opt('allDaySlot') ? |
|
1069 |
'<div class="fc-day-grid"></div>' + |
|
1070 |
'<hr class="fc-divider ' + theme.getClass('widgetHeader') + '" />' : |
|
1071 |
'') + |
|
1072 |
'</td>' + |
|
1073 |
'</tr>' + |
|
1074 |
'</tbody>' + |
|
1075 |
'</table>'; |
|
1076 |
}; |
|
1077 |
/* Now Indicator |
|
1078 |
------------------------------------------------------------------------------------------------------------------*/ |
|
1079 |
TimeGridView.prototype.getNowIndicatorUnit = function () { |
|
1080 |
return this.timeGrid.getNowIndicatorUnit(); |
|
1081 |
}; |
|
1082 |
// subclasses should implement |
|
1083 |
// renderNowIndicator(date: DateMarker) { |
|
1084 |
// } |
|
1085 |
TimeGridView.prototype.unrenderNowIndicator = function () { |
|
1086 |
this.timeGrid.unrenderNowIndicator(); |
|
1087 |
}; |
|
1088 |
/* Dimensions |
|
1089 |
------------------------------------------------------------------------------------------------------------------*/ |
|
1090 |
TimeGridView.prototype.updateSize = function (isResize, viewHeight, isAuto) { |
|
1091 |
_super.prototype.updateSize.call(this, isResize, viewHeight, isAuto); // will call updateBaseSize. important that executes first |
|
1092 |
this.timeGrid.updateSize(isResize); |
|
1093 |
if (this.dayGrid) { |
|
1094 |
this.dayGrid.updateSize(isResize); |
|
1095 |
} |
|
1096 |
}; |
|
1097 |
// Adjusts the vertical dimensions of the view to the specified values |
|
1098 |
TimeGridView.prototype.updateBaseSize = function (isResize, viewHeight, isAuto) { |
|
1099 |
var _this = this; |
|
1100 |
var eventLimit; |
|
1101 |
var scrollerHeight; |
|
1102 |
var scrollbarWidths; |
|
1103 |
// make all axis cells line up |
|
1104 |
this.axisWidth = core.matchCellWidths(core.findElements(this.el, '.fc-axis')); |
|
1105 |
// hack to give the view some height prior to timeGrid's columns being rendered |
|
1106 |
// TODO: separate setting height from scroller VS timeGrid. |
|
1107 |
if (!this.timeGrid.colEls) { |
|
1108 |
if (!isAuto) { |
|
1109 |
scrollerHeight = this.computeScrollerHeight(viewHeight); |
|
1110 |
this.scroller.setHeight(scrollerHeight); |
|
1111 |
} |
|
1112 |
return; |
|
1113 |
} |
|
1114 |
// set of fake row elements that must compensate when scroller has scrollbars |
|
1115 |
var noScrollRowEls = core.findElements(this.el, '.fc-row').filter(function (node) { |
|
1116 |
return !_this.scroller.el.contains(node); |
|
1117 |
}); |
|
1118 |
// reset all dimensions back to the original state |
|
1119 |
this.timeGrid.bottomRuleEl.style.display = 'none'; // will be shown later if this <hr> is necessary |
|
1120 |
this.scroller.clear(); // sets height to 'auto' and clears overflow |
|
1121 |
noScrollRowEls.forEach(core.uncompensateScroll); |
|
1122 |
// limit number of events in the all-day area |
|
1123 |
if (this.dayGrid) { |
|
1124 |
this.dayGrid.removeSegPopover(); // kill the "more" popover if displayed |
|
1125 |
eventLimit = this.opt('eventLimit'); |
|
1126 |
if (eventLimit && typeof eventLimit !== 'number') { |
|
1127 |
eventLimit = TIMEGRID_ALL_DAY_EVENT_LIMIT; // make sure "auto" goes to a real number |
|
1128 |
} |
|
1129 |
if (eventLimit) { |
|
1130 |
this.dayGrid.limitRows(eventLimit); |
|
1131 |
} |
|
1132 |
} |
|
1133 |
if (!isAuto) { // should we force dimensions of the scroll container? |
|
1134 |
scrollerHeight = this.computeScrollerHeight(viewHeight); |
|
1135 |
this.scroller.setHeight(scrollerHeight); |
|
1136 |
scrollbarWidths = this.scroller.getScrollbarWidths(); |
|
1137 |
if (scrollbarWidths.left || scrollbarWidths.right) { // using scrollbars? |
|
1138 |
// make the all-day and header rows lines up |
|
1139 |
noScrollRowEls.forEach(function (rowEl) { |
|
1140 |
core.compensateScroll(rowEl, scrollbarWidths); |
|
1141 |
}); |
|
1142 |
// the scrollbar compensation might have changed text flow, which might affect height, so recalculate |
|
1143 |
// and reapply the desired height to the scroller. |
|
1144 |
scrollerHeight = this.computeScrollerHeight(viewHeight); |
|
1145 |
this.scroller.setHeight(scrollerHeight); |
|
1146 |
} |
|
1147 |
// guarantees the same scrollbar widths |
|
1148 |
this.scroller.lockOverflow(scrollbarWidths); |
|
1149 |
// if there's any space below the slats, show the horizontal rule. |
|
1150 |
// this won't cause any new overflow, because lockOverflow already called. |
|
1151 |
if (this.timeGrid.getTotalSlatHeight() < scrollerHeight) { |
|
1152 |
this.timeGrid.bottomRuleEl.style.display = ''; |
|
1153 |
} |
|
1154 |
} |
|
1155 |
}; |
|
1156 |
// given a desired total height of the view, returns what the height of the scroller should be |
|
1157 |
TimeGridView.prototype.computeScrollerHeight = function (viewHeight) { |
|
1158 |
return viewHeight - |
|
1159 |
core.subtractInnerElHeight(this.el, this.scroller.el); // everything that's NOT the scroller |
|
1160 |
}; |
|
1161 |
/* Scroll |
|
1162 |
------------------------------------------------------------------------------------------------------------------*/ |
|
1163 |
// Computes the initial pre-configured scroll state prior to allowing the user to change it |
|
1164 |
TimeGridView.prototype.computeDateScroll = function (duration) { |
|
1165 |
var top = this.timeGrid.computeTimeTop(duration); |
|
1166 |
// zoom can give weird floating-point values. rather scroll a little bit further |
|
1167 |
top = Math.ceil(top); |
|
1168 |
if (top) { |
|
1169 |
top++; // to overcome top border that slots beyond the first have. looks better |
|
1170 |
} |
|
1171 |
return { top: top }; |
|
1172 |
}; |
|
1173 |
TimeGridView.prototype.queryDateScroll = function () { |
|
1174 |
return { top: this.scroller.getScrollTop() }; |
|
1175 |
}; |
|
1176 |
TimeGridView.prototype.applyDateScroll = function (scroll) { |
|
1177 |
if (scroll.top !== undefined) { |
|
1178 |
this.scroller.setScrollTop(scroll.top); |
|
1179 |
} |
|
1180 |
}; |
|
1181 |
// Generates an HTML attribute string for setting the width of the axis, if it is known |
|
1182 |
TimeGridView.prototype.axisStyleAttr = function () { |
|
1183 |
if (this.axisWidth != null) { |
|
1184 |
return 'style="width:' + this.axisWidth + 'px"'; |
|
1185 |
} |
|
1186 |
return ''; |
|
1187 |
}; |
|
1188 |
return TimeGridView; |
|
1189 |
}(core.View)); |
|
1190 |
TimeGridView.prototype.usesMinMaxTime = true; // indicates that minTime/maxTime affects rendering |
|
1191 |
|
|
1192 |
var SimpleTimeGrid = /** @class */ (function (_super) { |
|
1193 |
__extends(SimpleTimeGrid, _super); |
|
1194 |
function SimpleTimeGrid(context, timeGrid) { |
|
1195 |
var _this = _super.call(this, context, timeGrid.el) || this; |
|
1196 |
_this.buildDayRanges = core.memoize(buildDayRanges); |
|
1197 |
_this.slicer = new TimeGridSlicer(); |
|
1198 |
_this.timeGrid = timeGrid; |
|
1199 |
context.calendar.registerInteractiveComponent(_this, { |
|
1200 |
el: _this.timeGrid.el |
|
1201 |
}); |
|
1202 |
return _this; |
|
1203 |
} |
|
1204 |
SimpleTimeGrid.prototype.destroy = function () { |
|
1205 |
_super.prototype.destroy.call(this); |
|
1206 |
this.calendar.unregisterInteractiveComponent(this); |
|
1207 |
}; |
|
1208 |
SimpleTimeGrid.prototype.render = function (props) { |
|
1209 |
var dateProfile = props.dateProfile, dayTable = props.dayTable; |
|
1210 |
var dayRanges = this.dayRanges = this.buildDayRanges(dayTable, dateProfile, this.dateEnv); |
|
1211 |
this.timeGrid.receiveProps(__assign({}, this.slicer.sliceProps(props, dateProfile, null, this.timeGrid, dayRanges), { dateProfile: dateProfile, cells: dayTable.cells[0] })); |
|
1212 |
}; |
|
1213 |
SimpleTimeGrid.prototype.renderNowIndicator = function (date) { |
|
1214 |
this.timeGrid.renderNowIndicator(this.slicer.sliceNowDate(date, this.timeGrid, this.dayRanges), date); |
|
1215 |
}; |
|
1216 |
SimpleTimeGrid.prototype.buildPositionCaches = function () { |
|
1217 |
this.timeGrid.buildPositionCaches(); |
|
1218 |
}; |
|
1219 |
SimpleTimeGrid.prototype.queryHit = function (positionLeft, positionTop) { |
|
1220 |
var rawHit = this.timeGrid.positionToHit(positionLeft, positionTop); |
|
1221 |
if (rawHit) { |
|
1222 |
return { |
|
1223 |
component: this.timeGrid, |
|
1224 |
dateSpan: rawHit.dateSpan, |
|
1225 |
dayEl: rawHit.dayEl, |
|
1226 |
rect: { |
|
1227 |
left: rawHit.relativeRect.left, |
|
1228 |
right: rawHit.relativeRect.right, |
|
1229 |
top: rawHit.relativeRect.top, |
|
1230 |
bottom: rawHit.relativeRect.bottom |
|
1231 |
}, |
|
1232 |
layer: 0 |
|
1233 |
}; |
|
1234 |
} |
|
1235 |
}; |
|
1236 |
return SimpleTimeGrid; |
|
1237 |
}(core.DateComponent)); |
|
1238 |
function buildDayRanges(dayTable, dateProfile, dateEnv) { |
|
1239 |
var ranges = []; |
|
1240 |
for (var _i = 0, _a = dayTable.headerDates; _i < _a.length; _i++) { |
|
1241 |
var date = _a[_i]; |
|
1242 |
ranges.push({ |
|
1243 |
start: dateEnv.add(date, dateProfile.minTime), |
|
1244 |
end: dateEnv.add(date, dateProfile.maxTime) |
|
1245 |
}); |
|
1246 |
} |
|
1247 |
return ranges; |
|
1248 |
} |
|
1249 |
var TimeGridSlicer = /** @class */ (function (_super) { |
|
1250 |
__extends(TimeGridSlicer, _super); |
|
1251 |
function TimeGridSlicer() { |
|
1252 |
return _super !== null && _super.apply(this, arguments) || this; |
|
1253 |
} |
|
1254 |
TimeGridSlicer.prototype.sliceRange = function (range, dayRanges) { |
|
1255 |
var segs = []; |
|
1256 |
for (var col = 0; col < dayRanges.length; col++) { |
|
1257 |
var segRange = core.intersectRanges(range, dayRanges[col]); |
|
1258 |
if (segRange) { |
|
1259 |
segs.push({ |
|
1260 |
start: segRange.start, |
|
1261 |
end: segRange.end, |
|
1262 |
isStart: segRange.start.valueOf() === range.start.valueOf(), |
|
1263 |
isEnd: segRange.end.valueOf() === range.end.valueOf(), |
|
1264 |
col: col |
|
1265 |
}); |
|
1266 |
} |
|
1267 |
} |
|
1268 |
return segs; |
|
1269 |
}; |
|
1270 |
return TimeGridSlicer; |
|
1271 |
}(core.Slicer)); |
|
1272 |
|
|
1273 |
var TimeGridView$1 = /** @class */ (function (_super) { |
|
1274 |
__extends(TimeGridView, _super); |
|
1275 |
function TimeGridView(_context, viewSpec, dateProfileGenerator, parentEl) { |
|
1276 |
var _this = _super.call(this, _context, viewSpec, dateProfileGenerator, parentEl) || this; |
|
1277 |
_this.buildDayTable = core.memoize(buildDayTable); |
|
1278 |
if (_this.opt('columnHeader')) { |
|
1279 |
_this.header = new core.DayHeader(_this.context, _this.el.querySelector('.fc-head-container')); |
|
1280 |
} |
|
1281 |
_this.simpleTimeGrid = new SimpleTimeGrid(_this.context, _this.timeGrid); |
|
1282 |
if (_this.dayGrid) { |
|
1283 |
_this.simpleDayGrid = new daygrid.SimpleDayGrid(_this.context, _this.dayGrid); |
|
1284 |
} |
|
1285 |
return _this; |
|
1286 |
} |
|
1287 |
TimeGridView.prototype.destroy = function () { |
|
1288 |
_super.prototype.destroy.call(this); |
|
1289 |
if (this.header) { |
|
1290 |
this.header.destroy(); |
|
1291 |
} |
|
1292 |
this.simpleTimeGrid.destroy(); |
|
1293 |
if (this.simpleDayGrid) { |
|
1294 |
this.simpleDayGrid.destroy(); |
|
1295 |
} |
|
1296 |
}; |
|
1297 |
TimeGridView.prototype.render = function (props) { |
|
1298 |
_super.prototype.render.call(this, props); // for flags for updateSize |
|
1299 |
var dateProfile = this.props.dateProfile; |
|
1300 |
var dayTable = this.buildDayTable(dateProfile, this.dateProfileGenerator); |
|
1301 |
var splitProps = this.splitter.splitProps(props); |
|
1302 |
if (this.header) { |
|
1303 |
this.header.receiveProps({ |
|
1304 |
dateProfile: dateProfile, |
|
1305 |
dates: dayTable.headerDates, |
|
1306 |
datesRepDistinctDays: true, |
|
1307 |
renderIntroHtml: this.renderHeadIntroHtml |
|
1308 |
}); |
|
1309 |
} |
|
1310 |
this.simpleTimeGrid.receiveProps(__assign({}, splitProps['timed'], { dateProfile: dateProfile, |
|
1311 |
dayTable: dayTable })); |
|
1312 |
if (this.simpleDayGrid) { |
|
1313 |
this.simpleDayGrid.receiveProps(__assign({}, splitProps['allDay'], { dateProfile: dateProfile, |
|
1314 |
dayTable: dayTable, nextDayThreshold: this.nextDayThreshold, isRigid: false })); |
|
1315 |
} |
|
1316 |
}; |
|
1317 |
TimeGridView.prototype.renderNowIndicator = function (date) { |
|
1318 |
this.simpleTimeGrid.renderNowIndicator(date); |
|
1319 |
}; |
|
1320 |
return TimeGridView; |
|
1321 |
}(TimeGridView)); |
|
1322 |
function buildDayTable(dateProfile, dateProfileGenerator) { |
|
1323 |
var daySeries = new core.DaySeries(dateProfile.renderRange, dateProfileGenerator); |
|
1324 |
return new core.DayTable(daySeries, false); |
|
1325 |
} |
|
1326 |
|
|
1327 |
var main = core.createPlugin({ |
|
1328 |
defaultView: 'timeGridWeek', |
|
1329 |
views: { |
|
1330 |
timeGrid: { |
|
1331 |
class: TimeGridView$1, |
|
1332 |
allDaySlot: true, |
|
1333 |
slotDuration: '00:30:00', |
|
1334 |
slotEventOverlap: true // a bad name. confused with overlap/constraint system |
|
1335 |
}, |
|
1336 |
timeGridDay: { |
|
1337 |
type: 'timeGrid', |
|
1338 |
duration: { days: 1 } |
|
1339 |
}, |
|
1340 |
timeGridWeek: { |
|
1341 |
type: 'timeGrid', |
|
1342 |
duration: { weeks: 1 } |
|
1343 |
} |
|
1344 |
} |
|
1345 |
}); |
|
1346 |
|
|
1347 |
exports.AbstractTimeGridView = TimeGridView; |
|
1348 |
exports.TimeGrid = TimeGrid; |
|
1349 |
exports.TimeGridSlicer = TimeGridSlicer; |
|
1350 |
exports.TimeGridView = TimeGridView$1; |
|
1351 |
exports.buildDayRanges = buildDayRanges; |
|
1352 |
exports.buildDayTable = buildDayTable; |
|
1353 |
exports.default = main; |
|
1354 |
|
|
1355 |
Object.defineProperty(exports, '__esModule', { value: true }); |
|
1356 |
|
|
1357 |
})); |