@fullcalendar/timeline 6.1.15 → 7.0.0-beta.1
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 -1
- package/index.global.js +711 -596
- package/index.global.min.js +2 -2
- package/index.js +1 -1
- package/internal.cjs +709 -594
- package/internal.d.ts +142 -138
- package/internal.js +706 -594
- package/package.json +4 -4
package/internal.cjs
CHANGED
|
@@ -444,152 +444,91 @@ function buildCellObject(date, text, rowUnit) {
|
|
|
444
444
|
return { date, text, rowUnit, colspan: 1, isWeekStart: false };
|
|
445
445
|
}
|
|
446
446
|
|
|
447
|
-
class
|
|
447
|
+
class TimelineSlatCell extends internal_cjs.BaseComponent {
|
|
448
448
|
constructor() {
|
|
449
449
|
super(...arguments);
|
|
450
|
-
|
|
451
|
-
this.
|
|
450
|
+
// ref
|
|
451
|
+
this.innerElRef = preact_cjs.createRef();
|
|
452
452
|
}
|
|
453
453
|
render() {
|
|
454
454
|
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: [
|
|
455
|
+
let { dateEnv, options, theme } = context;
|
|
456
|
+
let { date, tDateProfile, isEm } = props;
|
|
457
|
+
let dateMeta = internal_cjs.getDateMeta(props.date, props.todayRange, props.nowDate, props.dateProfile);
|
|
458
|
+
let renderProps = Object.assign(Object.assign({ date: dateEnv.toDate(props.date) }, dateMeta), { view: context.viewApi });
|
|
459
|
+
return (preact_cjs.createElement(internal_cjs.ContentContainer, { elTag: "div", elClasses: [
|
|
460
|
+
'fc-flex-column',
|
|
461
|
+
'fc-align-start',
|
|
462
|
+
'fc-cell',
|
|
469
463
|
'fc-timeline-slot',
|
|
470
|
-
'fc-timeline-slot-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
464
|
+
'fc-timeline-slot-lane',
|
|
465
|
+
isEm ? 'fc-timeline-slot-em' : '',
|
|
466
|
+
tDateProfile.isTimeScale ? (internal_cjs.isInt(dateEnv.countDurationsBetween(// best to do this here?
|
|
467
|
+
tDateProfile.normalizedRange.start, props.date, tDateProfile.labelInterval)) ?
|
|
468
|
+
'fc-timeline-slot-major' :
|
|
469
|
+
'fc-timeline-slot-minor') : '',
|
|
470
|
+
...(props.isDay ?
|
|
471
|
+
internal_cjs.getDayClassNames(dateMeta, theme) :
|
|
472
|
+
internal_cjs.getSlotClassNames(dateMeta, theme)),
|
|
476
473
|
], elAttrs: {
|
|
477
|
-
|
|
478
|
-
'data-date': dateEnv.formatIso(cell.date, {
|
|
479
|
-
omitTime: !tDateProfile.isTimeScale,
|
|
474
|
+
'data-date': dateEnv.formatIso(date, {
|
|
480
475
|
omitTimeZoneOffset: true,
|
|
476
|
+
omitTime: !tDateProfile.isTimeScale,
|
|
481
477
|
}),
|
|
482
|
-
},
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
props.isSticky && 'fc-sticky',
|
|
487
|
-
], elAttrs: this.buildCellNavLinkAttrs(context, cell.date, cell.rowUnit) })))));
|
|
478
|
+
}, elStyle: {
|
|
479
|
+
width: props.width,
|
|
480
|
+
}, 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' },
|
|
481
|
+
preact_cjs.createElement(InnerContent, { elTag: "div", elClasses: ['fc-cell-inner'] })))));
|
|
488
482
|
}
|
|
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
|
-
})));
|
|
483
|
+
componentDidMount() {
|
|
484
|
+
const innerEl = this.innerElRef.current;
|
|
485
|
+
this.detachWidth = internal_cjs.watchWidth(innerEl, (width) => {
|
|
486
|
+
internal_cjs.setRef(this.props.innerWidthRef, width);
|
|
487
|
+
});
|
|
488
|
+
}
|
|
489
|
+
componentWillUnmount() {
|
|
490
|
+
this.detachWidth();
|
|
491
|
+
internal_cjs.setRef(this.props.innerWidthRef, null);
|
|
521
492
|
}
|
|
522
493
|
}
|
|
523
494
|
|
|
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;
|
|
495
|
+
class TimelineSlats extends internal_cjs.BaseComponent {
|
|
496
|
+
constructor() {
|
|
497
|
+
super(...arguments);
|
|
498
|
+
this.innerWidthRefMap = new internal_cjs.RefMap(() => {
|
|
499
|
+
internal_cjs.afterSize(this.handleInnerWidths);
|
|
500
|
+
});
|
|
501
|
+
this.handleInnerWidths = () => {
|
|
502
|
+
const innerWidthMap = this.innerWidthRefMap.current;
|
|
503
|
+
let max = 0;
|
|
504
|
+
for (const innerWidth of innerWidthMap.values()) {
|
|
505
|
+
max = Math.max(max, innerWidth);
|
|
576
506
|
}
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
coordFromLeft(coord) {
|
|
581
|
-
if (this.isRtl) {
|
|
582
|
-
return this.outerCoordCache.originClientRect.width - coord;
|
|
583
|
-
}
|
|
584
|
-
return coord;
|
|
507
|
+
// TODO: check to see if changed before firing ref!? YES. do in other places too
|
|
508
|
+
internal_cjs.setRef(this.props.innerWidthRef, max);
|
|
509
|
+
};
|
|
585
510
|
}
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
511
|
+
render() {
|
|
512
|
+
let { props, innerWidthRefMap } = this;
|
|
513
|
+
let { tDateProfile, slotWidth } = props;
|
|
514
|
+
let { slotDates, isWeekStarts } = tDateProfile;
|
|
515
|
+
let isDay = !tDateProfile.isTimeScale && !tDateProfile.largeUnit;
|
|
516
|
+
return (preact_cjs.createElement("div", { className: "fc-timeline-slots fc-fill fc-flex-row" }, slotDates.map((slotDate, i) => {
|
|
517
|
+
let key = slotDate.toISOString();
|
|
518
|
+
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,
|
|
519
|
+
// ref
|
|
520
|
+
innerWidthRef: innerWidthRefMap.createRef(key),
|
|
521
|
+
// dimensions
|
|
522
|
+
width: slotWidth }));
|
|
523
|
+
})));
|
|
589
524
|
}
|
|
590
525
|
}
|
|
526
|
+
|
|
527
|
+
/*
|
|
528
|
+
TODO: rename this file!
|
|
529
|
+
*/
|
|
591
530
|
// returned value is between 0 and the number of snaps
|
|
592
|
-
function computeDateSnapCoverage(date, tDateProfile, dateEnv) {
|
|
531
|
+
function computeDateSnapCoverage$1(date, tDateProfile, dateEnv) {
|
|
593
532
|
let snapDiff = dateEnv.countDurationsBetween(tDateProfile.normalizedRange.start, date, tDateProfile.snapDuration);
|
|
594
533
|
if (snapDiff < 0) {
|
|
595
534
|
return 0;
|
|
@@ -609,6 +548,9 @@ function computeDateSnapCoverage(date, tDateProfile, dateEnv) {
|
|
|
609
548
|
}
|
|
610
549
|
return snapCoverage;
|
|
611
550
|
}
|
|
551
|
+
/*
|
|
552
|
+
TODO: audit!!!
|
|
553
|
+
*/
|
|
612
554
|
function coordToCss(hcoord, isRtl) {
|
|
613
555
|
if (hcoord === null) {
|
|
614
556
|
return { left: '', right: '' };
|
|
@@ -618,6 +560,9 @@ function coordToCss(hcoord, isRtl) {
|
|
|
618
560
|
}
|
|
619
561
|
return { left: hcoord, right: '' };
|
|
620
562
|
}
|
|
563
|
+
/*
|
|
564
|
+
TODO: audit!!!
|
|
565
|
+
*/
|
|
621
566
|
function coordsToCss(hcoords, isRtl) {
|
|
622
567
|
if (!hcoords) {
|
|
623
568
|
return { left: '', right: '' };
|
|
@@ -627,216 +572,141 @@ function coordsToCss(hcoords, isRtl) {
|
|
|
627
572
|
}
|
|
628
573
|
return { left: hcoords.start, right: -hcoords.end };
|
|
629
574
|
}
|
|
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 }))))))));
|
|
575
|
+
/*
|
|
576
|
+
TODO: DRY up with elsewhere?
|
|
577
|
+
*/
|
|
578
|
+
function horizontalsToCss(hcoord, isRtl) {
|
|
579
|
+
if (!hcoord) {
|
|
580
|
+
return {};
|
|
653
581
|
}
|
|
654
|
-
|
|
655
|
-
|
|
582
|
+
if (isRtl) {
|
|
583
|
+
return { right: hcoord.start, width: hcoord.size };
|
|
656
584
|
}
|
|
657
|
-
|
|
658
|
-
|
|
585
|
+
else {
|
|
586
|
+
return { left: hcoord.start, width: hcoord.size };
|
|
659
587
|
}
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
}
|
|
588
|
+
}
|
|
589
|
+
function horizontalCoordToCss(start, isRtl) {
|
|
590
|
+
if (isRtl) {
|
|
591
|
+
return { right: start };
|
|
664
592
|
}
|
|
665
|
-
|
|
666
|
-
return
|
|
593
|
+
else {
|
|
594
|
+
return { left: start };
|
|
667
595
|
}
|
|
668
596
|
}
|
|
669
597
|
|
|
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" }))));
|
|
598
|
+
function createVerticalStyle(props) {
|
|
599
|
+
if (props) {
|
|
600
|
+
return {
|
|
601
|
+
top: props.start,
|
|
602
|
+
height: props.size,
|
|
603
|
+
};
|
|
693
604
|
}
|
|
694
605
|
}
|
|
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
|
-
}))));
|
|
606
|
+
function createHorizontalStyle(props, isRtl) {
|
|
607
|
+
if (props) {
|
|
608
|
+
return {
|
|
609
|
+
[isRtl ? 'right' : 'left']: props.start,
|
|
610
|
+
width: props.size,
|
|
611
|
+
};
|
|
707
612
|
}
|
|
708
613
|
}
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
};
|
|
614
|
+
// Timeline-specific
|
|
615
|
+
// -------------------------------------------------------------------------------------------------
|
|
616
|
+
const MIN_SLOT_WIDTH = 30; // for real
|
|
617
|
+
/*
|
|
618
|
+
TODO: DRY with computeSlatHeight?
|
|
619
|
+
*/
|
|
620
|
+
function computeSlotWidth(slatCnt, slatsPerLabel, slatMinWidth, labelInnerWidth, viewportWidth) {
|
|
621
|
+
if (labelInnerWidth == null || viewportWidth == null) {
|
|
622
|
+
return [undefined, undefined, false];
|
|
623
|
+
}
|
|
624
|
+
slatMinWidth = Math.max(slatMinWidth || 0, (labelInnerWidth + 1) / slatsPerLabel, MIN_SLOT_WIDTH);
|
|
625
|
+
const slatTryWidth = viewportWidth / slatCnt;
|
|
626
|
+
let slatLiquid;
|
|
627
|
+
let slatWidth;
|
|
628
|
+
if (slatTryWidth >= slatMinWidth) {
|
|
629
|
+
slatLiquid = true;
|
|
630
|
+
slatWidth = slatTryWidth;
|
|
727
631
|
}
|
|
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 }))));
|
|
632
|
+
else {
|
|
633
|
+
slatLiquid = false;
|
|
634
|
+
slatWidth = Math.max(slatMinWidth, slatTryWidth);
|
|
737
635
|
}
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
636
|
+
return [slatWidth * slatCnt, slatWidth, slatLiquid];
|
|
637
|
+
}
|
|
638
|
+
function timeToCoord(// pixels
|
|
639
|
+
time, dateEnv, dateProfile, tDateProfile, slowWidth) {
|
|
640
|
+
let date = dateEnv.add(dateProfile.activeRange.start, time);
|
|
641
|
+
if (!tDateProfile.isTimeScale) {
|
|
642
|
+
date = internal_cjs.startOfDay(date);
|
|
741
643
|
}
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
644
|
+
return dateToCoord(date, dateEnv, tDateProfile, slowWidth);
|
|
645
|
+
}
|
|
646
|
+
function dateToCoord(// pixels
|
|
647
|
+
date, dateEnv, tDateProfile, slotWidth) {
|
|
648
|
+
let snapCoverage = computeDateSnapCoverage(date, tDateProfile, dateEnv);
|
|
649
|
+
let slotCoverage = snapCoverage / tDateProfile.snapsPerSlot;
|
|
650
|
+
return slotCoverage * slotWidth;
|
|
651
|
+
}
|
|
652
|
+
/*
|
|
653
|
+
returned value is between 0 and the number of snaps
|
|
654
|
+
*/
|
|
655
|
+
function computeDateSnapCoverage(date, tDateProfile, dateEnv) {
|
|
656
|
+
let snapDiff = dateEnv.countDurationsBetween(tDateProfile.normalizedRange.start, date, tDateProfile.snapDuration);
|
|
657
|
+
if (snapDiff < 0) {
|
|
658
|
+
return 0;
|
|
745
659
|
}
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
if (this.props.onCoords) {
|
|
749
|
-
this.props.onCoords(null);
|
|
750
|
-
}
|
|
660
|
+
if (snapDiff >= tDateProfile.snapDiffToIndex.length) {
|
|
661
|
+
return tDateProfile.snapCnt;
|
|
751
662
|
}
|
|
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
|
-
}
|
|
663
|
+
let snapDiffInt = Math.floor(snapDiff);
|
|
664
|
+
let snapCoverage = tDateProfile.snapDiffToIndex[snapDiffInt];
|
|
665
|
+
if (internal_cjs.isInt(snapCoverage)) { // not an in-between value
|
|
666
|
+
snapCoverage += snapDiff - snapDiffInt; // add the remainder
|
|
767
667
|
}
|
|
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;
|
|
668
|
+
else {
|
|
669
|
+
// a fractional value, meaning the date is not visible
|
|
670
|
+
// always round up in this case. works for start AND end dates in a range.
|
|
671
|
+
snapCoverage = Math.ceil(snapCoverage);
|
|
793
672
|
}
|
|
794
|
-
|
|
795
|
-
function collectCellEls(elMap, slotDates) {
|
|
796
|
-
return slotDates.map((slotDate) => {
|
|
797
|
-
let key = slotDate.toISOString();
|
|
798
|
-
return elMap[key];
|
|
799
|
-
});
|
|
673
|
+
return snapCoverage;
|
|
800
674
|
}
|
|
801
675
|
|
|
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
|
-
}
|
|
676
|
+
function computeManySegHorizontals(segs, segMinWidth, dateEnv, tDateProfile, slotWidth) {
|
|
677
|
+
const res = {};
|
|
678
|
+
for (const seg of segs) {
|
|
679
|
+
res[seg.eventRange.instance.instanceId] = computeSegHorizontals(seg, segMinWidth, dateEnv, tDateProfile, slotWidth);
|
|
814
680
|
}
|
|
815
|
-
return
|
|
681
|
+
return res;
|
|
682
|
+
}
|
|
683
|
+
function computeSegHorizontals(seg, segMinWidth, dateEnv, tDateProfile, slotWidth) {
|
|
684
|
+
const startCoord = dateToCoord(seg.start, dateEnv, tDateProfile, slotWidth);
|
|
685
|
+
const endCoord = dateToCoord(seg.end, dateEnv, tDateProfile, slotWidth);
|
|
686
|
+
let size = endCoord - startCoord;
|
|
687
|
+
if (segMinWidth) {
|
|
688
|
+
size = Math.max(size, segMinWidth);
|
|
689
|
+
}
|
|
690
|
+
return { start: startCoord, size };
|
|
816
691
|
}
|
|
817
|
-
function computeFgSegPlacements(
|
|
818
|
-
|
|
819
|
-
moreLinkHeights, // might not have for every more-link
|
|
692
|
+
function computeFgSegPlacements(// mostly horizontals
|
|
693
|
+
segs, segHorizontals, segHeights, // keyed by instanceId
|
|
820
694
|
strictOrder, maxStackCnt) {
|
|
821
|
-
let
|
|
822
|
-
let crudePlacements = []; // when we don't know dims
|
|
695
|
+
let segEntries = [];
|
|
823
696
|
for (let i = 0; i < segs.length; i += 1) {
|
|
824
697
|
let seg = segs[i];
|
|
825
698
|
let instanceId = seg.eventRange.instance.instanceId;
|
|
826
|
-
let height =
|
|
827
|
-
let hcoords =
|
|
828
|
-
if (height && hcoords) {
|
|
829
|
-
|
|
699
|
+
let height = segHeights.get(instanceId);
|
|
700
|
+
let hcoords = segHorizontals[instanceId];
|
|
701
|
+
if (height != null && hcoords != null) {
|
|
702
|
+
segEntries.push({
|
|
830
703
|
index: i,
|
|
831
|
-
span: hcoords,
|
|
832
|
-
thickness: height,
|
|
833
|
-
});
|
|
834
|
-
}
|
|
835
|
-
else {
|
|
836
|
-
crudePlacements.push({
|
|
837
704
|
seg,
|
|
838
|
-
|
|
839
|
-
|
|
705
|
+
span: {
|
|
706
|
+
start: hcoords.start,
|
|
707
|
+
end: hcoords.start + hcoords.size,
|
|
708
|
+
},
|
|
709
|
+
thickness: height,
|
|
840
710
|
});
|
|
841
711
|
}
|
|
842
712
|
}
|
|
@@ -847,80 +717,84 @@ strictOrder, maxStackCnt) {
|
|
|
847
717
|
if (maxStackCnt != null) {
|
|
848
718
|
hierarchy.maxStackCnt = maxStackCnt;
|
|
849
719
|
}
|
|
850
|
-
let hiddenEntries = hierarchy.addSegs(
|
|
851
|
-
let hiddenPlacements = hiddenEntries.map((entry) => ({
|
|
852
|
-
seg: segs[entry.index],
|
|
853
|
-
hcoords: entry.span,
|
|
854
|
-
top: null,
|
|
855
|
-
}));
|
|
720
|
+
let hiddenEntries = hierarchy.addSegs(segEntries);
|
|
856
721
|
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
|
-
}
|
|
722
|
+
let hiddenGroupEntries = hiddenGroups.map((hiddenGroup, index) => ({
|
|
723
|
+
index: segs.length + index,
|
|
724
|
+
segGroup: hiddenGroup,
|
|
725
|
+
span: hiddenGroup.span,
|
|
726
|
+
thickness: 1, // HACK to ensure it's placed
|
|
727
|
+
}));
|
|
880
728
|
// add more-links into the hierarchy, but don't limit
|
|
881
729
|
hierarchy.maxStackCnt = -1;
|
|
882
|
-
hierarchy.addSegs(
|
|
730
|
+
hierarchy.addSegs(hiddenGroupEntries);
|
|
883
731
|
let visibleRects = hierarchy.toRects();
|
|
884
|
-
let
|
|
885
|
-
let
|
|
732
|
+
let segTops = {};
|
|
733
|
+
let hiddenGroupTops = {};
|
|
886
734
|
for (let rect of visibleRects) {
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
seg
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
});
|
|
895
|
-
maxHeight = Math.max(maxHeight, rect.levelCoord + rect.thickness);
|
|
735
|
+
const { seg, segGroup } = rect;
|
|
736
|
+
if (seg) { // regular seg
|
|
737
|
+
segTops[seg.eventRange.instance.instanceId] = rect.levelCoord;
|
|
738
|
+
}
|
|
739
|
+
else { // hiddenGroup
|
|
740
|
+
hiddenGroupTops[segGroup.key] = rect.levelCoord;
|
|
741
|
+
}
|
|
896
742
|
}
|
|
897
743
|
return [
|
|
898
|
-
|
|
899
|
-
|
|
744
|
+
segTops,
|
|
745
|
+
computeMaxBottom(segs, segTops, segHeights),
|
|
746
|
+
hiddenGroups,
|
|
747
|
+
hiddenGroupTops,
|
|
900
748
|
];
|
|
901
749
|
}
|
|
750
|
+
function computeMaxBottom(segs, segTops, segHeights) {
|
|
751
|
+
let max = 0;
|
|
752
|
+
for (const seg of segs) {
|
|
753
|
+
const { instanceId } = seg.eventRange.instance;
|
|
754
|
+
const top = segTops[instanceId];
|
|
755
|
+
const height = segHeights.get(instanceId);
|
|
756
|
+
if (top != null && height != null) {
|
|
757
|
+
max = Math.max(max, top + height);
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
return max;
|
|
761
|
+
}
|
|
762
|
+
/*
|
|
763
|
+
TODO: converge with computeMaxBottom, but keys are different
|
|
764
|
+
*/
|
|
765
|
+
function computeMoreLinkMaxBottom(hiddenGroups, hiddenGroupTops, hiddenGroupHeights) {
|
|
766
|
+
let max = 0;
|
|
767
|
+
for (const hiddenGroup of hiddenGroups) {
|
|
768
|
+
const top = hiddenGroupTops[hiddenGroup.key];
|
|
769
|
+
const height = hiddenGroupHeights.get(hiddenGroup.key);
|
|
770
|
+
if (top != null && height != null) {
|
|
771
|
+
max = Math.max(max, top + height);
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
return max;
|
|
775
|
+
}
|
|
902
776
|
|
|
903
777
|
class TimelineLaneBg extends internal_cjs.BaseComponent {
|
|
904
778
|
render() {
|
|
905
779
|
let { props } = this;
|
|
906
780
|
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
|
-
|
|
781
|
+
return (preact_cjs.createElement("div", { className: "fc-timeline-bg" },
|
|
782
|
+
this.renderSegs(props.businessHourSegs || [], 'non-business'),
|
|
783
|
+
this.renderSegs(props.bgEventSegs || [], 'bg-event'),
|
|
784
|
+
this.renderSegs(highlightSeg, 'highlight')));
|
|
785
|
+
}
|
|
786
|
+
renderSegs(segs, fillType) {
|
|
787
|
+
let { tDateProfile, todayRange, nowDate, slotWidth } = this.props;
|
|
788
|
+
let { dateEnv, isRtl } = this.context;
|
|
789
|
+
return (preact_cjs.createElement(preact_cjs.Fragment, null, segs.map((seg) => {
|
|
790
|
+
let hStyle; // TODO
|
|
791
|
+
if (slotWidth != null) {
|
|
792
|
+
let segHorizontal = computeSegHorizontals(seg, undefined, dateEnv, tDateProfile, slotWidth);
|
|
793
|
+
hStyle = horizontalsToCss(segHorizontal, isRtl);
|
|
794
|
+
}
|
|
919
795
|
return (preact_cjs.createElement("div", { key: internal_cjs.buildEventRangeKey(seg.eventRange), className: "fc-timeline-bg-harness", style: hStyle }, fillType === 'bg-event' ?
|
|
920
|
-
preact_cjs.createElement(internal_cjs.BgEvent, Object.assign({ seg: seg }, internal_cjs.
|
|
921
|
-
|
|
922
|
-
});
|
|
923
|
-
return preact_cjs.createElement(preact_cjs.Fragment, null, children);
|
|
796
|
+
preact_cjs.createElement(internal_cjs.BgEvent, Object.assign({ eventRange: seg.eventRange, isStart: seg.isStart, isEnd: seg.isEnd }, internal_cjs.getEventRangeMeta(seg.eventRange, todayRange, nowDate))) : (internal_cjs.renderFill(fillType))));
|
|
797
|
+
})));
|
|
924
798
|
}
|
|
925
799
|
}
|
|
926
800
|
|
|
@@ -929,8 +803,8 @@ class TimelineLaneSlicer extends internal_cjs.Slicer {
|
|
|
929
803
|
let normalRange = normalizeRange(origRange, tDateProfile, dateEnv);
|
|
930
804
|
let segs = [];
|
|
931
805
|
// 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)) {
|
|
806
|
+
if (computeDateSnapCoverage$1(normalRange.start, tDateProfile, dateEnv)
|
|
807
|
+
< computeDateSnapCoverage$1(normalRange.end, tDateProfile, dateEnv)) {
|
|
934
808
|
// intersect the footprint's range with the grid's range
|
|
935
809
|
let slicedRange = internal_cjs.intersectRanges(normalRange, tDateProfile.normalizedRange);
|
|
936
810
|
if (slicedRange) {
|
|
@@ -956,48 +830,86 @@ const DEFAULT_TIME_FORMAT = internal_cjs.createFormatter({
|
|
|
956
830
|
});
|
|
957
831
|
class TimelineEvent extends internal_cjs.BaseComponent {
|
|
958
832
|
render() {
|
|
959
|
-
let { props } = this;
|
|
960
|
-
|
|
833
|
+
let { props, context } = this;
|
|
834
|
+
let { options } = context;
|
|
835
|
+
return (preact_cjs.createElement(internal_cjs.StandardEvent, Object.assign({}, props, { elClasses: [
|
|
836
|
+
'fc-timeline-event',
|
|
837
|
+
'fc-h-event',
|
|
838
|
+
options.eventOverlap === false // TODO: fix bad default
|
|
839
|
+
? 'fc-timeline-event-spacious'
|
|
840
|
+
: ''
|
|
841
|
+
], defaultTimeFormat: DEFAULT_TIME_FORMAT, defaultDisplayEventTime: !props.isTimeScale })));
|
|
961
842
|
}
|
|
962
843
|
}
|
|
963
844
|
|
|
964
845
|
class TimelineLaneMoreLink extends internal_cjs.BaseComponent {
|
|
965
846
|
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);
|
|
847
|
+
let { props } = this;
|
|
848
|
+
let { hiddenSegs, resourceId, forcedInvisibleMap } = props;
|
|
971
849
|
let extraDateSpan = resourceId ? { resourceId } : {};
|
|
972
|
-
return (preact_cjs.createElement(internal_cjs.MoreLinkContainer, {
|
|
973
|
-
let
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
850
|
+
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) => {
|
|
851
|
+
let { eventRange } = seg;
|
|
852
|
+
let instanceId = eventRange.instance.instanceId;
|
|
853
|
+
return (preact_cjs.createElement("div", { key: instanceId, style: { visibility: forcedInvisibleMap[instanceId] ? 'hidden' : '' } },
|
|
854
|
+
preact_cjs.createElement(TimelineEvent, Object.assign({ isTimeScale: props.isTimeScale, eventRange: eventRange, isStart: seg.isStart, isEnd: seg.isEnd, isDragging: false, isResizing: false, isDateSelecting: false, isSelected: instanceId === props.eventSelection }, internal_cjs.getEventRangeMeta(eventRange, props.todayRange, props.nowDate)))));
|
|
855
|
+
}))) }, (InnerContent) => (preact_cjs.createElement(InnerContent, { elTag: "div", elClasses: ['fc-timeline-more-link-inner', 'fc-sticky-x'] }))));
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
/*
|
|
860
|
+
TODO: make DRY with other Event Harnesses
|
|
861
|
+
*/
|
|
862
|
+
class TimelineEventHarness extends preact_cjs.Component {
|
|
863
|
+
constructor() {
|
|
864
|
+
super(...arguments);
|
|
865
|
+
// ref
|
|
866
|
+
this.rootElRef = preact_cjs.createRef();
|
|
867
|
+
}
|
|
868
|
+
render() {
|
|
869
|
+
const { props } = this;
|
|
870
|
+
return (preact_cjs.createElement("div", { className: "fc-abs", style: props.style, ref: this.rootElRef }, props.children));
|
|
871
|
+
}
|
|
872
|
+
componentDidMount() {
|
|
873
|
+
const rootEl = this.rootElRef.current; // TODO: make dynamic with useEffect
|
|
874
|
+
this.detachHeight = internal_cjs.watchHeight(rootEl, (height) => {
|
|
875
|
+
internal_cjs.setRef(this.props.heightRef, height);
|
|
876
|
+
});
|
|
877
|
+
}
|
|
878
|
+
componentWillUnmount() {
|
|
879
|
+
this.detachHeight();
|
|
880
|
+
internal_cjs.setRef(this.props.heightRef, null);
|
|
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,290 @@ 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 { eventRange } = seg;
|
|
959
|
+
const { instanceId } = eventRange.instance;
|
|
960
|
+
const segTop = segTops[instanceId];
|
|
961
|
+
const segHorizontal = segHorizontals[instanceId];
|
|
962
|
+
const isVisible = isMirror ||
|
|
963
|
+
(segHorizontal && segTop != null && !forcedInvisibleMap[instanceId]);
|
|
964
|
+
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) },
|
|
965
|
+
preact_cjs.createElement(TimelineEvent, Object.assign({ isTimeScale: props.tDateProfile.isTimeScale, eventRange: eventRange, isStart: seg.isStart, isEnd: seg.isEnd, isDragging: isDragging, isResizing: isResizing, isDateSelecting: isDateSelecting, isSelected: instanceId === props.eventSelection /* TODO: bad for mirror? */ }, internal_cjs.getEventRangeMeta(eventRange, props.todayRange, props.nowDate)))));
|
|
966
|
+
}),
|
|
967
|
+
hiddenGroups.map((hiddenGroup) => (preact_cjs.createElement(TimelineEventHarness, { key: hiddenGroup.key, style: Object.assign({ top: hiddenGroupTops[hiddenGroup.key] || 0 }, horizontalsToCss({
|
|
968
|
+
start: hiddenGroup.span.start,
|
|
969
|
+
size: hiddenGroup.span.end - hiddenGroup.span.start
|
|
970
|
+
}, context.isRtl)), heightRef: moreLinkHeightRefMap.createRef(hiddenGroup.key) },
|
|
971
|
+
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 }))))));
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
class TimelineHeaderCell extends internal_cjs.BaseComponent {
|
|
976
|
+
constructor() {
|
|
977
|
+
super(...arguments);
|
|
978
|
+
// memo
|
|
979
|
+
this.refineRenderProps = internal_cjs.memoizeObjArg(refineRenderProps);
|
|
980
|
+
this.buildCellNavLinkAttrs = internal_cjs.memoize(buildCellNavLinkAttrs);
|
|
981
|
+
// ref
|
|
982
|
+
this.innerElRef = preact_cjs.createRef();
|
|
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
|
|
1044
|
+
const { props } = this;
|
|
1045
|
+
this.detachSize();
|
|
1046
|
+
internal_cjs.setRef(props.innerWidthRef, null);
|
|
1047
|
+
internal_cjs.setRef(props.innerHeightRef, null);
|
|
1035
1048
|
}
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
}
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1049
|
+
}
|
|
1050
|
+
// Utils
|
|
1051
|
+
// -------------------------------------------------------------------------------------------------
|
|
1052
|
+
function buildCellNavLinkAttrs(context, cellDate, rowUnit) {
|
|
1053
|
+
return (rowUnit && rowUnit !== 'time')
|
|
1054
|
+
? internal_cjs.buildNavLinkAttrs(context, cellDate, rowUnit)
|
|
1055
|
+
: {};
|
|
1056
|
+
}
|
|
1057
|
+
function renderInnerContent(renderProps) {
|
|
1058
|
+
return renderProps.text;
|
|
1059
|
+
}
|
|
1060
|
+
function refineRenderProps(input) {
|
|
1061
|
+
return {
|
|
1062
|
+
level: input.level,
|
|
1063
|
+
date: input.dateEnv.toDate(input.dateMarker),
|
|
1064
|
+
view: input.viewApi,
|
|
1065
|
+
text: input.text,
|
|
1066
|
+
};
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
class TimelineHeaderRow extends internal_cjs.BaseComponent {
|
|
1070
|
+
constructor() {
|
|
1071
|
+
super(...arguments);
|
|
1072
|
+
// refs
|
|
1073
|
+
this.innerWidthRefMap = new internal_cjs.RefMap(() => {
|
|
1074
|
+
internal_cjs.afterSize(this.handleInnerWidths);
|
|
1075
|
+
});
|
|
1076
|
+
this.innerHeightRefMap = new internal_cjs.RefMap(() => {
|
|
1077
|
+
internal_cjs.afterSize(this.handleInnerHeights);
|
|
1078
|
+
});
|
|
1079
|
+
this.handleInnerWidths = () => {
|
|
1080
|
+
const innerWidthMap = this.innerWidthRefMap.current;
|
|
1081
|
+
let max = 0;
|
|
1082
|
+
for (const innerWidth of innerWidthMap.values()) {
|
|
1083
|
+
max = Math.max(max, innerWidth);
|
|
1084
|
+
}
|
|
1085
|
+
// TODO: ensure not equal?
|
|
1086
|
+
internal_cjs.setRef(this.props.innerWidthRef, max);
|
|
1087
|
+
};
|
|
1088
|
+
this.handleInnerHeights = () => {
|
|
1089
|
+
const innerHeightMap = this.innerHeightRefMap.current;
|
|
1090
|
+
let max = 0;
|
|
1091
|
+
for (const innerHeight of innerHeightMap.values()) {
|
|
1092
|
+
max = Math.max(max, innerHeight);
|
|
1066
1093
|
}
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1094
|
+
// TODO: ensure not equal?
|
|
1095
|
+
internal_cjs.setRef(this.props.innerHeighRef, max);
|
|
1096
|
+
};
|
|
1097
|
+
}
|
|
1098
|
+
render() {
|
|
1099
|
+
const { props, innerWidthRefMap, innerHeightRefMap } = this;
|
|
1100
|
+
const isCentered = !(props.tDateProfile.isTimeScale && props.isLastRow);
|
|
1101
|
+
const isSticky = !props.isLastRow;
|
|
1102
|
+
return (preact_cjs.createElement("div", { className: 'fc-row', style: { height: props.height } }, props.cells.map((cell) => {
|
|
1103
|
+
// TODO: make this part of the cell obj?
|
|
1104
|
+
// TODO: rowUnit seems wrong sometimes. says 'month' when it should be day
|
|
1105
|
+
// TODO: rowUnit is relevant to whole row. put it on a row object, not the cells
|
|
1106
|
+
// TODO: use rowUnit to key the Row itself?
|
|
1107
|
+
const key = cell.rowUnit + ':' + cell.date.toISOString();
|
|
1108
|
+
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,
|
|
1109
|
+
// refs
|
|
1110
|
+
innerWidthRef: innerWidthRefMap.createRef(key), innerHeightRef: innerHeightRefMap.createRef(key),
|
|
1111
|
+
// dimensions
|
|
1112
|
+
slotWidth: props.slotWidth }));
|
|
1072
1113
|
})));
|
|
1073
1114
|
}
|
|
1115
|
+
componentWillUnmount() {
|
|
1116
|
+
internal_cjs.setRef(this.props.innerWidthRef, null);
|
|
1117
|
+
internal_cjs.setRef(this.props.innerHeighRef, null);
|
|
1118
|
+
}
|
|
1074
1119
|
}
|
|
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
|
-
}));
|
|
1120
|
+
|
|
1121
|
+
class TimelineNowIndicatorLine extends internal_cjs.BaseComponent {
|
|
1122
|
+
render() {
|
|
1123
|
+
const { props, context } = this;
|
|
1124
|
+
return (preact_cjs.createElement("div", { className: "fc-timeline-now-indicator-container" },
|
|
1125
|
+
preact_cjs.createElement(internal_cjs.NowIndicatorContainer // TODO: make separate component?
|
|
1126
|
+
, { elClasses: ['fc-timeline-now-indicator-line'], elStyle: props.slotWidth != null
|
|
1127
|
+
? horizontalCoordToCss(dateToCoord(props.nowDate, context.dateEnv, props.tDateProfile, props.slotWidth), context.isRtl)
|
|
1128
|
+
: {}, isAxis: false, date: props.nowDate })));
|
|
1129
|
+
}
|
|
1089
1130
|
}
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1131
|
+
|
|
1132
|
+
class TimelineNowIndicatorArrow extends internal_cjs.BaseComponent {
|
|
1133
|
+
render() {
|
|
1134
|
+
const { props, context } = this;
|
|
1135
|
+
return (preact_cjs.createElement("div", { className: "fc-timeline-now-indicator-container" },
|
|
1136
|
+
preact_cjs.createElement(internal_cjs.NowIndicatorContainer, { elClasses: ['fc-timeline-now-indicator-arrow'], elStyle: props.slotWidth != null
|
|
1137
|
+
? horizontalCoordToCss(dateToCoord(props.nowDate, context.dateEnv, props.tDateProfile, props.slotWidth), context.isRtl)
|
|
1138
|
+
: {}, isAxis: true, date: props.nowDate })));
|
|
1097
1139
|
}
|
|
1098
|
-
return topsByInstanceId;
|
|
1099
1140
|
}
|
|
1100
1141
|
|
|
1101
|
-
class
|
|
1142
|
+
class TimelineView extends internal_cjs.DateComponent {
|
|
1102
1143
|
constructor() {
|
|
1103
1144
|
super(...arguments);
|
|
1104
|
-
|
|
1105
|
-
this.
|
|
1106
|
-
|
|
1145
|
+
// memoized
|
|
1146
|
+
this.buildTimelineDateProfile = internal_cjs.memoize(buildTimelineDateProfile);
|
|
1147
|
+
this.computeSlotWidth = internal_cjs.memoize(computeSlotWidth);
|
|
1148
|
+
// refs
|
|
1149
|
+
this.headerScrollerRef = preact_cjs.createRef();
|
|
1150
|
+
this.bodyScrollerRef = preact_cjs.createRef();
|
|
1151
|
+
this.footerScrollerRef = preact_cjs.createRef();
|
|
1152
|
+
this.headerRowInnerWidthMap = new internal_cjs.RefMap(() => {
|
|
1153
|
+
internal_cjs.afterSize(this.handleSlotInnerWidths);
|
|
1154
|
+
});
|
|
1155
|
+
this.scrollTime = null;
|
|
1156
|
+
// Sizing
|
|
1157
|
+
// -----------------------------------------------------------------------------------------------
|
|
1158
|
+
this.handleBodySlotInnerWidth = (innerWidth) => {
|
|
1159
|
+
this.bodySlotInnerWidth = innerWidth;
|
|
1160
|
+
internal_cjs.afterSize(this.handleSlotInnerWidths);
|
|
1161
|
+
};
|
|
1162
|
+
this.handleSlotInnerWidths = () => {
|
|
1163
|
+
const { state } = this;
|
|
1164
|
+
const slotInnerWidth = Math.max(this.headerRowInnerWidthMap.current.get(this.tDateProfile.cellRows.length - 1) || 0, this.bodySlotInnerWidth);
|
|
1165
|
+
if (state.slotInnerWidth !== slotInnerWidth) {
|
|
1166
|
+
this.setState({ slotInnerWidth });
|
|
1167
|
+
}
|
|
1168
|
+
};
|
|
1169
|
+
this.handleScrollerWidth = (scrollerWidth) => {
|
|
1170
|
+
this.setState({
|
|
1171
|
+
scrollerWidth,
|
|
1172
|
+
});
|
|
1107
1173
|
};
|
|
1108
|
-
this.
|
|
1174
|
+
this.handleLeftScrollbarWidth = (leftScrollbarWidth) => {
|
|
1175
|
+
this.setState({
|
|
1176
|
+
leftScrollbarWidth
|
|
1177
|
+
});
|
|
1178
|
+
};
|
|
1179
|
+
this.handleRightScrollbarWidth = (rightScrollbarWidth) => {
|
|
1180
|
+
this.setState({
|
|
1181
|
+
rightScrollbarWidth
|
|
1182
|
+
});
|
|
1183
|
+
};
|
|
1184
|
+
this.handleTimeScroll = (scrollTime) => {
|
|
1185
|
+
this.scrollTime = scrollTime;
|
|
1186
|
+
this.updateScroll();
|
|
1187
|
+
};
|
|
1188
|
+
this.updateScroll = () => {
|
|
1189
|
+
const { props, context, tDateProfile, scrollTime, slotWidth } = this;
|
|
1190
|
+
if (scrollTime != null && slotWidth != null) {
|
|
1191
|
+
let x = timeToCoord(scrollTime, context.dateEnv, props.dateProfile, tDateProfile, slotWidth);
|
|
1192
|
+
if (x) {
|
|
1193
|
+
x += context.isRtl ? -1 : 1; // overcome border. TODO: DRY this up
|
|
1194
|
+
}
|
|
1195
|
+
this.syncedScroller.scrollTo({ x });
|
|
1196
|
+
}
|
|
1197
|
+
};
|
|
1198
|
+
this.clearScroll = () => {
|
|
1199
|
+
this.scrollTime = null;
|
|
1200
|
+
};
|
|
1201
|
+
// Hit System
|
|
1202
|
+
// -----------------------------------------------------------------------------------------------
|
|
1203
|
+
this.handeBodyEl = (el) => {
|
|
1204
|
+
this.bodyEl = el;
|
|
1109
1205
|
if (el) {
|
|
1110
1206
|
this.context.registerInteractiveComponent(this, { el });
|
|
1111
1207
|
}
|
|
@@ -1113,45 +1209,143 @@ class TimelineGrid extends internal_cjs.DateComponent {
|
|
|
1113
1209
|
this.context.unregisterInteractiveComponent(this);
|
|
1114
1210
|
}
|
|
1115
1211
|
};
|
|
1116
|
-
this.handleCoords = (coords) => {
|
|
1117
|
-
this.setState({ coords });
|
|
1118
|
-
if (this.props.onSlatCoords) {
|
|
1119
|
-
this.props.onSlatCoords(coords);
|
|
1120
|
-
}
|
|
1121
|
-
};
|
|
1122
1212
|
}
|
|
1123
1213
|
render() {
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1214
|
+
const { props, state, context } = this;
|
|
1215
|
+
const { options } = context;
|
|
1216
|
+
/* date */
|
|
1217
|
+
const tDateProfile = this.tDateProfile = this.buildTimelineDateProfile(props.dateProfile, context.dateEnv, options, context.dateProfileGenerator);
|
|
1218
|
+
const { cellRows } = tDateProfile;
|
|
1219
|
+
const timerUnit = internal_cjs.greatestDurationDenominator(tDateProfile.slotDuration).unit;
|
|
1220
|
+
/* table settings */
|
|
1221
|
+
const verticalScrolling = !props.forPrint && !internal_cjs.getIsHeightAuto(options);
|
|
1222
|
+
const stickyHeaderDates = !props.forPrint && internal_cjs.getStickyHeaderDates(options);
|
|
1223
|
+
const stickyFooterScrollbar = !props.forPrint && internal_cjs.getStickyFooterScrollbar(options);
|
|
1224
|
+
/* table positions */
|
|
1225
|
+
const [canvasWidth, slotWidth] = this.computeSlotWidth(tDateProfile.slotCnt, tDateProfile.slotsPerLabel, options.slotMinWidth, state.slotInnerWidth, // is ACTUALLY the label width. rename?
|
|
1226
|
+
state.scrollerWidth);
|
|
1227
|
+
this.slotWidth = slotWidth;
|
|
1228
|
+
return (preact_cjs.createElement(internal_cjs.NowTimer, { unit: timerUnit }, (nowDate, todayRange) => {
|
|
1229
|
+
const enableNowIndicator = // TODO: DRY
|
|
1230
|
+
options.nowIndicator &&
|
|
1231
|
+
slotWidth != null &&
|
|
1232
|
+
internal_cjs.rangeContainsMarker(props.dateProfile.currentRange, nowDate);
|
|
1233
|
+
return (preact_cjs.createElement(internal_cjs.ViewContainer, { viewSpec: context.viewSpec, elClasses: [
|
|
1234
|
+
'fc-timeline-view',
|
|
1235
|
+
'fc-flex-column',
|
|
1236
|
+
'fc-border',
|
|
1237
|
+
] },
|
|
1238
|
+
preact_cjs.createElement(internal_cjs.Scroller, { horizontal: true, hideScrollbars: true, elClassNames: [
|
|
1239
|
+
'fc-timeline-header',
|
|
1240
|
+
'fc-rowgroup',
|
|
1241
|
+
stickyHeaderDates ? 'fc-sticky-header' : '',
|
|
1242
|
+
], ref: this.headerScrollerRef },
|
|
1243
|
+
preact_cjs.createElement("div", { className: 'fc-rel fc-content-box' // origin for now-indicator
|
|
1244
|
+
, style: {
|
|
1245
|
+
width: canvasWidth,
|
|
1246
|
+
paddingLeft: state.leftScrollbarWidth,
|
|
1247
|
+
paddingRight: state.rightScrollbarWidth,
|
|
1248
|
+
} },
|
|
1249
|
+
preact_cjs.createElement("div", null, cellRows.map((cells, rowLevel) => {
|
|
1250
|
+
const isLast = rowLevel === cellRows.length - 1;
|
|
1251
|
+
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: this.headerRowInnerWidthMap.createRef(rowLevel) }));
|
|
1252
|
+
})),
|
|
1253
|
+
enableNowIndicator && (
|
|
1254
|
+
// TODO: make this positioned WITHIN padding?
|
|
1255
|
+
preact_cjs.createElement(TimelineNowIndicatorArrow, { tDateProfile: tDateProfile, nowDate: nowDate, slotWidth: slotWidth })))),
|
|
1256
|
+
preact_cjs.createElement(internal_cjs.Scroller, { vertical: verticalScrolling, horizontal: true, elClassNames: [
|
|
1257
|
+
'fc-timeline-body',
|
|
1258
|
+
'fc-rowgroup',
|
|
1259
|
+
verticalScrolling ? 'fc-liquid' : '',
|
|
1260
|
+
], ref: this.bodyScrollerRef, widthRef: this.handleScrollerWidth, leftScrollbarWidthRef: this.handleLeftScrollbarWidth, rightScrollbarWidthRef: this.handleRightScrollbarWidth },
|
|
1261
|
+
preact_cjs.createElement("div", { className: "fc-rel fc-grow", style: {
|
|
1262
|
+
width: canvasWidth,
|
|
1263
|
+
}, ref: this.handeBodyEl },
|
|
1264
|
+
preact_cjs.createElement(TimelineSlats, { dateProfile: props.dateProfile, tDateProfile: tDateProfile, nowDate: nowDate, todayRange: todayRange,
|
|
1265
|
+
// ref
|
|
1266
|
+
innerWidthRef: this.handleBodySlotInnerWidth,
|
|
1267
|
+
// dimensions
|
|
1268
|
+
slotWidth: slotWidth }),
|
|
1269
|
+
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 }),
|
|
1270
|
+
enableNowIndicator && (preact_cjs.createElement(TimelineNowIndicatorLine, { tDateProfile: tDateProfile, nowDate: nowDate, slotWidth: slotWidth })))),
|
|
1271
|
+
stickyFooterScrollbar && (preact_cjs.createElement(internal_cjs.Scroller, { ref: this.footerScrollerRef, horizontal: true },
|
|
1272
|
+
preact_cjs.createElement("div", { style: { width: canvasWidth } })))));
|
|
1273
|
+
}));
|
|
1274
|
+
}
|
|
1275
|
+
// Lifecycle
|
|
1276
|
+
// -----------------------------------------------------------------------------------------------
|
|
1277
|
+
componentDidMount() {
|
|
1278
|
+
this.syncedScroller = new internal_cjs$1.ScrollerSyncer(true); // horizontal=true
|
|
1279
|
+
this.updateSyncedScroller();
|
|
1280
|
+
this.resetScroll();
|
|
1281
|
+
this.context.emitter.on('_timeScrollRequest', this.handleTimeScroll);
|
|
1282
|
+
this.syncedScroller.addScrollEndListener(this.clearScroll);
|
|
1283
|
+
}
|
|
1284
|
+
componentDidUpdate(prevProps) {
|
|
1285
|
+
this.updateSyncedScroller();
|
|
1286
|
+
if (prevProps.dateProfile !== this.props.dateProfile && this.context.options.scrollTimeReset) {
|
|
1287
|
+
this.resetScroll();
|
|
1288
|
+
}
|
|
1289
|
+
else {
|
|
1290
|
+
// TODO: inefficient to update so often
|
|
1291
|
+
this.updateScroll();
|
|
1292
|
+
}
|
|
1293
|
+
}
|
|
1294
|
+
componentWillUnmount() {
|
|
1295
|
+
this.syncedScroller.destroy();
|
|
1296
|
+
this.context.emitter.off('_timeScrollRequest', this.handleTimeScroll);
|
|
1297
|
+
this.syncedScroller.removeScrollEndListener(this.clearScroll);
|
|
1298
|
+
}
|
|
1299
|
+
// Scrolling
|
|
1300
|
+
// -----------------------------------------------------------------------------------------------
|
|
1301
|
+
updateSyncedScroller() {
|
|
1302
|
+
this.syncedScroller.handleChildren([
|
|
1303
|
+
this.headerScrollerRef.current,
|
|
1304
|
+
this.bodyScrollerRef.current,
|
|
1305
|
+
this.footerScrollerRef.current
|
|
1306
|
+
]);
|
|
1307
|
+
}
|
|
1308
|
+
resetScroll() {
|
|
1309
|
+
this.handleTimeScroll(this.context.options.scrollTime);
|
|
1310
|
+
}
|
|
1141
1311
|
queryHit(positionLeft, positionTop, elWidth, elHeight) {
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
if (
|
|
1312
|
+
const { props, context, tDateProfile, slotWidth } = this;
|
|
1313
|
+
const { dateEnv } = context;
|
|
1314
|
+
if (slotWidth) {
|
|
1315
|
+
const x = context.isRtl ? elWidth - positionLeft : positionLeft;
|
|
1316
|
+
const slatIndex = Math.floor(x / slotWidth);
|
|
1317
|
+
const slatX = slatIndex * slotWidth;
|
|
1318
|
+
const partial = (x - slatX) / slotWidth; // floating point number between 0 and 1
|
|
1319
|
+
const localSnapIndex = Math.floor(partial * tDateProfile.snapsPerSlot); // the snap # relative to start of slat
|
|
1320
|
+
let startDate = dateEnv.add(tDateProfile.slotDates[slatIndex], internal_cjs.multiplyDuration(tDateProfile.snapDuration, localSnapIndex));
|
|
1321
|
+
let endDate = dateEnv.add(startDate, tDateProfile.snapDuration);
|
|
1322
|
+
// TODO: generalize this coord stuff to TimeGrid?
|
|
1323
|
+
let snapWidth = slotWidth / tDateProfile.snapsPerSlot;
|
|
1324
|
+
let startCoord = slatIndex * slotWidth + (snapWidth * localSnapIndex);
|
|
1325
|
+
let endCoord = startCoord + snapWidth;
|
|
1326
|
+
let left, right;
|
|
1327
|
+
if (context.isRtl) {
|
|
1328
|
+
left = elWidth - endCoord;
|
|
1329
|
+
right = elWidth - startCoord;
|
|
1330
|
+
}
|
|
1331
|
+
else {
|
|
1332
|
+
left = startCoord;
|
|
1333
|
+
right = endCoord;
|
|
1334
|
+
}
|
|
1145
1335
|
return {
|
|
1146
|
-
dateProfile:
|
|
1147
|
-
dateSpan:
|
|
1336
|
+
dateProfile: props.dateProfile,
|
|
1337
|
+
dateSpan: {
|
|
1338
|
+
range: { start: startDate, end: endDate },
|
|
1339
|
+
allDay: !tDateProfile.isTimeScale,
|
|
1340
|
+
},
|
|
1148
1341
|
rect: {
|
|
1149
|
-
left
|
|
1150
|
-
right
|
|
1342
|
+
left,
|
|
1343
|
+
right,
|
|
1151
1344
|
top: 0,
|
|
1152
1345
|
bottom: elHeight,
|
|
1153
1346
|
},
|
|
1154
|
-
|
|
1347
|
+
// HACK. TODO: This is expensive to do every hit-query
|
|
1348
|
+
dayEl: this.bodyEl.querySelectorAll('.fc-timeline-slot')[slatIndex],
|
|
1155
1349
|
layer: 0,
|
|
1156
1350
|
};
|
|
1157
1351
|
}
|
|
@@ -1159,100 +1353,21 @@ class TimelineGrid extends internal_cjs.DateComponent {
|
|
|
1159
1353
|
}
|
|
1160
1354
|
}
|
|
1161
1355
|
|
|
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;pointer-events:none;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}";
|
|
1356
|
+
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}";
|
|
1245
1357
|
internal_cjs.injectStyles(css_248z);
|
|
1246
1358
|
|
|
1247
|
-
exports.
|
|
1248
|
-
exports.TimelineHeader = TimelineHeader;
|
|
1249
|
-
exports.TimelineHeaderRows = TimelineHeaderRows;
|
|
1359
|
+
exports.TimelineHeaderRow = TimelineHeaderRow;
|
|
1250
1360
|
exports.TimelineLane = TimelineLane;
|
|
1251
1361
|
exports.TimelineLaneBg = TimelineLaneBg;
|
|
1252
1362
|
exports.TimelineLaneSlicer = TimelineLaneSlicer;
|
|
1363
|
+
exports.TimelineNowIndicatorArrow = TimelineNowIndicatorArrow;
|
|
1364
|
+
exports.TimelineNowIndicatorLine = TimelineNowIndicatorLine;
|
|
1253
1365
|
exports.TimelineSlats = TimelineSlats;
|
|
1254
1366
|
exports.TimelineView = TimelineView;
|
|
1255
|
-
exports.buildSlatCols = buildSlatCols;
|
|
1256
1367
|
exports.buildTimelineDateProfile = buildTimelineDateProfile;
|
|
1368
|
+
exports.computeSlotWidth = computeSlotWidth;
|
|
1257
1369
|
exports.coordToCss = coordToCss;
|
|
1258
1370
|
exports.coordsToCss = coordsToCss;
|
|
1371
|
+
exports.createHorizontalStyle = createHorizontalStyle;
|
|
1372
|
+
exports.createVerticalStyle = createVerticalStyle;
|
|
1373
|
+
exports.timeToCoord = timeToCoord;
|