@fullcalendar/timeline 6.1.14 → 7.0.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.cjs +1 -2
- package/index.global.js +690 -594
- package/index.global.min.js +2 -2
- package/index.js +1 -2
- package/internal.cjs +688 -593
- package/internal.d.ts +138 -138
- package/internal.js +684 -592
- package/package.json +4 -4
package/internal.cjs
CHANGED
|
@@ -4,7 +4,9 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
4
4
|
|
|
5
5
|
var internal_cjs = require('@fullcalendar/core/internal.cjs');
|
|
6
6
|
var preact_cjs = require('@fullcalendar/core/preact.cjs');
|
|
7
|
-
|
|
7
|
+
|
|
8
|
+
var css_248z = ".fc-timeline-slots{z-index:1}.fc-timeline-slot-minor{border-style:dotted}.fc-timeline-now-indicator-container{bottom:0;left:0;overflow:hidden;position:absolute;right:0;top:0;z-index:4}.fc-timeline-now-indicator-arrow,.fc-timeline-now-indicator-line{border-color:var(--fc-now-indicator-color);border-style:solid;pointer-events:none;position:absolute;top:0}.fc-timeline-now-indicator-arrow{border-left-color:transparent;border-right-color:transparent;border-width:6px 5px 0;margin:0 -5px}.fc-timeline-now-indicator-line{border-width:0 0 0 1px;bottom:0}.fc-timeline-events{z-index:3}.fc-timeline-events-overlap-enabled{padding-bottom:10px}.fc-timeline-event{border-radius:0;font-size:var(--fc-small-font-size);margin-bottom:1px;z-index:1}.fc-timeline-event.fc-event-mirror{z-index:2}.fc-direction-ltr .fc-timeline-event.fc-event-end{margin-right:1px}.fc-direction-rtl .fc-timeline-event.fc-event-end{margin-left:1px}.fc-timeline-event-spacious{margin-bottom:0;padding-bottom:5px;padding-top:5px}.fc-timeline-event .fc-event-inner{align-items:center;display:flex;flex-direction:row;padding:2px 1px}.fc-timeline-event:not(.fc-event-end) .fc-event-inner:after,.fc-timeline-event:not(.fc-event-start) .fc-event-inner:before{border-color:transparent #000;border-style:solid;border-width:5px;content:\"\";flex-grow:0;flex-shrink:0;height:0;margin:0 1px;opacity:.5;width:0}.fc-direction-ltr .fc-timeline-event:not(.fc-event-start) .fc-event-inner:before,.fc-direction-rtl .fc-timeline-event:not(.fc-event-end) .fc-event-inner:after{border-left:0}.fc-direction-ltr .fc-timeline-event:not(.fc-event-end) .fc-event-inner:after,.fc-direction-rtl .fc-timeline-event:not(.fc-event-start) .fc-event-inner:before{border-right:0}.fc-timeline-event .fc-event-time{font-weight:700}.fc-timeline-event .fc-event-time,.fc-timeline-event .fc-event-title{padding:0 2px}.fc-timeline-more-link{align-items:flex-start;background:var(--fc-more-link-bg-color);color:var(--fc-more-link-text-color);cursor:pointer;display:flex;flex-direction:column;font-size:var(--fc-small-font-size);padding:1px}.fc-direction-ltr .fc-timeline-more-link{margin-right:1px}.fc-direction-rtl .fc-timeline-more-link{margin-left:1px}.fc-timeline-more-link-inner{padding:2px}.fc-timeline-bg{bottom:0;left:0;position:absolute;right:0;top:0;z-index:2}.fc-timeline-bg .fc-non-business{z-index:1}.fc-timeline-bg .fc-bg-event{z-index:2}.fc-timeline-bg .fc-highlight{z-index:3}.fc-timeline-bg-harness{bottom:0;position:absolute;top:0}";
|
|
9
|
+
internal_cjs.injectStyles(css_248z);
|
|
8
10
|
|
|
9
11
|
const MIN_AUTO_LABELS = 18; // more than `12` months but less that `24` hours
|
|
10
12
|
const MAX_AUTO_SLOTS_PER_LABEL = 6; // allows 6 10-min slots in an hour
|
|
@@ -444,152 +446,90 @@ function buildCellObject(date, text, rowUnit) {
|
|
|
444
446
|
return { date, text, rowUnit, colspan: 1, isWeekStart: false };
|
|
445
447
|
}
|
|
446
448
|
|
|
447
|
-
class
|
|
449
|
+
class TimelineSlatCell extends internal_cjs.BaseComponent {
|
|
448
450
|
constructor() {
|
|
449
451
|
super(...arguments);
|
|
450
|
-
|
|
451
|
-
this.
|
|
452
|
+
// ref
|
|
453
|
+
this.innerElRef = preact_cjs.createRef();
|
|
452
454
|
}
|
|
453
455
|
render() {
|
|
454
456
|
let { props, context } = this;
|
|
455
|
-
let { dateEnv, options } = context;
|
|
456
|
-
let {
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
dateMarker: cell.date,
|
|
464
|
-
text: cell.text,
|
|
465
|
-
dateEnv: context.dateEnv,
|
|
466
|
-
viewApi: context.viewApi,
|
|
467
|
-
});
|
|
468
|
-
return (preact_cjs.createElement(internal_cjs.ContentContainer, { elTag: "th", elClasses: [
|
|
457
|
+
let { dateEnv, options, theme } = context;
|
|
458
|
+
let { date, tDateProfile, isEm } = props;
|
|
459
|
+
let dateMeta = internal_cjs.getDateMeta(props.date, props.todayRange, props.nowDate, props.dateProfile);
|
|
460
|
+
let renderProps = Object.assign(Object.assign({ date: dateEnv.toDate(props.date) }, dateMeta), { view: context.viewApi });
|
|
461
|
+
return (preact_cjs.createElement(internal_cjs.ContentContainer, { elTag: "div", elClasses: [
|
|
462
|
+
'fc-flex-column',
|
|
463
|
+
'fc-align-start',
|
|
464
|
+
'fc-cell',
|
|
469
465
|
'fc-timeline-slot',
|
|
470
|
-
'fc-timeline-slot-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
466
|
+
'fc-timeline-slot-lane',
|
|
467
|
+
isEm ? 'fc-timeline-slot-em' : '',
|
|
468
|
+
tDateProfile.isTimeScale ? (internal_cjs.isInt(dateEnv.countDurationsBetween(// best to do this here?
|
|
469
|
+
tDateProfile.normalizedRange.start, props.date, tDateProfile.labelInterval)) ?
|
|
470
|
+
'fc-timeline-slot-major' :
|
|
471
|
+
'fc-timeline-slot-minor') : '',
|
|
472
|
+
...(props.isDay ?
|
|
473
|
+
internal_cjs.getDayClassNames(dateMeta, theme) :
|
|
474
|
+
internal_cjs.getSlotClassNames(dateMeta, theme)),
|
|
476
475
|
], elAttrs: {
|
|
477
|
-
|
|
478
|
-
'data-date': dateEnv.formatIso(cell.date, {
|
|
479
|
-
omitTime: !tDateProfile.isTimeScale,
|
|
476
|
+
'data-date': dateEnv.formatIso(date, {
|
|
480
477
|
omitTimeZoneOffset: true,
|
|
478
|
+
omitTime: !tDateProfile.isTimeScale,
|
|
481
479
|
}),
|
|
482
|
-
},
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
props.isSticky && 'fc-sticky',
|
|
487
|
-
], elAttrs: this.buildCellNavLinkAttrs(context, cell.date, cell.rowUnit) })))));
|
|
480
|
+
}, elStyle: {
|
|
481
|
+
width: props.width,
|
|
482
|
+
}, renderProps: renderProps, generatorName: "slotLaneContent", customGenerator: options.slotLaneContent, classNameGenerator: options.slotLaneClassNames, didMount: options.slotLaneDidMount, willUnmount: options.slotLaneWillUnmount }, (InnerContent) => (preact_cjs.createElement("div", { ref: this.innerElRef, className: 'fc-flex-column' },
|
|
483
|
+
preact_cjs.createElement(InnerContent, { elTag: "div", elClasses: ['fc-cell-inner'] })))));
|
|
488
484
|
}
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
}
|
|
498
|
-
function refineRenderProps(input) {
|
|
499
|
-
return {
|
|
500
|
-
level: input.level,
|
|
501
|
-
date: input.dateEnv.toDate(input.dateMarker),
|
|
502
|
-
view: input.viewApi,
|
|
503
|
-
text: input.text,
|
|
504
|
-
};
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
class TimelineHeaderRows extends internal_cjs.BaseComponent {
|
|
508
|
-
render() {
|
|
509
|
-
let { dateProfile, tDateProfile, rowInnerHeights, todayRange, nowDate } = this.props;
|
|
510
|
-
let { cellRows } = tDateProfile;
|
|
511
|
-
return (preact_cjs.createElement(preact_cjs.Fragment, null, cellRows.map((rowCells, rowLevel) => {
|
|
512
|
-
let isLast = rowLevel === cellRows.length - 1;
|
|
513
|
-
let isChrono = tDateProfile.isTimeScale && isLast; // the final row, with times?
|
|
514
|
-
let classNames = [
|
|
515
|
-
'fc-timeline-header-row',
|
|
516
|
-
isChrono ? 'fc-timeline-header-row-chrono' : '',
|
|
517
|
-
];
|
|
518
|
-
return ( // eslint-disable-next-line react/no-array-index-key
|
|
519
|
-
preact_cjs.createElement("tr", { key: rowLevel, className: classNames.join(' ') }, rowCells.map((cell) => (preact_cjs.createElement(TimelineHeaderTh, { key: cell.date.toISOString(), cell: cell, rowLevel: rowLevel, dateProfile: dateProfile, tDateProfile: tDateProfile, todayRange: todayRange, nowDate: nowDate, rowInnerHeight: rowInnerHeights && rowInnerHeights[rowLevel], isSticky: !isLast })))));
|
|
520
|
-
})));
|
|
485
|
+
componentDidMount() {
|
|
486
|
+
const innerEl = this.innerElRef.current;
|
|
487
|
+
this.detachWidth = internal_cjs.watchWidth(innerEl, (width) => {
|
|
488
|
+
internal_cjs.setRef(this.props.innerWidthRef, width);
|
|
489
|
+
});
|
|
490
|
+
}
|
|
491
|
+
componentWillUnmount() {
|
|
492
|
+
this.detachWidth();
|
|
521
493
|
}
|
|
522
494
|
}
|
|
523
495
|
|
|
524
|
-
class
|
|
525
|
-
constructor(
|
|
526
|
-
|
|
527
|
-
this.
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
this.
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
// used for event rendering and scrollTime, to disregard slat border
|
|
536
|
-
this.innerCoordCache = new internal_cjs.PositionCache(slatRootEl, internal_cjs.findDirectChildren(slatEls, 'div'), true, // isHorizontal
|
|
537
|
-
false);
|
|
538
|
-
}
|
|
539
|
-
isDateInRange(date) {
|
|
540
|
-
return internal_cjs.rangeContainsMarker(this.dateProfile.currentRange, date);
|
|
541
|
-
}
|
|
542
|
-
// results range from negative width of area to 0
|
|
543
|
-
dateToCoord(date) {
|
|
544
|
-
let { tDateProfile } = this;
|
|
545
|
-
let snapCoverage = this.computeDateSnapCoverage(date);
|
|
546
|
-
let slotCoverage = snapCoverage / tDateProfile.snapsPerSlot;
|
|
547
|
-
let slotIndex = Math.floor(slotCoverage);
|
|
548
|
-
slotIndex = Math.min(slotIndex, tDateProfile.slotCnt - 1);
|
|
549
|
-
let partial = slotCoverage - slotIndex;
|
|
550
|
-
let { innerCoordCache, outerCoordCache } = this;
|
|
551
|
-
if (this.isRtl) {
|
|
552
|
-
return outerCoordCache.originClientRect.width - (outerCoordCache.rights[slotIndex] -
|
|
553
|
-
(innerCoordCache.getWidth(slotIndex) * partial));
|
|
554
|
-
}
|
|
555
|
-
return (outerCoordCache.lefts[slotIndex] +
|
|
556
|
-
(innerCoordCache.getWidth(slotIndex) * partial));
|
|
557
|
-
}
|
|
558
|
-
rangeToCoords(range) {
|
|
559
|
-
return {
|
|
560
|
-
start: this.dateToCoord(range.start),
|
|
561
|
-
end: this.dateToCoord(range.end),
|
|
562
|
-
};
|
|
563
|
-
}
|
|
564
|
-
durationToCoord(duration) {
|
|
565
|
-
let { dateProfile, tDateProfile, dateEnv, isRtl } = this;
|
|
566
|
-
let coord = 0;
|
|
567
|
-
if (dateProfile) {
|
|
568
|
-
let date = dateEnv.add(dateProfile.activeRange.start, duration);
|
|
569
|
-
if (!tDateProfile.isTimeScale) {
|
|
570
|
-
date = internal_cjs.startOfDay(date);
|
|
571
|
-
}
|
|
572
|
-
coord = this.dateToCoord(date);
|
|
573
|
-
// hack to overcome the left borders of non-first slat
|
|
574
|
-
if (!isRtl && coord) {
|
|
575
|
-
coord += 1;
|
|
496
|
+
class TimelineSlats extends internal_cjs.BaseComponent {
|
|
497
|
+
constructor() {
|
|
498
|
+
super(...arguments);
|
|
499
|
+
this.innerWidthRefMap = new internal_cjs.RefMap(() => {
|
|
500
|
+
internal_cjs.afterSize(this.handleInnerWidths);
|
|
501
|
+
});
|
|
502
|
+
this.handleInnerWidths = () => {
|
|
503
|
+
const innerWidthMap = this.innerWidthRefMap.current;
|
|
504
|
+
let max = 0;
|
|
505
|
+
for (const innerWidth of innerWidthMap.values()) {
|
|
506
|
+
max = Math.max(max, innerWidth);
|
|
576
507
|
}
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
coordFromLeft(coord) {
|
|
581
|
-
if (this.isRtl) {
|
|
582
|
-
return this.outerCoordCache.originClientRect.width - coord;
|
|
583
|
-
}
|
|
584
|
-
return coord;
|
|
508
|
+
// TODO: check to see if changed before firing ref!? YES. do in other places too
|
|
509
|
+
internal_cjs.setRef(this.props.innerWidthRef, max);
|
|
510
|
+
};
|
|
585
511
|
}
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
512
|
+
render() {
|
|
513
|
+
let { props, innerWidthRefMap } = this;
|
|
514
|
+
let { tDateProfile, slotWidth } = props;
|
|
515
|
+
let { slotDates, isWeekStarts } = tDateProfile;
|
|
516
|
+
let isDay = !tDateProfile.isTimeScale && !tDateProfile.largeUnit;
|
|
517
|
+
return (preact_cjs.createElement("div", { className: "fc-timeline-slots fc-fill fc-flex-row" }, slotDates.map((slotDate, i) => {
|
|
518
|
+
let key = slotDate.toISOString();
|
|
519
|
+
return (preact_cjs.createElement(TimelineSlatCell, { key: key, date: slotDate, dateProfile: props.dateProfile, tDateProfile: tDateProfile, nowDate: props.nowDate, todayRange: props.todayRange, isEm: isWeekStarts[i], isDay: isDay,
|
|
520
|
+
// ref
|
|
521
|
+
innerWidthRef: innerWidthRefMap.createRef(key),
|
|
522
|
+
// dimensions
|
|
523
|
+
width: slotWidth }));
|
|
524
|
+
})));
|
|
589
525
|
}
|
|
590
526
|
}
|
|
527
|
+
|
|
528
|
+
/*
|
|
529
|
+
TODO: rename this file!
|
|
530
|
+
*/
|
|
591
531
|
// returned value is between 0 and the number of snaps
|
|
592
|
-
function computeDateSnapCoverage(date, tDateProfile, dateEnv) {
|
|
532
|
+
function computeDateSnapCoverage$1(date, tDateProfile, dateEnv) {
|
|
593
533
|
let snapDiff = dateEnv.countDurationsBetween(tDateProfile.normalizedRange.start, date, tDateProfile.snapDuration);
|
|
594
534
|
if (snapDiff < 0) {
|
|
595
535
|
return 0;
|
|
@@ -609,6 +549,9 @@ function computeDateSnapCoverage(date, tDateProfile, dateEnv) {
|
|
|
609
549
|
}
|
|
610
550
|
return snapCoverage;
|
|
611
551
|
}
|
|
552
|
+
/*
|
|
553
|
+
TODO: audit!!!
|
|
554
|
+
*/
|
|
612
555
|
function coordToCss(hcoord, isRtl) {
|
|
613
556
|
if (hcoord === null) {
|
|
614
557
|
return { left: '', right: '' };
|
|
@@ -618,6 +561,9 @@ function coordToCss(hcoord, isRtl) {
|
|
|
618
561
|
}
|
|
619
562
|
return { left: hcoord, right: '' };
|
|
620
563
|
}
|
|
564
|
+
/*
|
|
565
|
+
TODO: audit!!!
|
|
566
|
+
*/
|
|
621
567
|
function coordsToCss(hcoords, isRtl) {
|
|
622
568
|
if (!hcoords) {
|
|
623
569
|
return { left: '', right: '' };
|
|
@@ -627,216 +573,141 @@ function coordsToCss(hcoords, isRtl) {
|
|
|
627
573
|
}
|
|
628
574
|
return { left: hcoords.start, right: -hcoords.end };
|
|
629
575
|
}
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
render() {
|
|
637
|
-
let { props, context } = this;
|
|
638
|
-
// TODO: very repetitive
|
|
639
|
-
// TODO: make part of tDateProfile?
|
|
640
|
-
let timerUnit = internal_cjs.greatestDurationDenominator(props.tDateProfile.slotDuration).unit;
|
|
641
|
-
// WORKAROUND: make ignore slatCoords when out of sync with dateProfile
|
|
642
|
-
let slatCoords = props.slatCoords && props.slatCoords.dateProfile === props.dateProfile ? props.slatCoords : null;
|
|
643
|
-
return (preact_cjs.createElement(internal_cjs.NowTimer, { unit: timerUnit }, (nowDate, todayRange) => (preact_cjs.createElement("div", { className: "fc-timeline-header", ref: this.rootElRef },
|
|
644
|
-
preact_cjs.createElement("table", { "aria-hidden": true, className: "fc-scrollgrid-sync-table", style: { minWidth: props.tableMinWidth, width: props.clientWidth } },
|
|
645
|
-
props.tableColGroupNode,
|
|
646
|
-
preact_cjs.createElement("tbody", null,
|
|
647
|
-
preact_cjs.createElement(TimelineHeaderRows, { dateProfile: props.dateProfile, tDateProfile: props.tDateProfile, nowDate: nowDate, todayRange: todayRange, rowInnerHeights: props.rowInnerHeights }))),
|
|
648
|
-
context.options.nowIndicator && (
|
|
649
|
-
// need to have a container regardless of whether the current view has a visible now indicator
|
|
650
|
-
// because apparently removal of the element resets the scroll for some reasons (issue #5351).
|
|
651
|
-
// this issue doesn't happen for the timeline body however (
|
|
652
|
-
preact_cjs.createElement("div", { className: "fc-timeline-now-indicator-container" }, (slatCoords && slatCoords.isDateInRange(nowDate)) && (preact_cjs.createElement(internal_cjs.NowIndicatorContainer, { elClasses: ['fc-timeline-now-indicator-arrow'], elStyle: coordToCss(slatCoords.dateToCoord(nowDate), context.isRtl), isAxis: true, date: nowDate }))))))));
|
|
576
|
+
/*
|
|
577
|
+
TODO: DRY up with elsewhere?
|
|
578
|
+
*/
|
|
579
|
+
function horizontalsToCss(hcoord, isRtl) {
|
|
580
|
+
if (!hcoord) {
|
|
581
|
+
return {};
|
|
653
582
|
}
|
|
654
|
-
|
|
655
|
-
|
|
583
|
+
if (isRtl) {
|
|
584
|
+
return { right: hcoord.start, width: hcoord.size };
|
|
656
585
|
}
|
|
657
|
-
|
|
658
|
-
|
|
586
|
+
else {
|
|
587
|
+
return { left: hcoord.start, width: hcoord.size };
|
|
659
588
|
}
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
}
|
|
589
|
+
}
|
|
590
|
+
function horizontalCoordToCss(start, isRtl) {
|
|
591
|
+
if (isRtl) {
|
|
592
|
+
return { right: start };
|
|
664
593
|
}
|
|
665
|
-
|
|
666
|
-
return
|
|
594
|
+
else {
|
|
595
|
+
return { left: start };
|
|
667
596
|
}
|
|
668
597
|
}
|
|
669
598
|
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
let renderProps = Object.assign(Object.assign({ date: dateEnv.toDate(props.date) }, dateMeta), { view: context.viewApi });
|
|
677
|
-
return (preact_cjs.createElement(internal_cjs.ContentContainer, { elTag: "td", elRef: props.elRef, elClasses: [
|
|
678
|
-
'fc-timeline-slot',
|
|
679
|
-
'fc-timeline-slot-lane',
|
|
680
|
-
isEm && 'fc-timeline-slot-em',
|
|
681
|
-
tDateProfile.isTimeScale ? (internal_cjs.isInt(dateEnv.countDurationsBetween(tDateProfile.normalizedRange.start, props.date, tDateProfile.labelInterval)) ?
|
|
682
|
-
'fc-timeline-slot-major' :
|
|
683
|
-
'fc-timeline-slot-minor') : '',
|
|
684
|
-
...(props.isDay ?
|
|
685
|
-
internal_cjs.getDayClassNames(dateMeta, theme) :
|
|
686
|
-
internal_cjs.getSlotClassNames(dateMeta, theme)),
|
|
687
|
-
], elAttrs: {
|
|
688
|
-
'data-date': dateEnv.formatIso(date, {
|
|
689
|
-
omitTimeZoneOffset: true,
|
|
690
|
-
omitTime: !tDateProfile.isTimeScale,
|
|
691
|
-
}),
|
|
692
|
-
}, renderProps: renderProps, generatorName: "slotLaneContent", customGenerator: options.slotLaneContent, classNameGenerator: options.slotLaneClassNames, didMount: options.slotLaneDidMount, willUnmount: options.slotLaneWillUnmount }, (InnerContent) => (preact_cjs.createElement(InnerContent, { elTag: "div" }))));
|
|
599
|
+
function createVerticalStyle(props) {
|
|
600
|
+
if (props) {
|
|
601
|
+
return {
|
|
602
|
+
top: props.start,
|
|
603
|
+
height: props.size,
|
|
604
|
+
};
|
|
693
605
|
}
|
|
694
606
|
}
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
let isDay = !tDateProfile.isTimeScale && !tDateProfile.largeUnit;
|
|
702
|
-
return (preact_cjs.createElement("tbody", null,
|
|
703
|
-
preact_cjs.createElement("tr", null, slotDates.map((slotDate, i) => {
|
|
704
|
-
let key = slotDate.toISOString();
|
|
705
|
-
return (preact_cjs.createElement(TimelineSlatCell, { key: key, elRef: cellElRefs.createRef(key), date: slotDate, dateProfile: props.dateProfile, tDateProfile: tDateProfile, nowDate: props.nowDate, todayRange: props.todayRange, isEm: isWeekStarts[i], isDay: isDay }));
|
|
706
|
-
}))));
|
|
607
|
+
function createHorizontalStyle(props, isRtl) {
|
|
608
|
+
if (props) {
|
|
609
|
+
return {
|
|
610
|
+
[isRtl ? 'right' : 'left']: props.start,
|
|
611
|
+
width: props.size,
|
|
612
|
+
};
|
|
707
613
|
}
|
|
708
614
|
}
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
};
|
|
615
|
+
// Timeline-specific
|
|
616
|
+
// -------------------------------------------------------------------------------------------------
|
|
617
|
+
const MIN_SLOT_WIDTH = 30; // for real
|
|
618
|
+
/*
|
|
619
|
+
TODO: DRY with computeSlatHeight?
|
|
620
|
+
*/
|
|
621
|
+
function computeSlotWidth(slatCnt, slatsPerLabel, slatMinWidth, labelInnerWidth, viewportWidth) {
|
|
622
|
+
if (labelInnerWidth == null || viewportWidth == null) {
|
|
623
|
+
return [undefined, undefined, false];
|
|
624
|
+
}
|
|
625
|
+
slatMinWidth = Math.max(slatMinWidth || 0, (labelInnerWidth + 1) / slatsPerLabel, MIN_SLOT_WIDTH);
|
|
626
|
+
const slatTryWidth = viewportWidth / slatCnt;
|
|
627
|
+
let slatLiquid;
|
|
628
|
+
let slatWidth;
|
|
629
|
+
if (slatTryWidth >= slatMinWidth) {
|
|
630
|
+
slatLiquid = true;
|
|
631
|
+
slatWidth = slatTryWidth;
|
|
727
632
|
}
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
preact_cjs.createElement("table", { "aria-hidden": true, className: context.theme.getClass('table'), style: {
|
|
732
|
-
minWidth: props.tableMinWidth,
|
|
733
|
-
width: props.clientWidth,
|
|
734
|
-
} },
|
|
735
|
-
props.tableColGroupNode,
|
|
736
|
-
preact_cjs.createElement(TimelineSlatsBody, { cellElRefs: this.cellElRefs, dateProfile: props.dateProfile, tDateProfile: props.tDateProfile, nowDate: props.nowDate, todayRange: props.todayRange }))));
|
|
633
|
+
else {
|
|
634
|
+
slatLiquid = false;
|
|
635
|
+
slatWidth = Math.max(slatMinWidth, slatTryWidth);
|
|
737
636
|
}
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
637
|
+
return [slatWidth * slatCnt, slatWidth, slatLiquid];
|
|
638
|
+
}
|
|
639
|
+
function timeToCoord(// pixels
|
|
640
|
+
time, dateEnv, dateProfile, tDateProfile, slowWidth) {
|
|
641
|
+
let date = dateEnv.add(dateProfile.activeRange.start, time);
|
|
642
|
+
if (!tDateProfile.isTimeScale) {
|
|
643
|
+
date = internal_cjs.startOfDay(date);
|
|
741
644
|
}
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
645
|
+
return dateToCoord(date, dateEnv, tDateProfile, slowWidth);
|
|
646
|
+
}
|
|
647
|
+
function dateToCoord(// pixels
|
|
648
|
+
date, dateEnv, tDateProfile, slotWidth) {
|
|
649
|
+
let snapCoverage = computeDateSnapCoverage(date, tDateProfile, dateEnv);
|
|
650
|
+
let slotCoverage = snapCoverage / tDateProfile.snapsPerSlot;
|
|
651
|
+
return slotCoverage * slotWidth;
|
|
652
|
+
}
|
|
653
|
+
/*
|
|
654
|
+
returned value is between 0 and the number of snaps
|
|
655
|
+
*/
|
|
656
|
+
function computeDateSnapCoverage(date, tDateProfile, dateEnv) {
|
|
657
|
+
let snapDiff = dateEnv.countDurationsBetween(tDateProfile.normalizedRange.start, date, tDateProfile.snapDuration);
|
|
658
|
+
if (snapDiff < 0) {
|
|
659
|
+
return 0;
|
|
745
660
|
}
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
if (this.props.onCoords) {
|
|
749
|
-
this.props.onCoords(null);
|
|
750
|
-
}
|
|
661
|
+
if (snapDiff >= tDateProfile.snapDiffToIndex.length) {
|
|
662
|
+
return tDateProfile.snapCnt;
|
|
751
663
|
}
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
// ^it's possible to have clientWidth immediately after mount (when returning from print view), but w/o scrollResponder
|
|
757
|
-
) {
|
|
758
|
-
let rootEl = this.rootElRef.current;
|
|
759
|
-
if (rootEl.offsetWidth) { // not hidden by css
|
|
760
|
-
this.coords = new TimelineCoords(this.rootElRef.current, collectCellEls(this.cellElRefs.currentMap, props.tDateProfile.slotDates), props.dateProfile, props.tDateProfile, context.dateEnv, context.isRtl);
|
|
761
|
-
if (props.onCoords) {
|
|
762
|
-
props.onCoords(this.coords);
|
|
763
|
-
}
|
|
764
|
-
this.scrollResponder.update(false); // TODO: wouldn't have to do this if coords were in state
|
|
765
|
-
}
|
|
766
|
-
}
|
|
664
|
+
let snapDiffInt = Math.floor(snapDiff);
|
|
665
|
+
let snapCoverage = tDateProfile.snapDiffToIndex[snapDiffInt];
|
|
666
|
+
if (internal_cjs.isInt(snapCoverage)) { // not an in-between value
|
|
667
|
+
snapCoverage += snapDiff - snapDiffInt; // add the remainder
|
|
767
668
|
}
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
let slatIndex = outerCoordCache.leftToIndex(leftPosition);
|
|
773
|
-
if (slatIndex != null) {
|
|
774
|
-
// somewhat similar to what TimeGrid does. consolidate?
|
|
775
|
-
let slatWidth = outerCoordCache.getWidth(slatIndex);
|
|
776
|
-
let partial = isRtl ?
|
|
777
|
-
(outerCoordCache.rights[slatIndex] - leftPosition) / slatWidth :
|
|
778
|
-
(leftPosition - outerCoordCache.lefts[slatIndex]) / slatWidth;
|
|
779
|
-
let localSnapIndex = Math.floor(partial * tDateProfile.snapsPerSlot);
|
|
780
|
-
let start = dateEnv.add(tDateProfile.slotDates[slatIndex], internal_cjs.multiplyDuration(tDateProfile.snapDuration, localSnapIndex));
|
|
781
|
-
let end = dateEnv.add(start, tDateProfile.snapDuration);
|
|
782
|
-
return {
|
|
783
|
-
dateSpan: {
|
|
784
|
-
range: { start, end },
|
|
785
|
-
allDay: !this.props.tDateProfile.isTimeScale,
|
|
786
|
-
},
|
|
787
|
-
dayEl: this.cellElRefs.currentMap[slatIndex],
|
|
788
|
-
left: outerCoordCache.lefts[slatIndex],
|
|
789
|
-
right: outerCoordCache.rights[slatIndex],
|
|
790
|
-
};
|
|
791
|
-
}
|
|
792
|
-
return null;
|
|
669
|
+
else {
|
|
670
|
+
// a fractional value, meaning the date is not visible
|
|
671
|
+
// always round up in this case. works for start AND end dates in a range.
|
|
672
|
+
snapCoverage = Math.ceil(snapCoverage);
|
|
793
673
|
}
|
|
794
|
-
|
|
795
|
-
function collectCellEls(elMap, slotDates) {
|
|
796
|
-
return slotDates.map((slotDate) => {
|
|
797
|
-
let key = slotDate.toISOString();
|
|
798
|
-
return elMap[key];
|
|
799
|
-
});
|
|
674
|
+
return snapCoverage;
|
|
800
675
|
}
|
|
801
676
|
|
|
802
|
-
function
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
let res = timelineCoords.rangeToCoords(seg);
|
|
807
|
-
let start = Math.round(res.start); // for barely-overlapping collisions
|
|
808
|
-
let end = Math.round(res.end); //
|
|
809
|
-
if (end - start < minWidth) {
|
|
810
|
-
end = start + minWidth;
|
|
811
|
-
}
|
|
812
|
-
hcoords.push({ start, end });
|
|
813
|
-
}
|
|
677
|
+
function computeManySegHorizontals(segs, segMinWidth, dateEnv, tDateProfile, slotWidth) {
|
|
678
|
+
const res = {};
|
|
679
|
+
for (const seg of segs) {
|
|
680
|
+
res[seg.eventRange.instance.instanceId] = computeSegHorizontals(seg, segMinWidth, dateEnv, tDateProfile, slotWidth);
|
|
814
681
|
}
|
|
815
|
-
return
|
|
682
|
+
return res;
|
|
683
|
+
}
|
|
684
|
+
function computeSegHorizontals(seg, segMinWidth, dateEnv, tDateProfile, slotWidth) {
|
|
685
|
+
const startCoord = dateToCoord(seg.start, dateEnv, tDateProfile, slotWidth);
|
|
686
|
+
const endCoord = dateToCoord(seg.end, dateEnv, tDateProfile, slotWidth);
|
|
687
|
+
let size = endCoord - startCoord;
|
|
688
|
+
if (segMinWidth) {
|
|
689
|
+
size = Math.max(size, segMinWidth);
|
|
690
|
+
}
|
|
691
|
+
return { start: startCoord, size };
|
|
816
692
|
}
|
|
817
|
-
function computeFgSegPlacements(
|
|
818
|
-
|
|
819
|
-
moreLinkHeights, // might not have for every more-link
|
|
693
|
+
function computeFgSegPlacements(// mostly horizontals
|
|
694
|
+
segs, segHorizontals, segHeights, // keyed by instanceId
|
|
820
695
|
strictOrder, maxStackCnt) {
|
|
821
|
-
let
|
|
822
|
-
let crudePlacements = []; // when we don't know dims
|
|
696
|
+
let segEntries = [];
|
|
823
697
|
for (let i = 0; i < segs.length; i += 1) {
|
|
824
698
|
let seg = segs[i];
|
|
825
699
|
let instanceId = seg.eventRange.instance.instanceId;
|
|
826
|
-
let height =
|
|
827
|
-
let hcoords =
|
|
828
|
-
if (height && hcoords) {
|
|
829
|
-
|
|
700
|
+
let height = segHeights.get(instanceId);
|
|
701
|
+
let hcoords = segHorizontals[instanceId];
|
|
702
|
+
if (height != null && hcoords != null) {
|
|
703
|
+
segEntries.push({
|
|
830
704
|
index: i,
|
|
831
|
-
span: hcoords,
|
|
832
|
-
thickness: height,
|
|
833
|
-
});
|
|
834
|
-
}
|
|
835
|
-
else {
|
|
836
|
-
crudePlacements.push({
|
|
837
705
|
seg,
|
|
838
|
-
|
|
839
|
-
|
|
706
|
+
span: {
|
|
707
|
+
start: hcoords.start,
|
|
708
|
+
end: hcoords.start + hcoords.size,
|
|
709
|
+
},
|
|
710
|
+
thickness: height,
|
|
840
711
|
});
|
|
841
712
|
}
|
|
842
713
|
}
|
|
@@ -847,80 +718,85 @@ strictOrder, maxStackCnt) {
|
|
|
847
718
|
if (maxStackCnt != null) {
|
|
848
719
|
hierarchy.maxStackCnt = maxStackCnt;
|
|
849
720
|
}
|
|
850
|
-
let hiddenEntries = hierarchy.addSegs(
|
|
851
|
-
let hiddenPlacements = hiddenEntries.map((entry) => ({
|
|
852
|
-
seg: segs[entry.index],
|
|
853
|
-
hcoords: entry.span,
|
|
854
|
-
top: null,
|
|
855
|
-
}));
|
|
721
|
+
let hiddenEntries = hierarchy.addSegs(segEntries);
|
|
856
722
|
let hiddenGroups = internal_cjs.groupIntersectingEntries(hiddenEntries);
|
|
857
|
-
let
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
let height = moreLinkHeights[internal_cjs.buildIsoString(internal_cjs.computeEarliestSegStart(sortedSegs))]; // not optimal :(
|
|
864
|
-
if (height != null) {
|
|
865
|
-
// NOTE: the hiddenGroup's spanStart/spanEnd are already computed by rangeToCoords. computed during input.
|
|
866
|
-
moreLinkInputs.push({
|
|
867
|
-
index: segs.length + i,
|
|
868
|
-
thickness: height,
|
|
869
|
-
span: hiddenGroup.span,
|
|
870
|
-
});
|
|
871
|
-
}
|
|
872
|
-
else {
|
|
873
|
-
moreLinkCrudePlacements.push({
|
|
874
|
-
seg: sortedSegs,
|
|
875
|
-
hcoords: hiddenGroup.span,
|
|
876
|
-
top: null,
|
|
877
|
-
});
|
|
878
|
-
}
|
|
879
|
-
}
|
|
723
|
+
let hiddenGroupEntries = hiddenGroups.map((hiddenGroup, index) => ({
|
|
724
|
+
index: segs.length + index,
|
|
725
|
+
segGroup: hiddenGroup,
|
|
726
|
+
span: hiddenGroup.span,
|
|
727
|
+
thickness: 1, // HACK to ensure it's placed
|
|
728
|
+
}));
|
|
880
729
|
// add more-links into the hierarchy, but don't limit
|
|
881
730
|
hierarchy.maxStackCnt = -1;
|
|
882
|
-
hierarchy.addSegs(
|
|
731
|
+
hierarchy.addSegs(hiddenGroupEntries);
|
|
883
732
|
let visibleRects = hierarchy.toRects();
|
|
884
|
-
let
|
|
885
|
-
let
|
|
733
|
+
let segTops = {};
|
|
734
|
+
let hiddenGroupTops = {};
|
|
886
735
|
for (let rect of visibleRects) {
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
seg
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
});
|
|
895
|
-
maxHeight = Math.max(maxHeight, rect.levelCoord + rect.thickness);
|
|
736
|
+
const { seg, segGroup } = rect;
|
|
737
|
+
if (seg) { // regular seg
|
|
738
|
+
segTops[seg.eventRange.instance.instanceId] = rect.levelCoord;
|
|
739
|
+
}
|
|
740
|
+
else { // hiddenGroup
|
|
741
|
+
hiddenGroupTops[segGroup.key] = rect.levelCoord;
|
|
742
|
+
}
|
|
896
743
|
}
|
|
897
744
|
return [
|
|
898
|
-
|
|
899
|
-
|
|
745
|
+
segTops,
|
|
746
|
+
computeMaxBottom(segs, segTops, segHeights),
|
|
747
|
+
hiddenGroups,
|
|
748
|
+
hiddenGroupTops,
|
|
900
749
|
];
|
|
901
750
|
}
|
|
751
|
+
function computeMaxBottom(segs, segTops, segHeights) {
|
|
752
|
+
let max = 0;
|
|
753
|
+
for (const seg of segs) {
|
|
754
|
+
const { instanceId } = seg.eventRange.instance;
|
|
755
|
+
const top = segTops[instanceId];
|
|
756
|
+
const height = segHeights.get(instanceId);
|
|
757
|
+
if (top != null && height != null) {
|
|
758
|
+
max = Math.max(max, top + height);
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
return max;
|
|
762
|
+
}
|
|
763
|
+
/*
|
|
764
|
+
TODO: converge with computeMaxBottom, but keys are different
|
|
765
|
+
*/
|
|
766
|
+
function computeMoreLinkMaxBottom(hiddenGroups, hiddenGroupTops, hiddenGroupHeights) {
|
|
767
|
+
let max = 0;
|
|
768
|
+
for (const hiddenGroup of hiddenGroups) {
|
|
769
|
+
const top = hiddenGroupTops[hiddenGroup.key];
|
|
770
|
+
const height = hiddenGroupHeights.get(hiddenGroup.key);
|
|
771
|
+
if (top != null && height != null) {
|
|
772
|
+
max = Math.max(max, top + height);
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
return max;
|
|
776
|
+
}
|
|
902
777
|
|
|
903
778
|
class TimelineLaneBg extends internal_cjs.BaseComponent {
|
|
904
779
|
render() {
|
|
905
780
|
let { props } = this;
|
|
906
781
|
let highlightSeg = [].concat(props.eventResizeSegs, props.dateSelectionSegs);
|
|
907
|
-
return
|
|
908
|
-
this.renderSegs(props.businessHourSegs || [],
|
|
909
|
-
this.renderSegs(props.bgEventSegs || [],
|
|
910
|
-
this.renderSegs(highlightSeg,
|
|
911
|
-
}
|
|
912
|
-
renderSegs(segs,
|
|
913
|
-
let { todayRange, nowDate } = this.props;
|
|
914
|
-
let { isRtl } = this.context;
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
782
|
+
return (preact_cjs.createElement("div", { className: "fc-timeline-bg" },
|
|
783
|
+
this.renderSegs(props.businessHourSegs || [], 'non-business'),
|
|
784
|
+
this.renderSegs(props.bgEventSegs || [], 'bg-event'),
|
|
785
|
+
this.renderSegs(highlightSeg, 'highlight')));
|
|
786
|
+
}
|
|
787
|
+
renderSegs(segs, fillType) {
|
|
788
|
+
let { tDateProfile, todayRange, nowDate, slotWidth } = this.props;
|
|
789
|
+
let { dateEnv, isRtl } = this.context;
|
|
790
|
+
return (preact_cjs.createElement(preact_cjs.Fragment, null, segs.map((seg) => {
|
|
791
|
+
let hStyle; // TODO
|
|
792
|
+
if (slotWidth != null) {
|
|
793
|
+
let segHorizontal = computeSegHorizontals(seg, undefined, dateEnv, tDateProfile, slotWidth);
|
|
794
|
+
hStyle = horizontalsToCss(segHorizontal, isRtl);
|
|
795
|
+
}
|
|
919
796
|
return (preact_cjs.createElement("div", { key: internal_cjs.buildEventRangeKey(seg.eventRange), className: "fc-timeline-bg-harness", style: hStyle }, fillType === 'bg-event' ?
|
|
920
797
|
preact_cjs.createElement(internal_cjs.BgEvent, Object.assign({ seg: seg }, internal_cjs.getSegMeta(seg, todayRange, nowDate))) :
|
|
921
798
|
internal_cjs.renderFill(fillType)));
|
|
922
|
-
});
|
|
923
|
-
return preact_cjs.createElement(preact_cjs.Fragment, null, children);
|
|
799
|
+
})));
|
|
924
800
|
}
|
|
925
801
|
}
|
|
926
802
|
|
|
@@ -929,8 +805,8 @@ class TimelineLaneSlicer extends internal_cjs.Slicer {
|
|
|
929
805
|
let normalRange = normalizeRange(origRange, tDateProfile, dateEnv);
|
|
930
806
|
let segs = [];
|
|
931
807
|
// protect against when the span is entirely in an invalid date region
|
|
932
|
-
if (computeDateSnapCoverage(normalRange.start, tDateProfile, dateEnv)
|
|
933
|
-
< computeDateSnapCoverage(normalRange.end, tDateProfile, dateEnv)) {
|
|
808
|
+
if (computeDateSnapCoverage$1(normalRange.start, tDateProfile, dateEnv)
|
|
809
|
+
< computeDateSnapCoverage$1(normalRange.end, tDateProfile, dateEnv)) {
|
|
934
810
|
// intersect the footprint's range with the grid's range
|
|
935
811
|
let slicedRange = internal_cjs.intersectRanges(normalRange, tDateProfile.normalizedRange);
|
|
936
812
|
if (slicedRange) {
|
|
@@ -956,48 +832,84 @@ const DEFAULT_TIME_FORMAT = internal_cjs.createFormatter({
|
|
|
956
832
|
});
|
|
957
833
|
class TimelineEvent extends internal_cjs.BaseComponent {
|
|
958
834
|
render() {
|
|
959
|
-
let { props } = this;
|
|
960
|
-
|
|
835
|
+
let { props, context } = this;
|
|
836
|
+
let { options } = context;
|
|
837
|
+
return (preact_cjs.createElement(internal_cjs.StandardEvent, Object.assign({}, props, { elClasses: [
|
|
838
|
+
'fc-timeline-event',
|
|
839
|
+
'fc-h-event',
|
|
840
|
+
options.eventOverlap === false // TODO: fix bad default
|
|
841
|
+
? 'fc-timeline-event-spacious'
|
|
842
|
+
: ''
|
|
843
|
+
], defaultTimeFormat: DEFAULT_TIME_FORMAT, defaultDisplayEventTime: !props.isTimeScale })));
|
|
961
844
|
}
|
|
962
845
|
}
|
|
963
846
|
|
|
964
847
|
class TimelineLaneMoreLink extends internal_cjs.BaseComponent {
|
|
965
848
|
render() {
|
|
966
|
-
let { props
|
|
967
|
-
let { hiddenSegs,
|
|
968
|
-
let { top, hcoords } = placement;
|
|
969
|
-
let isVisible = hcoords && top !== null;
|
|
970
|
-
let hStyle = coordsToCss(hcoords, context.isRtl);
|
|
849
|
+
let { props } = this;
|
|
850
|
+
let { hiddenSegs, resourceId, forcedInvisibleMap } = props;
|
|
971
851
|
let extraDateSpan = resourceId ? { resourceId } : {};
|
|
972
|
-
return (preact_cjs.createElement(internal_cjs.MoreLinkContainer, {
|
|
852
|
+
return (preact_cjs.createElement(internal_cjs.MoreLinkContainer, { elClasses: ['fc-timeline-more-link'], allDayDate: null, segs: hiddenSegs, hiddenSegs: hiddenSegs, dateProfile: props.dateProfile, todayRange: props.todayRange, extraDateSpan: extraDateSpan, popoverContent: () => (preact_cjs.createElement(preact_cjs.Fragment, null, hiddenSegs.map((seg) => {
|
|
973
853
|
let instanceId = seg.eventRange.instance.instanceId;
|
|
974
|
-
return (preact_cjs.createElement("div", { key: instanceId, style: { visibility:
|
|
854
|
+
return (preact_cjs.createElement("div", { key: instanceId, style: { visibility: forcedInvisibleMap[instanceId] ? 'hidden' : '' } },
|
|
975
855
|
preact_cjs.createElement(TimelineEvent, Object.assign({ isTimeScale: props.isTimeScale, seg: seg, isDragging: false, isResizing: false, isDateSelecting: false, isSelected: instanceId === props.eventSelection }, internal_cjs.getSegMeta(seg, props.todayRange, props.nowDate)))));
|
|
976
|
-
}))) }, (InnerContent) => (preact_cjs.createElement(InnerContent, { elTag: "div", elClasses: ['fc-timeline-more-link-inner', 'fc-sticky'] }))));
|
|
856
|
+
}))) }, (InnerContent) => (preact_cjs.createElement(InnerContent, { elTag: "div", elClasses: ['fc-timeline-more-link-inner', 'fc-sticky-x'] }))));
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
/*
|
|
861
|
+
TODO: make DRY with other Event Harnesses
|
|
862
|
+
*/
|
|
863
|
+
class TimelineEventHarness extends preact_cjs.Component {
|
|
864
|
+
constructor() {
|
|
865
|
+
super(...arguments);
|
|
866
|
+
// ref
|
|
867
|
+
this.rootElRef = preact_cjs.createRef();
|
|
868
|
+
}
|
|
869
|
+
render() {
|
|
870
|
+
const { props } = this;
|
|
871
|
+
return (preact_cjs.createElement("div", { className: "fc-abs", style: props.style, ref: this.rootElRef }, props.children));
|
|
872
|
+
}
|
|
873
|
+
componentDidMount() {
|
|
874
|
+
const rootEl = this.rootElRef.current; // TODO: make dynamic with useEffect
|
|
875
|
+
this.detachHeight = internal_cjs.watchHeight(rootEl, (height) => {
|
|
876
|
+
internal_cjs.setRef(this.props.heightRef, height);
|
|
877
|
+
});
|
|
878
|
+
}
|
|
879
|
+
componentWillUnmount() {
|
|
880
|
+
this.detachHeight();
|
|
977
881
|
}
|
|
978
882
|
}
|
|
979
883
|
|
|
884
|
+
/*
|
|
885
|
+
TODO: split TimelineLaneBg and TimelineLaneFg?
|
|
886
|
+
*/
|
|
980
887
|
class TimelineLane extends internal_cjs.BaseComponent {
|
|
981
888
|
constructor() {
|
|
982
889
|
super(...arguments);
|
|
983
|
-
|
|
890
|
+
// memo
|
|
984
891
|
this.sortEventSegs = internal_cjs.memoize(internal_cjs.sortEventSegs);
|
|
985
|
-
|
|
986
|
-
this.
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
this.
|
|
990
|
-
|
|
991
|
-
|
|
892
|
+
// refs
|
|
893
|
+
this.segHeightRefMap = new internal_cjs.RefMap(() => {
|
|
894
|
+
internal_cjs.afterSize(this.handleSegHeights);
|
|
895
|
+
});
|
|
896
|
+
this.moreLinkHeightRefMap = new internal_cjs.RefMap(() => {
|
|
897
|
+
internal_cjs.afterSize(this.handleMoreLinkHeights);
|
|
898
|
+
});
|
|
899
|
+
// internal
|
|
900
|
+
this.slicer = new TimelineLaneSlicer();
|
|
901
|
+
this.handleMoreLinkHeights = () => {
|
|
902
|
+
this.setState({ moreLinkHeightRev: this.moreLinkHeightRefMap.rev }); // will trigger rerender
|
|
992
903
|
};
|
|
993
|
-
this.
|
|
994
|
-
|
|
995
|
-
this.updateSize();
|
|
996
|
-
}
|
|
904
|
+
this.handleSegHeights = () => {
|
|
905
|
+
this.setState({ segHeightRev: this.segHeightRefMap.rev }); // will trigger rerender
|
|
997
906
|
};
|
|
998
907
|
}
|
|
908
|
+
/*
|
|
909
|
+
TODO: lots of memoization needed here!
|
|
910
|
+
*/
|
|
999
911
|
render() {
|
|
1000
|
-
let { props,
|
|
912
|
+
let { props, context, segHeightRefMap } = this;
|
|
1001
913
|
let { options } = context;
|
|
1002
914
|
let { dateProfile, tDateProfile } = props;
|
|
1003
915
|
let slicedProps = this.slicer.sliceProps(props, dateProfile, tDateProfile.isTimeScale ? null : props.nextDayThreshold, context, // wish we didn't have to pass in the rest of the args...
|
|
@@ -1006,106 +918,275 @@ class TimelineLane extends internal_cjs.BaseComponent {
|
|
|
1006
918
|
(slicedProps.eventResize ? slicedProps.eventResize.segs : null) ||
|
|
1007
919
|
[];
|
|
1008
920
|
let fgSegs = this.sortEventSegs(slicedProps.fgEventSegs, options.eventOrder);
|
|
1009
|
-
let
|
|
1010
|
-
|
|
1011
|
-
|
|
921
|
+
let fgSegHorizontals = props.slotWidth != null
|
|
922
|
+
? computeManySegHorizontals(fgSegs, options.eventMinWidth, context.dateEnv, tDateProfile, props.slotWidth)
|
|
923
|
+
: {};
|
|
924
|
+
let [fgSegTops, fgSegsBottom, hiddenGroups, hiddenGroupTops] = computeFgSegPlacements(// verticals
|
|
925
|
+
fgSegs, fgSegHorizontals, segHeightRefMap.current, options.eventOrderStrict, options.eventMaxStack);
|
|
926
|
+
let moreLinksBottom = computeMoreLinkMaxBottom(hiddenGroups, hiddenGroupTops, this.moreLinkHeightRefMap.current);
|
|
927
|
+
let innerHeight = Math.max(moreLinksBottom, fgSegsBottom);
|
|
928
|
+
let forcedInvisibleMap = // TODO: more convenient/DRY
|
|
1012
929
|
(slicedProps.eventDrag ? slicedProps.eventDrag.affectedInstances : null) ||
|
|
1013
930
|
(slicedProps.eventResize ? slicedProps.eventResize.affectedInstances : null) ||
|
|
1014
931
|
{};
|
|
1015
932
|
return (preact_cjs.createElement(preact_cjs.Fragment, null,
|
|
1016
|
-
preact_cjs.createElement(TimelineLaneBg, {
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
933
|
+
preact_cjs.createElement(TimelineLaneBg, { tDateProfile: tDateProfile, nowDate: props.nowDate, todayRange: props.todayRange,
|
|
934
|
+
// content
|
|
935
|
+
bgEventSegs: slicedProps.bgEventSegs, businessHourSegs: slicedProps.businessHourSegs, dateSelectionSegs: slicedProps.dateSelectionSegs, eventResizeSegs: slicedProps.eventResize ? slicedProps.eventResize.segs : [] /* bad new empty array? */,
|
|
936
|
+
// dimensions
|
|
937
|
+
slotWidth: props.slotWidth }),
|
|
938
|
+
preact_cjs.createElement("div", { className: [
|
|
939
|
+
'fc-timeline-events',
|
|
940
|
+
'fc-content-box',
|
|
941
|
+
options.eventOverlap === false // TODO: fix bad default
|
|
942
|
+
? 'fc-timeline-events-overlap-disabled'
|
|
943
|
+
: 'fc-timeline-events-overlap-enabled'
|
|
944
|
+
].join(' '), style: { height: innerHeight } },
|
|
945
|
+
this.renderFgSegs(fgSegs, fgSegHorizontals, fgSegTops, forcedInvisibleMap, hiddenGroups, hiddenGroupTops, false, // isDragging
|
|
946
|
+
false, // isResizing
|
|
947
|
+
false),
|
|
948
|
+
this.renderFgSegs(mirrorSegs, props.slotWidth // TODO: memoize
|
|
949
|
+
? computeManySegHorizontals(mirrorSegs, options.eventMinWidth, context.dateEnv, tDateProfile, props.slotWidth)
|
|
950
|
+
: {}, fgSegTops, {}, // forcedInvisibleMap
|
|
951
|
+
[], {}, Boolean(slicedProps.eventDrag), Boolean(slicedProps.eventResize), false))));
|
|
952
|
+
}
|
|
953
|
+
renderFgSegs(segs, segHorizontals, segTops, forcedInvisibleMap, hiddenGroups, hiddenGroupTops, isDragging, isResizing, isDateSelecting) {
|
|
954
|
+
let { props, context, segHeightRefMap, moreLinkHeightRefMap } = this;
|
|
955
|
+
let isMirror = isDragging || isResizing || isDateSelecting;
|
|
956
|
+
return (preact_cjs.createElement(preact_cjs.Fragment, null,
|
|
957
|
+
segs.map((seg) => {
|
|
958
|
+
const { instanceId } = seg.eventRange.instance;
|
|
959
|
+
const segTop = segTops[instanceId];
|
|
960
|
+
const segHorizontal = segHorizontals[instanceId];
|
|
961
|
+
const isVisible = isMirror ||
|
|
962
|
+
(segHorizontal && segTop != null && !forcedInvisibleMap[instanceId]);
|
|
963
|
+
return (preact_cjs.createElement(TimelineEventHarness, { key: instanceId, style: Object.assign({ visibility: isVisible ? '' : 'hidden', top: segTop || 0 }, horizontalsToCss(segHorizontal, context.isRtl)), heightRef: isMirror ? undefined : segHeightRefMap.createRef(instanceId) },
|
|
964
|
+
preact_cjs.createElement(TimelineEvent, Object.assign({ isTimeScale: props.tDateProfile.isTimeScale, seg: seg, isDragging: isDragging, isResizing: isResizing, isDateSelecting: isDateSelecting, isSelected: instanceId === props.eventSelection /* TODO: bad for mirror? */ }, internal_cjs.getSegMeta(seg, props.todayRange, props.nowDate)))));
|
|
965
|
+
}),
|
|
966
|
+
hiddenGroups.map((hiddenGroup) => (preact_cjs.createElement(TimelineEventHarness, { key: hiddenGroup.key, style: Object.assign({ top: hiddenGroupTops[hiddenGroup.key] || 0 }, horizontalsToCss({
|
|
967
|
+
start: hiddenGroup.span.start,
|
|
968
|
+
size: hiddenGroup.span.end - hiddenGroup.span.start
|
|
969
|
+
}, context.isRtl)), heightRef: moreLinkHeightRefMap.createRef(hiddenGroup.key) },
|
|
970
|
+
preact_cjs.createElement(TimelineLaneMoreLink, { hiddenSegs: hiddenGroup.segs /* TODO: make SegGroup generic! */, dateProfile: props.dateProfile, nowDate: props.nowDate, todayRange: props.todayRange, isTimeScale: props.tDateProfile.isTimeScale, eventSelection: props.eventSelection, resourceId: props.resourceId, forcedInvisibleMap: forcedInvisibleMap }))))));
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
class TimelineHeaderCell extends internal_cjs.BaseComponent {
|
|
975
|
+
constructor() {
|
|
976
|
+
super(...arguments);
|
|
977
|
+
// memo
|
|
978
|
+
this.refineRenderProps = internal_cjs.memoizeObjArg(refineRenderProps);
|
|
979
|
+
this.buildCellNavLinkAttrs = internal_cjs.memoize(buildCellNavLinkAttrs);
|
|
980
|
+
// ref
|
|
981
|
+
this.innerElRef = preact_cjs.createRef();
|
|
982
|
+
// TODO: unset width/height ref on unmount?
|
|
983
|
+
}
|
|
984
|
+
render() {
|
|
985
|
+
let { props, context } = this;
|
|
986
|
+
let { dateEnv, options } = context;
|
|
987
|
+
let { cell, dateProfile, tDateProfile } = props;
|
|
988
|
+
// the cell.rowUnit is f'd
|
|
989
|
+
// giving 'month' for a 3-day view
|
|
990
|
+
// workaround: to infer day, do NOT time
|
|
991
|
+
let dateMeta = internal_cjs.getDateMeta(cell.date, props.todayRange, props.nowDate, dateProfile);
|
|
992
|
+
let renderProps = this.refineRenderProps({
|
|
993
|
+
level: props.rowLevel,
|
|
994
|
+
dateMarker: cell.date,
|
|
995
|
+
text: cell.text,
|
|
996
|
+
dateEnv: context.dateEnv,
|
|
997
|
+
viewApi: context.viewApi,
|
|
998
|
+
});
|
|
999
|
+
return (preact_cjs.createElement(internal_cjs.ContentContainer, { elTag: "div", elClasses: [
|
|
1000
|
+
'fc-timeline-slot-label',
|
|
1001
|
+
'fc-timeline-slot',
|
|
1002
|
+
cell.isWeekStart ? 'fc-timeline-slot-em' : '',
|
|
1003
|
+
'fc-header-cell',
|
|
1004
|
+
'fc-cell',
|
|
1005
|
+
'fc-flex-column',
|
|
1006
|
+
'fc-justify-center',
|
|
1007
|
+
props.isCentered ? 'fc-align-center' : 'fc-align-start',
|
|
1008
|
+
...( // TODO: so slot classnames for week/month/bigger. see note above about rowUnit
|
|
1009
|
+
cell.rowUnit === 'time' ?
|
|
1010
|
+
internal_cjs.getSlotClassNames(dateMeta, context.theme) :
|
|
1011
|
+
internal_cjs.getDayClassNames(dateMeta, context.theme)),
|
|
1012
|
+
], elAttrs: {
|
|
1013
|
+
'data-date': dateEnv.formatIso(cell.date, {
|
|
1014
|
+
omitTime: !tDateProfile.isTimeScale,
|
|
1015
|
+
omitTimeZoneOffset: true,
|
|
1016
|
+
}),
|
|
1017
|
+
}, elStyle: {
|
|
1018
|
+
width: props.slotWidth != null
|
|
1019
|
+
? props.slotWidth * cell.colspan
|
|
1020
|
+
: undefined,
|
|
1021
|
+
}, renderProps: renderProps, generatorName: "slotLabelContent", customGenerator: options.slotLabelContent, defaultGenerator: renderInnerContent, classNameGenerator: options.slotLabelClassNames, didMount: options.slotLabelDidMount, willUnmount: options.slotLabelWillUnmount }, (InnerContent) => (preact_cjs.createElement("div", { ref: this.innerElRef, className: [
|
|
1022
|
+
'fc-flex-column',
|
|
1023
|
+
props.isSticky ? 'fc-sticky-x' : '',
|
|
1024
|
+
].join(' ') },
|
|
1025
|
+
preact_cjs.createElement(InnerContent, { elTag: "a", elClasses: [
|
|
1026
|
+
'fc-cell-inner',
|
|
1027
|
+
'fc-padding-md',
|
|
1028
|
+
], elAttrs: this.buildCellNavLinkAttrs(context, cell.date, cell.rowUnit) })))));
|
|
1020
1029
|
}
|
|
1021
1030
|
componentDidMount() {
|
|
1022
|
-
this
|
|
1023
|
-
this.
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1031
|
+
const { props } = this;
|
|
1032
|
+
const innerEl = this.innerElRef.current; // TODO: make dynamic with useEffect
|
|
1033
|
+
this.detachSize = internal_cjs.watchSize(innerEl, (width, height) => {
|
|
1034
|
+
internal_cjs.setRef(props.innerWidthRef, width);
|
|
1035
|
+
internal_cjs.setRef(props.innerHeightRef, height);
|
|
1036
|
+
// HACK for sticky-centering
|
|
1037
|
+
innerEl.style.left = innerEl.style.right =
|
|
1038
|
+
(props.isCentered && props.isSticky)
|
|
1039
|
+
? `calc(50% - ${width / 2}px)`
|
|
1040
|
+
: '';
|
|
1041
|
+
});
|
|
1032
1042
|
}
|
|
1033
1043
|
componentWillUnmount() {
|
|
1034
|
-
this.
|
|
1035
|
-
}
|
|
1036
|
-
updateSize() {
|
|
1037
|
-
let { props } = this;
|
|
1038
|
-
let { timelineCoords } = props;
|
|
1039
|
-
const innerEl = this.innerElRef.current;
|
|
1040
|
-
if (props.onHeightChange) {
|
|
1041
|
-
props.onHeightChange(innerEl, false);
|
|
1042
|
-
}
|
|
1043
|
-
if (timelineCoords) {
|
|
1044
|
-
this.setState({
|
|
1045
|
-
eventInstanceHeights: internal_cjs.mapHash(this.harnessElRefs.currentMap, (harnessEl) => (Math.round(harnessEl.getBoundingClientRect().height))),
|
|
1046
|
-
moreLinkHeights: internal_cjs.mapHash(this.moreElRefs.currentMap, (moreEl) => (Math.round(moreEl.getBoundingClientRect().height))),
|
|
1047
|
-
}, () => {
|
|
1048
|
-
if (props.onHeightChange) {
|
|
1049
|
-
props.onHeightChange(innerEl, true);
|
|
1050
|
-
}
|
|
1051
|
-
});
|
|
1052
|
-
}
|
|
1053
|
-
// hack
|
|
1054
|
-
if (props.syncParentMinHeight) {
|
|
1055
|
-
innerEl.parentElement.style.minHeight = innerEl.style.height;
|
|
1056
|
-
}
|
|
1044
|
+
this.detachSize();
|
|
1057
1045
|
}
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1046
|
+
}
|
|
1047
|
+
// Utils
|
|
1048
|
+
// -------------------------------------------------------------------------------------------------
|
|
1049
|
+
function buildCellNavLinkAttrs(context, cellDate, rowUnit) {
|
|
1050
|
+
return (rowUnit && rowUnit !== 'time')
|
|
1051
|
+
? internal_cjs.buildNavLinkAttrs(context, cellDate, rowUnit)
|
|
1052
|
+
: {};
|
|
1053
|
+
}
|
|
1054
|
+
function renderInnerContent(renderProps) {
|
|
1055
|
+
return renderProps.text;
|
|
1056
|
+
}
|
|
1057
|
+
function refineRenderProps(input) {
|
|
1058
|
+
return {
|
|
1059
|
+
level: input.level,
|
|
1060
|
+
date: input.dateEnv.toDate(input.dateMarker),
|
|
1061
|
+
view: input.viewApi,
|
|
1062
|
+
text: input.text,
|
|
1063
|
+
};
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1066
|
+
class TimelineHeaderRow extends internal_cjs.BaseComponent {
|
|
1067
|
+
constructor() {
|
|
1068
|
+
super(...arguments);
|
|
1069
|
+
// refs
|
|
1070
|
+
this.innerWidthRefMap = new internal_cjs.RefMap(() => {
|
|
1071
|
+
internal_cjs.afterSize(this.handleInnerWidths);
|
|
1072
|
+
});
|
|
1073
|
+
this.innerHeightRefMap = new internal_cjs.RefMap(() => {
|
|
1074
|
+
internal_cjs.afterSize(this.handleInnerHeights);
|
|
1075
|
+
});
|
|
1076
|
+
this.handleInnerWidths = () => {
|
|
1077
|
+
const innerWidthMap = this.innerWidthRefMap.current;
|
|
1078
|
+
let max = 0;
|
|
1079
|
+
for (const innerWidth of innerWidthMap.values()) {
|
|
1080
|
+
max = Math.max(max, innerWidth);
|
|
1081
|
+
}
|
|
1082
|
+
// TODO: ensure not equal?
|
|
1083
|
+
internal_cjs.setRef(this.props.innerWidthRef, max);
|
|
1084
|
+
};
|
|
1085
|
+
this.handleInnerHeights = () => {
|
|
1086
|
+
const innerHeightMap = this.innerHeightRefMap.current;
|
|
1087
|
+
let max = 0;
|
|
1088
|
+
for (const innerHeight of innerHeightMap.values()) {
|
|
1089
|
+
max = Math.max(max, innerHeight);
|
|
1066
1090
|
}
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1091
|
+
// TODO: ensure not equal?
|
|
1092
|
+
internal_cjs.setRef(this.props.innerHeighRef, max);
|
|
1093
|
+
};
|
|
1094
|
+
}
|
|
1095
|
+
render() {
|
|
1096
|
+
const { props, innerWidthRefMap, innerHeightRefMap } = this;
|
|
1097
|
+
const isCentered = !(props.tDateProfile.isTimeScale && props.isLastRow);
|
|
1098
|
+
const isSticky = !props.isLastRow;
|
|
1099
|
+
return (preact_cjs.createElement("div", { className: 'fc-row', style: { height: props.height } }, props.cells.map((cell) => {
|
|
1100
|
+
// TODO: make this part of the cell obj?
|
|
1101
|
+
// TODO: rowUnit seems wrong sometimes. says 'month' when it should be day
|
|
1102
|
+
// TODO: rowUnit is relevant to whole row. put it on a row object, not the cells
|
|
1103
|
+
const key = cell.rowUnit + ':' + cell.date.toISOString();
|
|
1104
|
+
return (preact_cjs.createElement(TimelineHeaderCell, { key: key, cell: cell, rowLevel: props.rowLevel, dateProfile: props.dateProfile, tDateProfile: props.tDateProfile, todayRange: props.todayRange, nowDate: props.nowDate, isCentered: isCentered, isSticky: isSticky,
|
|
1105
|
+
// refs
|
|
1106
|
+
innerWidthRef: innerWidthRefMap.createRef(key), innerHeightRef: innerHeightRefMap.createRef(key),
|
|
1107
|
+
// dimensions
|
|
1108
|
+
slotWidth: props.slotWidth }));
|
|
1072
1109
|
})));
|
|
1073
1110
|
}
|
|
1074
1111
|
}
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
}
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
seg,
|
|
1086
|
-
hcoords: timelineCoords.rangeToCoords(seg),
|
|
1087
|
-
top: topsByInstanceId[seg.eventRange.instance.instanceId],
|
|
1088
|
-
}));
|
|
1112
|
+
|
|
1113
|
+
class TimelineNowIndicatorLine extends internal_cjs.BaseComponent {
|
|
1114
|
+
render() {
|
|
1115
|
+
const { props, context } = this;
|
|
1116
|
+
return (preact_cjs.createElement("div", { className: "fc-timeline-now-indicator-container" },
|
|
1117
|
+
preact_cjs.createElement(internal_cjs.NowIndicatorContainer // TODO: make separate component?
|
|
1118
|
+
, { elClasses: ['fc-timeline-now-indicator-line'], elStyle: props.slotWidth != null
|
|
1119
|
+
? horizontalCoordToCss(dateToCoord(props.nowDate, context.dateEnv, props.tDateProfile, props.slotWidth), context.isRtl)
|
|
1120
|
+
: {}, isAxis: false, date: props.nowDate })));
|
|
1121
|
+
}
|
|
1089
1122
|
}
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1123
|
+
|
|
1124
|
+
class TimelineNowIndicatorArrow extends internal_cjs.BaseComponent {
|
|
1125
|
+
render() {
|
|
1126
|
+
const { props, context } = this;
|
|
1127
|
+
return (preact_cjs.createElement("div", { className: "fc-timeline-now-indicator-container" },
|
|
1128
|
+
preact_cjs.createElement(internal_cjs.NowIndicatorContainer, { elClasses: ['fc-timeline-now-indicator-arrow'], elStyle: props.slotWidth != null
|
|
1129
|
+
? horizontalCoordToCss(dateToCoord(props.nowDate, context.dateEnv, props.tDateProfile, props.slotWidth), context.isRtl)
|
|
1130
|
+
: {}, isAxis: true, date: props.nowDate })));
|
|
1097
1131
|
}
|
|
1098
|
-
return topsByInstanceId;
|
|
1099
1132
|
}
|
|
1100
1133
|
|
|
1101
|
-
class
|
|
1134
|
+
class TimelineView extends internal_cjs.DateComponent {
|
|
1102
1135
|
constructor() {
|
|
1103
1136
|
super(...arguments);
|
|
1104
|
-
|
|
1105
|
-
this.
|
|
1106
|
-
|
|
1137
|
+
// memoized
|
|
1138
|
+
this.buildTimelineDateProfile = internal_cjs.memoize(buildTimelineDateProfile);
|
|
1139
|
+
this.computeSlotWidth = internal_cjs.memoize(computeSlotWidth);
|
|
1140
|
+
// refs
|
|
1141
|
+
this.headerScrollerRef = preact_cjs.createRef();
|
|
1142
|
+
this.bodyScrollerRef = preact_cjs.createRef();
|
|
1143
|
+
this.footerScrollerRef = preact_cjs.createRef();
|
|
1144
|
+
// Sizing
|
|
1145
|
+
// -----------------------------------------------------------------------------------------------
|
|
1146
|
+
this.handleHeaderSlotInnerWidth = (innerWidth) => {
|
|
1147
|
+
this.headerSlotInnerWidth = innerWidth;
|
|
1148
|
+
internal_cjs.afterSize(this.handleSlotInnerWidths);
|
|
1149
|
+
};
|
|
1150
|
+
this.handleBodySlotInnerWidth = (innerWidth) => {
|
|
1151
|
+
this.bodySlotInnerWidth = innerWidth;
|
|
1152
|
+
internal_cjs.afterSize(this.handleSlotInnerWidths);
|
|
1153
|
+
};
|
|
1154
|
+
this.handleSlotInnerWidths = () => {
|
|
1155
|
+
const { state } = this;
|
|
1156
|
+
const slotInnerWidth = Math.max(this.headerSlotInnerWidth, this.bodySlotInnerWidth);
|
|
1157
|
+
if (state.slotInnerWidth !== slotInnerWidth) {
|
|
1158
|
+
this.setState({ slotInnerWidth });
|
|
1159
|
+
}
|
|
1160
|
+
};
|
|
1161
|
+
this.handleScrollerWidth = (scrollerWidth) => {
|
|
1162
|
+
this.setState({
|
|
1163
|
+
scrollerWidth,
|
|
1164
|
+
});
|
|
1165
|
+
};
|
|
1166
|
+
this.handleLeftScrollbarWidth = (leftScrollbarWidth) => {
|
|
1167
|
+
this.setState({
|
|
1168
|
+
leftScrollbarWidth
|
|
1169
|
+
});
|
|
1170
|
+
};
|
|
1171
|
+
this.handleRightScrollbarWidth = (rightScrollbarWidth) => {
|
|
1172
|
+
this.setState({
|
|
1173
|
+
rightScrollbarWidth
|
|
1174
|
+
});
|
|
1107
1175
|
};
|
|
1108
|
-
this.
|
|
1176
|
+
this.timeScrollResponder = new internal_cjs.ScrollResponder((time) => {
|
|
1177
|
+
const { props, context, tDateProfile, slotWidth } = this;
|
|
1178
|
+
if (slotWidth != null) {
|
|
1179
|
+
const x = timeToCoord(time, context.dateEnv, props.dateProfile, tDateProfile, slotWidth) +
|
|
1180
|
+
(context.isRtl ? -1 : 1); // overcome border. TODO: DRY this up
|
|
1181
|
+
this.syncedScroller.scrollTo({ x });
|
|
1182
|
+
return true;
|
|
1183
|
+
}
|
|
1184
|
+
return false;
|
|
1185
|
+
});
|
|
1186
|
+
// Hit System
|
|
1187
|
+
// -----------------------------------------------------------------------------------------------
|
|
1188
|
+
this.handeBodyEl = (el) => {
|
|
1189
|
+
this.bodyEl = el;
|
|
1109
1190
|
if (el) {
|
|
1110
1191
|
this.context.registerInteractiveComponent(this, { el });
|
|
1111
1192
|
}
|
|
@@ -1113,45 +1194,141 @@ class TimelineGrid extends internal_cjs.DateComponent {
|
|
|
1113
1194
|
this.context.unregisterInteractiveComponent(this);
|
|
1114
1195
|
}
|
|
1115
1196
|
};
|
|
1116
|
-
this.handleCoords = (coords) => {
|
|
1117
|
-
this.setState({ coords });
|
|
1118
|
-
if (this.props.onSlatCoords) {
|
|
1119
|
-
this.props.onSlatCoords(coords);
|
|
1120
|
-
}
|
|
1121
|
-
};
|
|
1122
1197
|
}
|
|
1123
1198
|
render() {
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1199
|
+
const { props, state, context } = this;
|
|
1200
|
+
const { options } = context;
|
|
1201
|
+
/* date */
|
|
1202
|
+
const tDateProfile = this.tDateProfile = this.buildTimelineDateProfile(props.dateProfile, context.dateEnv, options, context.dateProfileGenerator);
|
|
1203
|
+
const { cellRows } = tDateProfile;
|
|
1204
|
+
const timerUnit = internal_cjs.greatestDurationDenominator(tDateProfile.slotDuration).unit;
|
|
1205
|
+
/* table settings */
|
|
1206
|
+
const verticalScrolling = !props.forPrint && !internal_cjs.getIsHeightAuto(options);
|
|
1207
|
+
const stickyHeaderDates = !props.forPrint && internal_cjs.getStickyHeaderDates(options);
|
|
1208
|
+
const stickyFooterScrollbar = !props.forPrint && internal_cjs.getStickyFooterScrollbar(options);
|
|
1209
|
+
/* table positions */
|
|
1210
|
+
const [canvasWidth, slotWidth] = this.computeSlotWidth(tDateProfile.slotCnt, tDateProfile.slotsPerLabel, options.slotMinWidth, state.slotInnerWidth, // is ACTUALLY the label width. rename?
|
|
1211
|
+
state.scrollerWidth);
|
|
1212
|
+
this.slotWidth = slotWidth;
|
|
1213
|
+
return (preact_cjs.createElement(internal_cjs.NowTimer, { unit: timerUnit }, (nowDate, todayRange) => {
|
|
1214
|
+
const enableNowIndicator = // TODO: DRY
|
|
1215
|
+
options.nowIndicator &&
|
|
1216
|
+
slotWidth != null &&
|
|
1217
|
+
internal_cjs.rangeContainsMarker(props.dateProfile.currentRange, nowDate);
|
|
1218
|
+
return (preact_cjs.createElement(internal_cjs.ViewContainer, { viewSpec: context.viewSpec, elClasses: [
|
|
1219
|
+
'fc-timeline-view',
|
|
1220
|
+
'fc-flex-column',
|
|
1221
|
+
'fc-border',
|
|
1222
|
+
] },
|
|
1223
|
+
preact_cjs.createElement(internal_cjs.Scroller, { horizontal: true, hideScrollbars: true, elClassNames: [
|
|
1224
|
+
'fc-timeline-header',
|
|
1225
|
+
'fc-rowgroup',
|
|
1226
|
+
stickyHeaderDates ? 'fc-sticky-header' : '',
|
|
1227
|
+
], ref: this.headerScrollerRef },
|
|
1228
|
+
preact_cjs.createElement("div", { className: 'fc-rel fc-content-box' // origin for now-indicator
|
|
1229
|
+
, style: {
|
|
1230
|
+
width: canvasWidth,
|
|
1231
|
+
paddingLeft: state.leftScrollbarWidth,
|
|
1232
|
+
paddingRight: state.rightScrollbarWidth,
|
|
1233
|
+
} },
|
|
1234
|
+
preact_cjs.createElement("div", null, cellRows.map((cells, rowLevel) => {
|
|
1235
|
+
const isLast = rowLevel === cellRows.length - 1;
|
|
1236
|
+
return (preact_cjs.createElement(TimelineHeaderRow, { key: rowLevel, dateProfile: props.dateProfile, tDateProfile: tDateProfile, nowDate: nowDate, todayRange: todayRange, rowLevel: rowLevel, isLastRow: isLast, cells: cells, slotWidth: slotWidth, innerWidthRef: isLast ? this.handleHeaderSlotInnerWidth : undefined }));
|
|
1237
|
+
})),
|
|
1238
|
+
enableNowIndicator && (
|
|
1239
|
+
// TODO: make this positioned WITHIN padding?
|
|
1240
|
+
preact_cjs.createElement(TimelineNowIndicatorArrow, { tDateProfile: tDateProfile, nowDate: nowDate, slotWidth: slotWidth })))),
|
|
1241
|
+
preact_cjs.createElement(internal_cjs.Scroller, { vertical: verticalScrolling, horizontal: true, elClassNames: [
|
|
1242
|
+
'fc-timeline-body',
|
|
1243
|
+
'fc-rowgroup',
|
|
1244
|
+
verticalScrolling ? 'fc-liquid' : '',
|
|
1245
|
+
], ref: this.bodyScrollerRef, widthRef: this.handleScrollerWidth, leftScrollbarWidthRef: this.handleLeftScrollbarWidth, rightScrollbarWidthRef: this.handleRightScrollbarWidth },
|
|
1246
|
+
preact_cjs.createElement("div", { className: "fc-rel fc-grow", style: {
|
|
1247
|
+
width: canvasWidth,
|
|
1248
|
+
}, ref: this.handeBodyEl },
|
|
1249
|
+
preact_cjs.createElement(TimelineSlats, { dateProfile: props.dateProfile, tDateProfile: tDateProfile, nowDate: nowDate, todayRange: todayRange,
|
|
1250
|
+
// ref
|
|
1251
|
+
innerWidthRef: this.handleBodySlotInnerWidth,
|
|
1252
|
+
// dimensions
|
|
1253
|
+
slotWidth: slotWidth }),
|
|
1254
|
+
preact_cjs.createElement(TimelineLane, { dateProfile: props.dateProfile, tDateProfile: tDateProfile, nowDate: nowDate, todayRange: todayRange, nextDayThreshold: options.nextDayThreshold, eventStore: props.eventStore, eventUiBases: props.eventUiBases, businessHours: props.businessHours, dateSelection: props.dateSelection, eventDrag: props.eventDrag, eventResize: props.eventResize, eventSelection: props.eventSelection, slotWidth: slotWidth }),
|
|
1255
|
+
enableNowIndicator && (preact_cjs.createElement(TimelineNowIndicatorLine, { tDateProfile: tDateProfile, nowDate: nowDate, slotWidth: slotWidth })))),
|
|
1256
|
+
stickyFooterScrollbar && (preact_cjs.createElement(internal_cjs.Scroller, { ref: this.footerScrollerRef, horizontal: true },
|
|
1257
|
+
preact_cjs.createElement("div", { style: { width: canvasWidth } })))));
|
|
1258
|
+
}));
|
|
1259
|
+
}
|
|
1260
|
+
// Lifecycle
|
|
1261
|
+
// -----------------------------------------------------------------------------------------------
|
|
1262
|
+
componentDidMount() {
|
|
1263
|
+
const { context } = this;
|
|
1264
|
+
const { options } = context;
|
|
1265
|
+
const ScrollerSyncer = internal_cjs.getScrollerSyncerClass(this.context.pluginHooks);
|
|
1266
|
+
this.syncedScroller = new ScrollerSyncer(true); // horizontal=true
|
|
1267
|
+
this.updateSyncedScroller();
|
|
1268
|
+
context.emitter.on('_timeScrollRequest', this.timeScrollResponder.handleScroll);
|
|
1269
|
+
this.timeScrollResponder.handleScroll(options.scrollTime);
|
|
1270
|
+
}
|
|
1271
|
+
componentDidUpdate(prevProps) {
|
|
1272
|
+
const { options } = this.context;
|
|
1273
|
+
this.updateSyncedScroller();
|
|
1274
|
+
if (prevProps.dateProfile !== this.props.dateProfile && options.scrollTimeReset) {
|
|
1275
|
+
this.timeScrollResponder.handleScroll(options.scrollTime);
|
|
1276
|
+
}
|
|
1277
|
+
else {
|
|
1278
|
+
this.timeScrollResponder.drain();
|
|
1279
|
+
}
|
|
1280
|
+
}
|
|
1281
|
+
componentWillUnmount() {
|
|
1282
|
+
this.syncedScroller.destroy();
|
|
1283
|
+
this.context.emitter.off('_timeScrollRequest', this.timeScrollResponder.handleScroll);
|
|
1284
|
+
}
|
|
1285
|
+
// Scrolling
|
|
1286
|
+
// -----------------------------------------------------------------------------------------------
|
|
1287
|
+
updateSyncedScroller() {
|
|
1288
|
+
this.syncedScroller.handleChildren([
|
|
1289
|
+
this.headerScrollerRef.current,
|
|
1290
|
+
this.bodyScrollerRef.current,
|
|
1291
|
+
this.footerScrollerRef.current
|
|
1292
|
+
], this.context.isRtl);
|
|
1293
|
+
}
|
|
1141
1294
|
queryHit(positionLeft, positionTop, elWidth, elHeight) {
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
if (
|
|
1295
|
+
const { props, context, tDateProfile, slotWidth } = this;
|
|
1296
|
+
const { dateEnv } = context;
|
|
1297
|
+
if (slotWidth) {
|
|
1298
|
+
const x = context.isRtl ? elWidth - positionLeft : positionLeft;
|
|
1299
|
+
const slatIndex = Math.floor(x / slotWidth);
|
|
1300
|
+
const slatX = slatIndex * slotWidth;
|
|
1301
|
+
const partial = (x - slatX) / slotWidth; // floating point number between 0 and 1
|
|
1302
|
+
const localSnapIndex = Math.floor(partial * tDateProfile.snapsPerSlot); // the snap # relative to start of slat
|
|
1303
|
+
let startDate = dateEnv.add(tDateProfile.slotDates[slatIndex], internal_cjs.multiplyDuration(tDateProfile.snapDuration, localSnapIndex));
|
|
1304
|
+
let endDate = dateEnv.add(startDate, tDateProfile.snapDuration);
|
|
1305
|
+
// TODO: generalize this coord stuff to TimeGrid?
|
|
1306
|
+
let snapWidth = slotWidth / tDateProfile.snapsPerSlot;
|
|
1307
|
+
let startCoord = slatIndex * slotWidth + (snapWidth * localSnapIndex);
|
|
1308
|
+
let endCoord = startCoord + snapWidth;
|
|
1309
|
+
let left, right;
|
|
1310
|
+
if (context.isRtl) {
|
|
1311
|
+
left = elWidth - endCoord;
|
|
1312
|
+
right = elWidth - startCoord;
|
|
1313
|
+
}
|
|
1314
|
+
else {
|
|
1315
|
+
left = startCoord;
|
|
1316
|
+
right = endCoord;
|
|
1317
|
+
}
|
|
1145
1318
|
return {
|
|
1146
|
-
dateProfile:
|
|
1147
|
-
dateSpan:
|
|
1319
|
+
dateProfile: props.dateProfile,
|
|
1320
|
+
dateSpan: {
|
|
1321
|
+
range: { start: startDate, end: endDate },
|
|
1322
|
+
allDay: !tDateProfile.isTimeScale,
|
|
1323
|
+
},
|
|
1148
1324
|
rect: {
|
|
1149
|
-
left
|
|
1150
|
-
right
|
|
1325
|
+
left,
|
|
1326
|
+
right,
|
|
1151
1327
|
top: 0,
|
|
1152
1328
|
bottom: elHeight,
|
|
1153
1329
|
},
|
|
1154
|
-
|
|
1330
|
+
// HACK. TODO: This is expensive to do every hit-query
|
|
1331
|
+
dayEl: this.bodyEl.querySelectorAll('.fc-timeline-slot')[slatIndex],
|
|
1155
1332
|
layer: 0,
|
|
1156
1333
|
};
|
|
1157
1334
|
}
|
|
@@ -1159,100 +1336,18 @@ class TimelineGrid extends internal_cjs.DateComponent {
|
|
|
1159
1336
|
}
|
|
1160
1337
|
}
|
|
1161
1338
|
|
|
1162
|
-
|
|
1163
|
-
constructor() {
|
|
1164
|
-
super(...arguments);
|
|
1165
|
-
this.buildTimelineDateProfile = internal_cjs.memoize(buildTimelineDateProfile);
|
|
1166
|
-
this.scrollGridRef = preact_cjs.createRef();
|
|
1167
|
-
this.state = {
|
|
1168
|
-
slatCoords: null,
|
|
1169
|
-
slotCushionMaxWidth: null,
|
|
1170
|
-
};
|
|
1171
|
-
this.handleSlatCoords = (slatCoords) => {
|
|
1172
|
-
this.setState({ slatCoords });
|
|
1173
|
-
};
|
|
1174
|
-
this.handleScrollLeftRequest = (scrollLeft) => {
|
|
1175
|
-
let scrollGrid = this.scrollGridRef.current;
|
|
1176
|
-
scrollGrid.forceScrollLeft(0, scrollLeft);
|
|
1177
|
-
};
|
|
1178
|
-
this.handleMaxCushionWidth = (slotCushionMaxWidth) => {
|
|
1179
|
-
this.setState({
|
|
1180
|
-
slotCushionMaxWidth: Math.ceil(slotCushionMaxWidth), // for less rerendering TODO: DRY
|
|
1181
|
-
});
|
|
1182
|
-
};
|
|
1183
|
-
}
|
|
1184
|
-
render() {
|
|
1185
|
-
let { props, state, context } = this;
|
|
1186
|
-
let { options } = context;
|
|
1187
|
-
let stickyHeaderDates = !props.forPrint && internal_cjs.getStickyHeaderDates(options);
|
|
1188
|
-
let stickyFooterScrollbar = !props.forPrint && internal_cjs.getStickyFooterScrollbar(options);
|
|
1189
|
-
let tDateProfile = this.buildTimelineDateProfile(props.dateProfile, context.dateEnv, options, context.dateProfileGenerator);
|
|
1190
|
-
let { slotMinWidth } = options;
|
|
1191
|
-
let slatCols = buildSlatCols(tDateProfile, slotMinWidth || this.computeFallbackSlotMinWidth(tDateProfile));
|
|
1192
|
-
let sections = [
|
|
1193
|
-
{
|
|
1194
|
-
type: 'header',
|
|
1195
|
-
key: 'header',
|
|
1196
|
-
isSticky: stickyHeaderDates,
|
|
1197
|
-
chunks: [{
|
|
1198
|
-
key: 'timeline',
|
|
1199
|
-
content: (contentArg) => (preact_cjs.createElement(TimelineHeader, { dateProfile: props.dateProfile, clientWidth: contentArg.clientWidth, clientHeight: contentArg.clientHeight, tableMinWidth: contentArg.tableMinWidth, tableColGroupNode: contentArg.tableColGroupNode, tDateProfile: tDateProfile, slatCoords: state.slatCoords, onMaxCushionWidth: slotMinWidth ? null : this.handleMaxCushionWidth })),
|
|
1200
|
-
}],
|
|
1201
|
-
},
|
|
1202
|
-
{
|
|
1203
|
-
type: 'body',
|
|
1204
|
-
key: 'body',
|
|
1205
|
-
liquid: true,
|
|
1206
|
-
chunks: [{
|
|
1207
|
-
key: 'timeline',
|
|
1208
|
-
content: (contentArg) => (preact_cjs.createElement(TimelineGrid, Object.assign({}, props, { clientWidth: contentArg.clientWidth, clientHeight: contentArg.clientHeight, tableMinWidth: contentArg.tableMinWidth, tableColGroupNode: contentArg.tableColGroupNode, tDateProfile: tDateProfile, onSlatCoords: this.handleSlatCoords, onScrollLeftRequest: this.handleScrollLeftRequest }))),
|
|
1209
|
-
}],
|
|
1210
|
-
},
|
|
1211
|
-
];
|
|
1212
|
-
if (stickyFooterScrollbar) {
|
|
1213
|
-
sections.push({
|
|
1214
|
-
type: 'footer',
|
|
1215
|
-
key: 'footer',
|
|
1216
|
-
isSticky: true,
|
|
1217
|
-
chunks: [{
|
|
1218
|
-
key: 'timeline',
|
|
1219
|
-
content: internal_cjs.renderScrollShim,
|
|
1220
|
-
}],
|
|
1221
|
-
});
|
|
1222
|
-
}
|
|
1223
|
-
return (preact_cjs.createElement(internal_cjs.ViewContainer, { elClasses: [
|
|
1224
|
-
'fc-timeline',
|
|
1225
|
-
options.eventOverlap === false ?
|
|
1226
|
-
'fc-timeline-overlap-disabled' :
|
|
1227
|
-
'',
|
|
1228
|
-
], viewSpec: context.viewSpec },
|
|
1229
|
-
preact_cjs.createElement(internal_cjs$1.ScrollGrid, { ref: this.scrollGridRef, liquid: !props.isHeightAuto && !props.forPrint, forPrint: props.forPrint, collapsibleWidth: false, colGroups: [
|
|
1230
|
-
{ cols: slatCols },
|
|
1231
|
-
], sections: sections })));
|
|
1232
|
-
}
|
|
1233
|
-
computeFallbackSlotMinWidth(tDateProfile) {
|
|
1234
|
-
return Math.max(30, ((this.state.slotCushionMaxWidth || 0) / tDateProfile.slotsPerLabel));
|
|
1235
|
-
}
|
|
1236
|
-
}
|
|
1237
|
-
function buildSlatCols(tDateProfile, slotMinWidth) {
|
|
1238
|
-
return [{
|
|
1239
|
-
span: tDateProfile.slotCnt,
|
|
1240
|
-
minWidth: slotMinWidth || 1, // needs to be a non-zero number to trigger horizontal scrollbars!??????
|
|
1241
|
-
}];
|
|
1242
|
-
}
|
|
1243
|
-
|
|
1244
|
-
var css_248z = ".fc .fc-timeline-body{min-height:100%;position:relative;z-index:1}.fc .fc-timeline-slots{bottom:0;position:absolute;top:0;z-index:1}.fc .fc-timeline-slots>table{height:100%}.fc .fc-timeline-slot-minor{border-style:dotted}.fc .fc-timeline-slot-frame{align-items:center;display:flex;justify-content:center}.fc .fc-timeline-header-row-chrono .fc-timeline-slot-frame{justify-content:flex-start}.fc .fc-timeline-header-row:last-child .fc-timeline-slot-frame{overflow:hidden}.fc .fc-timeline-slot-cushion{padding:4px 5px;white-space:nowrap}.fc-direction-ltr .fc-timeline-slot{border-right:0!important}.fc-direction-rtl .fc-timeline-slot{border-left:0!important}.fc .fc-timeline-now-indicator-container{bottom:0;left:0;position:absolute;right:0;top:0;width:0;z-index:4}.fc .fc-timeline-now-indicator-arrow,.fc .fc-timeline-now-indicator-line{border-color:var(--fc-now-indicator-color);border-style:solid;position:absolute;top:0}.fc .fc-timeline-now-indicator-arrow{border-left-color:transparent;border-right-color:transparent;border-width:6px 5px 0;margin:0 -6px}.fc .fc-timeline-now-indicator-line{border-width:0 0 0 1px;bottom:0;margin:0 -1px}.fc .fc-timeline-events{position:relative;width:0;z-index:3}.fc .fc-timeline-event-harness,.fc .fc-timeline-more-link{position:absolute;top:0}.fc-timeline-event{z-index:1}.fc-timeline-event.fc-event-mirror{z-index:2}.fc-timeline-event{align-items:center;border-radius:0;display:flex;font-size:var(--fc-small-font-size);margin-bottom:1px;padding:2px 1px;position:relative}.fc-timeline-event .fc-event-main{flex-grow:1;flex-shrink:1;min-width:0}.fc-timeline-event .fc-event-time{font-weight:700}.fc-timeline-event .fc-event-time,.fc-timeline-event .fc-event-title{padding:0 2px;white-space:nowrap}.fc-direction-ltr .fc-timeline-event.fc-event-end,.fc-direction-ltr .fc-timeline-more-link{margin-right:1px}.fc-direction-rtl .fc-timeline-event.fc-event-end,.fc-direction-rtl .fc-timeline-more-link{margin-left:1px}.fc-timeline-overlap-disabled .fc-timeline-event{margin-bottom:0;padding-bottom:5px;padding-top:5px}.fc-timeline-event:not(.fc-event-end):after,.fc-timeline-event:not(.fc-event-start):before{border-color:transparent #000;border-style:solid;border-width:5px;content:\"\";flex-grow:0;flex-shrink:0;height:0;margin:0 1px;opacity:.5;width:0}.fc-direction-ltr .fc-timeline-event:not(.fc-event-start):before,.fc-direction-rtl .fc-timeline-event:not(.fc-event-end):after{border-left:0}.fc-direction-ltr .fc-timeline-event:not(.fc-event-end):after,.fc-direction-rtl .fc-timeline-event:not(.fc-event-start):before{border-right:0}.fc-timeline-more-link{background:var(--fc-more-link-bg-color);color:var(--fc-more-link-text-color);cursor:pointer;font-size:var(--fc-small-font-size);padding:1px}.fc-timeline-more-link-inner{display:inline-block;left:0;padding:2px;right:0}.fc .fc-timeline-bg{bottom:0;left:0;position:absolute;right:0;top:0;width:0;z-index:2}.fc .fc-timeline-bg .fc-non-business{z-index:1}.fc .fc-timeline-bg .fc-bg-event{z-index:2}.fc .fc-timeline-bg .fc-highlight{z-index:3}.fc .fc-timeline-bg-harness{bottom:0;position:absolute;top:0}";
|
|
1245
|
-
internal_cjs.injectStyles(css_248z);
|
|
1246
|
-
|
|
1247
|
-
exports.TimelineCoords = TimelineCoords;
|
|
1248
|
-
exports.TimelineHeader = TimelineHeader;
|
|
1249
|
-
exports.TimelineHeaderRows = TimelineHeaderRows;
|
|
1339
|
+
exports.TimelineHeaderRow = TimelineHeaderRow;
|
|
1250
1340
|
exports.TimelineLane = TimelineLane;
|
|
1251
1341
|
exports.TimelineLaneBg = TimelineLaneBg;
|
|
1252
1342
|
exports.TimelineLaneSlicer = TimelineLaneSlicer;
|
|
1343
|
+
exports.TimelineNowIndicatorArrow = TimelineNowIndicatorArrow;
|
|
1344
|
+
exports.TimelineNowIndicatorLine = TimelineNowIndicatorLine;
|
|
1253
1345
|
exports.TimelineSlats = TimelineSlats;
|
|
1254
1346
|
exports.TimelineView = TimelineView;
|
|
1255
|
-
exports.buildSlatCols = buildSlatCols;
|
|
1256
1347
|
exports.buildTimelineDateProfile = buildTimelineDateProfile;
|
|
1348
|
+
exports.computeSlotWidth = computeSlotWidth;
|
|
1257
1349
|
exports.coordToCss = coordToCss;
|
|
1258
1350
|
exports.coordsToCss = coordsToCss;
|
|
1351
|
+
exports.createHorizontalStyle = createHorizontalStyle;
|
|
1352
|
+
exports.createVerticalStyle = createVerticalStyle;
|
|
1353
|
+
exports.timeToCoord = timeToCoord;
|