gantt-lib 0.111.0 → 0.113.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/dist/core/scheduling/index.d.mts +1 -1
- package/dist/core/scheduling/index.d.ts +1 -1
- package/dist/{index-CQSAjkhV.d.mts → index-D1s_8MxS.d.mts} +5 -1
- package/dist/{index-CQSAjkhV.d.ts → index-D1s_8MxS.d.ts} +5 -1
- package/dist/index.css.map +1 -1
- package/dist/index.d.mts +43 -4
- package/dist/index.d.ts +43 -4
- package/dist/index.js +1270 -136
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1266 -133
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +282 -0
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"use client";
|
|
4
4
|
|
|
5
5
|
// src/components/GanttChart/GanttChart.tsx
|
|
6
|
-
import { useMemo as
|
|
6
|
+
import { useMemo as useMemo13, useCallback as useCallback10, useRef as useRef11, useState as useState11, useEffect as useEffect10, useImperativeHandle, forwardRef } from "react";
|
|
7
7
|
|
|
8
8
|
// src/core/scheduling/dateMath.ts
|
|
9
9
|
var DAY_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -557,10 +557,10 @@ function buildTaskRangeFromStart(startDate, duration, businessDays = false, week
|
|
|
557
557
|
end: parseDateOnly(addBusinessDays(normalizedStart, duration, weekendPredicate))
|
|
558
558
|
};
|
|
559
559
|
}
|
|
560
|
-
const
|
|
560
|
+
const DAY_MS6 = 24 * 60 * 60 * 1e3;
|
|
561
561
|
return {
|
|
562
562
|
start: normalizedStart,
|
|
563
|
-
end: new Date(normalizedStart.getTime() + (Math.max(1, duration) - 1) *
|
|
563
|
+
end: new Date(normalizedStart.getTime() + (Math.max(1, duration) - 1) * DAY_MS6)
|
|
564
564
|
};
|
|
565
565
|
}
|
|
566
566
|
function buildTaskRangeFromEnd(endDate, duration, businessDays = false, weekendPredicate, snapDirection = -1) {
|
|
@@ -571,9 +571,9 @@ function buildTaskRangeFromEnd(endDate, duration, businessDays = false, weekendP
|
|
|
571
571
|
end: normalizedEnd
|
|
572
572
|
};
|
|
573
573
|
}
|
|
574
|
-
const
|
|
574
|
+
const DAY_MS6 = 24 * 60 * 60 * 1e3;
|
|
575
575
|
return {
|
|
576
|
-
start: new Date(normalizedEnd.getTime() - (Math.max(1, duration) - 1) *
|
|
576
|
+
start: new Date(normalizedEnd.getTime() - (Math.max(1, duration) - 1) * DAY_MS6),
|
|
577
577
|
end: normalizedEnd
|
|
578
578
|
};
|
|
579
579
|
}
|
|
@@ -988,13 +988,13 @@ function computeParentProgress(parentId, tasks) {
|
|
|
988
988
|
if (children.length === 0) {
|
|
989
989
|
return 0;
|
|
990
990
|
}
|
|
991
|
-
const
|
|
991
|
+
const DAY_MS6 = 24 * 60 * 60 * 1e3;
|
|
992
992
|
let totalWeight = 0;
|
|
993
993
|
let weightedSum = 0;
|
|
994
994
|
for (const child of children) {
|
|
995
995
|
const start = new Date(child.startDate).getTime();
|
|
996
996
|
const end = new Date(child.endDate).getTime();
|
|
997
|
-
const duration = (end - start +
|
|
997
|
+
const duration = (end - start + DAY_MS6) / DAY_MS6;
|
|
998
998
|
const progress = child.progress ?? 0;
|
|
999
999
|
totalWeight += duration;
|
|
1000
1000
|
weightedSum += duration * progress;
|
|
@@ -10447,6 +10447,1001 @@ function TableMatrix({
|
|
|
10447
10447
|
] });
|
|
10448
10448
|
}
|
|
10449
10449
|
|
|
10450
|
+
// src/components/PlanFactMatrix/PlanFactMatrix.tsx
|
|
10451
|
+
import React15, { useCallback as useCallback9, useEffect as useEffect9, useMemo as useMemo12, useRef as useRef10, useState as useState10 } from "react";
|
|
10452
|
+
import { jsx as jsx18, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
10453
|
+
var DAY_MS5 = 24 * 60 * 60 * 1e3;
|
|
10454
|
+
function joinClasses2(...values) {
|
|
10455
|
+
return values.filter(Boolean).join(" ");
|
|
10456
|
+
}
|
|
10457
|
+
function formatDateKey(date) {
|
|
10458
|
+
const year = date.getUTCFullYear();
|
|
10459
|
+
const month = String(date.getUTCMonth() + 1).padStart(2, "0");
|
|
10460
|
+
const day = String(date.getUTCDate()).padStart(2, "0");
|
|
10461
|
+
return `${year}-${month}-${day}`;
|
|
10462
|
+
}
|
|
10463
|
+
function escapeAttributeValue(value) {
|
|
10464
|
+
return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
10465
|
+
}
|
|
10466
|
+
function parseNumberInput(value) {
|
|
10467
|
+
const trimmed = value.trim();
|
|
10468
|
+
if (trimmed === "") return void 0;
|
|
10469
|
+
const normalized = trimmed.replace(/\s+/g, "").replace(",", ".");
|
|
10470
|
+
const parsed = Number(normalized);
|
|
10471
|
+
if (!Number.isFinite(parsed) || parsed < 0) {
|
|
10472
|
+
return null;
|
|
10473
|
+
}
|
|
10474
|
+
return parsed;
|
|
10475
|
+
}
|
|
10476
|
+
function getDateOnlyMs(date) {
|
|
10477
|
+
return Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate());
|
|
10478
|
+
}
|
|
10479
|
+
function getPlannedIndexRange(task, rangeStartMs, rangeLength) {
|
|
10480
|
+
if (rangeLength <= 0) return null;
|
|
10481
|
+
const start = parseUTCDate(task.startDate);
|
|
10482
|
+
const end = parseUTCDate(task.endDate);
|
|
10483
|
+
const startIndex = Math.ceil((getDateOnlyMs(start) - rangeStartMs) / DAY_MS5);
|
|
10484
|
+
const endIndex = Math.floor((getDateOnlyMs(end) - rangeStartMs) / DAY_MS5);
|
|
10485
|
+
const clampedStartIndex = Math.max(0, startIndex);
|
|
10486
|
+
const clampedEndIndex = Math.min(rangeLength - 1, endIndex);
|
|
10487
|
+
if (clampedStartIndex > clampedEndIndex) return null;
|
|
10488
|
+
return {
|
|
10489
|
+
startIndex: clampedStartIndex,
|
|
10490
|
+
endIndex: clampedEndIndex
|
|
10491
|
+
};
|
|
10492
|
+
}
|
|
10493
|
+
function isDateIndexWithinPlannedRange(dateIndex, range) {
|
|
10494
|
+
return !!range && range.startIndex <= dateIndex && dateIndex <= range.endIndex;
|
|
10495
|
+
}
|
|
10496
|
+
function formatValue(value) {
|
|
10497
|
+
if (value === void 0) return "";
|
|
10498
|
+
const absoluteValue = Math.abs(value);
|
|
10499
|
+
if (absoluteValue >= 1e6) {
|
|
10500
|
+
const compactValue = value / 1e6;
|
|
10501
|
+
const fractionDigits = absoluteValue >= 1e7 ? 0 : 1;
|
|
10502
|
+
return `${compactValue.toLocaleString("ru-RU", {
|
|
10503
|
+
minimumFractionDigits: 0,
|
|
10504
|
+
maximumFractionDigits: fractionDigits,
|
|
10505
|
+
useGrouping: false
|
|
10506
|
+
})}m`;
|
|
10507
|
+
}
|
|
10508
|
+
if (absoluteValue >= 1e4) {
|
|
10509
|
+
const compactValue = value / 1e3;
|
|
10510
|
+
const fractionDigits = absoluteValue >= 1e5 ? 0 : 1;
|
|
10511
|
+
return `${compactValue.toLocaleString("ru-RU", {
|
|
10512
|
+
minimumFractionDigits: 0,
|
|
10513
|
+
maximumFractionDigits: fractionDigits,
|
|
10514
|
+
useGrouping: false
|
|
10515
|
+
})}k`;
|
|
10516
|
+
}
|
|
10517
|
+
return Number.isInteger(value) ? String(value) : String(value).replace(".", ",");
|
|
10518
|
+
}
|
|
10519
|
+
function formatTooltipValue(value) {
|
|
10520
|
+
if (value === void 0) return "";
|
|
10521
|
+
return value.toLocaleString("ru-RU", { maximumFractionDigits: 20 });
|
|
10522
|
+
}
|
|
10523
|
+
function getSubrowIndex(taskIndex, kind) {
|
|
10524
|
+
return taskIndex * 2 + (kind === "plan" ? 0 : 1);
|
|
10525
|
+
}
|
|
10526
|
+
function findEditableTaskIndex(tasks, parentTaskIds, startIndex, step) {
|
|
10527
|
+
let index = startIndex;
|
|
10528
|
+
while (index >= 0 && index < tasks.length) {
|
|
10529
|
+
if (!parentTaskIds.has(tasks[index].id)) {
|
|
10530
|
+
return index;
|
|
10531
|
+
}
|
|
10532
|
+
index += step;
|
|
10533
|
+
}
|
|
10534
|
+
return null;
|
|
10535
|
+
}
|
|
10536
|
+
function PlanFactCellEditor({
|
|
10537
|
+
value,
|
|
10538
|
+
startValue,
|
|
10539
|
+
onCommit,
|
|
10540
|
+
onCommitRange,
|
|
10541
|
+
onCancel
|
|
10542
|
+
}) {
|
|
10543
|
+
const [draft, setDraft] = useState10(startValue ?? (value === void 0 ? "" : String(value)));
|
|
10544
|
+
const inputRef = useRef10(null);
|
|
10545
|
+
useEffect9(() => {
|
|
10546
|
+
inputRef.current?.focus();
|
|
10547
|
+
if (startValue === void 0) {
|
|
10548
|
+
inputRef.current?.select();
|
|
10549
|
+
} else {
|
|
10550
|
+
inputRef.current?.setSelectionRange(startValue.length, startValue.length);
|
|
10551
|
+
}
|
|
10552
|
+
}, [startValue]);
|
|
10553
|
+
const commit = useCallback9(() => {
|
|
10554
|
+
const parsed = parseNumberInput(draft);
|
|
10555
|
+
if (parsed === null) {
|
|
10556
|
+
onCancel();
|
|
10557
|
+
return;
|
|
10558
|
+
}
|
|
10559
|
+
onCommit(parsed);
|
|
10560
|
+
}, [draft, onCancel, onCommit]);
|
|
10561
|
+
return /* @__PURE__ */ jsx18(
|
|
10562
|
+
"input",
|
|
10563
|
+
{
|
|
10564
|
+
ref: inputRef,
|
|
10565
|
+
value: draft,
|
|
10566
|
+
className: "gantt-pf-editor",
|
|
10567
|
+
inputMode: "decimal",
|
|
10568
|
+
onChange: (event) => setDraft(event.target.value),
|
|
10569
|
+
onBlur: commit,
|
|
10570
|
+
onKeyDown: (event) => {
|
|
10571
|
+
if (event.key === "Escape") {
|
|
10572
|
+
event.preventDefault();
|
|
10573
|
+
onCancel();
|
|
10574
|
+
return;
|
|
10575
|
+
}
|
|
10576
|
+
if (event.key === "Enter") {
|
|
10577
|
+
event.preventDefault();
|
|
10578
|
+
if (event.ctrlKey || event.metaKey) {
|
|
10579
|
+
const parsed = parseNumberInput(draft);
|
|
10580
|
+
if (parsed === null) {
|
|
10581
|
+
onCancel();
|
|
10582
|
+
return;
|
|
10583
|
+
}
|
|
10584
|
+
onCommitRange?.(parsed);
|
|
10585
|
+
} else {
|
|
10586
|
+
commit();
|
|
10587
|
+
}
|
|
10588
|
+
}
|
|
10589
|
+
}
|
|
10590
|
+
}
|
|
10591
|
+
);
|
|
10592
|
+
}
|
|
10593
|
+
function getCellSignatureForTask(cell, taskId) {
|
|
10594
|
+
return cell?.taskId === taskId ? `${cell.dateIndex}:${cell.kind}` : "";
|
|
10595
|
+
}
|
|
10596
|
+
function getEditingCellSignatureForTask(cell, taskId) {
|
|
10597
|
+
return cell?.taskId === taskId ? `${cell.dateIndex}:${cell.kind}:${cell.startValue ?? ""}` : "";
|
|
10598
|
+
}
|
|
10599
|
+
function getRangeAnchorSignatureForTask(range, taskId) {
|
|
10600
|
+
return range?.anchor.taskId === taskId ? `${range.anchor.dateIndex}:${range.anchor.kind}` : "";
|
|
10601
|
+
}
|
|
10602
|
+
function doesRangeTouchRow(bounds, rowIndex) {
|
|
10603
|
+
if (!bounds) return false;
|
|
10604
|
+
const firstSubrowIndex = rowIndex * 2;
|
|
10605
|
+
const lastSubrowIndex = firstSubrowIndex + 1;
|
|
10606
|
+
return bounds.fromSubrowIndex <= lastSubrowIndex && bounds.toSubrowIndex >= firstSubrowIndex;
|
|
10607
|
+
}
|
|
10608
|
+
function areRangeBoundsEqual(left, right) {
|
|
10609
|
+
if (left === right) return true;
|
|
10610
|
+
if (!left || !right) return false;
|
|
10611
|
+
return left.fromDateIndex === right.fromDateIndex && left.toDateIndex === right.toDateIndex && left.fromSubrowIndex === right.fromSubrowIndex && left.toSubrowIndex === right.toSubrowIndex;
|
|
10612
|
+
}
|
|
10613
|
+
function PlanFactRowInner({
|
|
10614
|
+
task,
|
|
10615
|
+
rowIndex,
|
|
10616
|
+
dateRange,
|
|
10617
|
+
dateKeys,
|
|
10618
|
+
renderedDateIndices,
|
|
10619
|
+
rowHeight,
|
|
10620
|
+
subrowHeight,
|
|
10621
|
+
dayWidth,
|
|
10622
|
+
plannedRange,
|
|
10623
|
+
todayDateIndex,
|
|
10624
|
+
isParent,
|
|
10625
|
+
isHighlighted,
|
|
10626
|
+
selectedTaskId,
|
|
10627
|
+
activeCell,
|
|
10628
|
+
editingCell,
|
|
10629
|
+
selectedRange,
|
|
10630
|
+
renderedRangeBounds,
|
|
10631
|
+
didDragSelectRef,
|
|
10632
|
+
isSelectingRef,
|
|
10633
|
+
isFillDraggingRef,
|
|
10634
|
+
onTaskSelect,
|
|
10635
|
+
selectSingleCell,
|
|
10636
|
+
queueHoverCellUpdate,
|
|
10637
|
+
setActiveCell,
|
|
10638
|
+
setEditingCell,
|
|
10639
|
+
setFillRange,
|
|
10640
|
+
clearSelectedCells,
|
|
10641
|
+
commitCell,
|
|
10642
|
+
commitSelectedCells,
|
|
10643
|
+
moveActiveCell,
|
|
10644
|
+
extendSelectedRange,
|
|
10645
|
+
focusCell,
|
|
10646
|
+
showOverflowTooltip,
|
|
10647
|
+
hideOverflowTooltip
|
|
10648
|
+
}) {
|
|
10649
|
+
return /* @__PURE__ */ jsx18(
|
|
10650
|
+
"div",
|
|
10651
|
+
{
|
|
10652
|
+
"data-gantt-task-row-id": task.id,
|
|
10653
|
+
className: joinClasses2(
|
|
10654
|
+
"gantt-pf-row",
|
|
10655
|
+
isParent && "gantt-pf-row-parent",
|
|
10656
|
+
selectedTaskId === task.id && "gantt-pf-row-selected",
|
|
10657
|
+
isHighlighted && "gantt-pf-row-highlighted"
|
|
10658
|
+
),
|
|
10659
|
+
style: {
|
|
10660
|
+
top: `${rowIndex * rowHeight}px`,
|
|
10661
|
+
height: `${rowHeight}px`,
|
|
10662
|
+
gridTemplateColumns: `repeat(${dateRange.length}, ${dayWidth}px)`,
|
|
10663
|
+
["--gantt-pf-today-left"]: todayDateIndex !== void 0 && todayDateIndex >= 0 ? `${todayDateIndex * dayWidth}px` : void 0
|
|
10664
|
+
},
|
|
10665
|
+
onClick: () => onTaskSelect?.(task.id),
|
|
10666
|
+
children: renderedDateIndices.map((dateIndex) => {
|
|
10667
|
+
const dateKey = dateKeys[dateIndex];
|
|
10668
|
+
if (dateKey === void 0) return null;
|
|
10669
|
+
const planned = isDateIndexWithinPlannedRange(dateIndex, plannedRange);
|
|
10670
|
+
return ["plan", "fact"].map((kind) => {
|
|
10671
|
+
const subrowIndex = getSubrowIndex(rowIndex, kind);
|
|
10672
|
+
const isInRenderedRange = !!renderedRangeBounds && dateIndex >= renderedRangeBounds.fromDateIndex && dateIndex <= renderedRangeBounds.toDateIndex && subrowIndex >= renderedRangeBounds.fromSubrowIndex && subrowIndex <= renderedRangeBounds.toSubrowIndex;
|
|
10673
|
+
const planValue = task.planByDate?.[dateKey];
|
|
10674
|
+
const factValue = task.factByDate?.[dateKey];
|
|
10675
|
+
const value = kind === "plan" ? planValue : factValue;
|
|
10676
|
+
const factStatus = factValue === void 0 || planValue === void 0 ? null : factValue >= planValue ? "success" : "warning";
|
|
10677
|
+
const isActive = activeCell?.taskId === task.id && activeCell.dateIndex === dateIndex && activeCell.kind === kind;
|
|
10678
|
+
const isEditing = editingCell?.taskId === task.id && editingCell.dateIndex === dateIndex && editingCell.kind === kind;
|
|
10679
|
+
const currentCell = { taskId: task.id, dateIndex, kind };
|
|
10680
|
+
const isSelected = !isParent && isInRenderedRange;
|
|
10681
|
+
const showFillHandle = !isParent && !isEditing && isInRenderedRange && renderedRangeBounds !== null && dateIndex === renderedRangeBounds.toDateIndex && subrowIndex === renderedRangeBounds.toSubrowIndex;
|
|
10682
|
+
const isRangeAnchor = !showFillHandle && !isParent && selectedRange?.anchor.taskId === task.id && selectedRange.anchor.dateIndex === dateIndex && selectedRange.anchor.kind === kind;
|
|
10683
|
+
return /* @__PURE__ */ jsxs14(
|
|
10684
|
+
"div",
|
|
10685
|
+
{
|
|
10686
|
+
"data-plan-fact-task-id": task.id,
|
|
10687
|
+
"data-plan-fact-date-index": dateIndex,
|
|
10688
|
+
"data-plan-fact-kind": kind,
|
|
10689
|
+
className: joinClasses2(
|
|
10690
|
+
"gantt-pf-cell",
|
|
10691
|
+
`gantt-pf-cell-${kind}`,
|
|
10692
|
+
planned && kind === "plan" && "gantt-pf-cell-planned",
|
|
10693
|
+
value !== void 0 && "gantt-pf-cell-hasValue",
|
|
10694
|
+
kind === "fact" && factStatus === "success" && "gantt-pf-cell-factSuccess",
|
|
10695
|
+
kind === "fact" && factStatus === "warning" && "gantt-pf-cell-factWarning",
|
|
10696
|
+
isSelected && "gantt-pf-cell-selected",
|
|
10697
|
+
isInRenderedRange && renderedRangeBounds !== null && dateIndex === renderedRangeBounds.fromDateIndex && "gantt-pf-cell-rangeLeft",
|
|
10698
|
+
isInRenderedRange && renderedRangeBounds !== null && dateIndex === renderedRangeBounds.toDateIndex && "gantt-pf-cell-rangeRight",
|
|
10699
|
+
isInRenderedRange && renderedRangeBounds !== null && subrowIndex === renderedRangeBounds.fromSubrowIndex && "gantt-pf-cell-rangeTop",
|
|
10700
|
+
isInRenderedRange && renderedRangeBounds !== null && subrowIndex === renderedRangeBounds.toSubrowIndex && "gantt-pf-cell-rangeBottom",
|
|
10701
|
+
isRangeAnchor && "gantt-pf-cell-rangeAnchor",
|
|
10702
|
+
isActive && "gantt-pf-cell-active",
|
|
10703
|
+
isEditing && "gantt-pf-cell-editing",
|
|
10704
|
+
isParent && "gantt-pf-cell-readonly"
|
|
10705
|
+
),
|
|
10706
|
+
style: {
|
|
10707
|
+
gridColumn: dateIndex + 1,
|
|
10708
|
+
gridRow: kind === "plan" ? 1 : 2,
|
|
10709
|
+
height: `${subrowHeight}px`
|
|
10710
|
+
},
|
|
10711
|
+
tabIndex: isParent ? -1 : 0,
|
|
10712
|
+
onMouseDown: (event) => {
|
|
10713
|
+
if (isParent) return;
|
|
10714
|
+
event.preventDefault();
|
|
10715
|
+
event.stopPropagation();
|
|
10716
|
+
didDragSelectRef.current = false;
|
|
10717
|
+
isSelectingRef.current = true;
|
|
10718
|
+
selectSingleCell(currentCell);
|
|
10719
|
+
onTaskSelect?.(task.id);
|
|
10720
|
+
event.currentTarget.focus();
|
|
10721
|
+
},
|
|
10722
|
+
onMouseEnter: () => {
|
|
10723
|
+
if (isParent) return;
|
|
10724
|
+
if (!isFillDraggingRef.current && !isSelectingRef.current) return;
|
|
10725
|
+
queueHoverCellUpdate(currentCell);
|
|
10726
|
+
},
|
|
10727
|
+
onFocus: () => {
|
|
10728
|
+
if (isParent) return;
|
|
10729
|
+
setActiveCell({ taskId: task.id, dateIndex, kind });
|
|
10730
|
+
},
|
|
10731
|
+
onClick: (event) => {
|
|
10732
|
+
event.stopPropagation();
|
|
10733
|
+
if (didDragSelectRef.current) {
|
|
10734
|
+
didDragSelectRef.current = false;
|
|
10735
|
+
return;
|
|
10736
|
+
}
|
|
10737
|
+
onTaskSelect?.(task.id);
|
|
10738
|
+
if (isParent) return;
|
|
10739
|
+
selectSingleCell(currentCell);
|
|
10740
|
+
event.currentTarget.focus();
|
|
10741
|
+
},
|
|
10742
|
+
onDoubleClick: (event) => {
|
|
10743
|
+
event.stopPropagation();
|
|
10744
|
+
if (isParent) return;
|
|
10745
|
+
setEditingCell({ taskId: task.id, dateIndex, kind });
|
|
10746
|
+
},
|
|
10747
|
+
onKeyDown: (event) => {
|
|
10748
|
+
if (isParent || isEditing) return;
|
|
10749
|
+
if (event.key === "ArrowLeft" || event.key === "ArrowRight" || event.key === "ArrowUp" || event.key === "ArrowDown") {
|
|
10750
|
+
event.preventDefault();
|
|
10751
|
+
event.stopPropagation();
|
|
10752
|
+
const direction = event.key.replace("Arrow", "").toLowerCase();
|
|
10753
|
+
if (event.shiftKey) {
|
|
10754
|
+
extendSelectedRange(selectedRange?.focus ?? currentCell, direction);
|
|
10755
|
+
} else {
|
|
10756
|
+
moveActiveCell(currentCell, direction);
|
|
10757
|
+
}
|
|
10758
|
+
return;
|
|
10759
|
+
}
|
|
10760
|
+
if (event.key === "Enter" || event.key === "F2") {
|
|
10761
|
+
event.preventDefault();
|
|
10762
|
+
event.stopPropagation();
|
|
10763
|
+
setEditingCell(selectedRange?.anchor ?? currentCell);
|
|
10764
|
+
return;
|
|
10765
|
+
}
|
|
10766
|
+
if (event.key === "Backspace" || event.key === "Delete") {
|
|
10767
|
+
event.preventDefault();
|
|
10768
|
+
event.stopPropagation();
|
|
10769
|
+
clearSelectedCells();
|
|
10770
|
+
return;
|
|
10771
|
+
}
|
|
10772
|
+
if (event.key.length === 1 && !event.ctrlKey && !event.metaKey && !event.altKey) {
|
|
10773
|
+
event.preventDefault();
|
|
10774
|
+
event.stopPropagation();
|
|
10775
|
+
setEditingCell({ ...currentCell, startValue: event.key });
|
|
10776
|
+
}
|
|
10777
|
+
},
|
|
10778
|
+
children: [
|
|
10779
|
+
isEditing ? /* @__PURE__ */ jsx18(
|
|
10780
|
+
PlanFactCellEditor,
|
|
10781
|
+
{
|
|
10782
|
+
value,
|
|
10783
|
+
startValue: editingCell.startValue,
|
|
10784
|
+
onCommit: (nextValue) => {
|
|
10785
|
+
commitCell(task, dateIndex, kind, nextValue);
|
|
10786
|
+
setEditingCell(null);
|
|
10787
|
+
const nextActiveCell = { taskId: task.id, dateIndex, kind };
|
|
10788
|
+
selectSingleCell(nextActiveCell);
|
|
10789
|
+
focusCell(nextActiveCell);
|
|
10790
|
+
},
|
|
10791
|
+
onCommitRange: (nextValue) => {
|
|
10792
|
+
commitSelectedCells(nextValue);
|
|
10793
|
+
setEditingCell(null);
|
|
10794
|
+
const nextActiveCell = { taskId: task.id, dateIndex, kind };
|
|
10795
|
+
selectSingleCell(nextActiveCell);
|
|
10796
|
+
focusCell(nextActiveCell);
|
|
10797
|
+
},
|
|
10798
|
+
onCancel: () => {
|
|
10799
|
+
setEditingCell(null);
|
|
10800
|
+
const nextActiveCell = { taskId: task.id, dateIndex, kind };
|
|
10801
|
+
selectSingleCell(nextActiveCell);
|
|
10802
|
+
focusCell(nextActiveCell);
|
|
10803
|
+
}
|
|
10804
|
+
}
|
|
10805
|
+
) : /* @__PURE__ */ jsx18(
|
|
10806
|
+
"span",
|
|
10807
|
+
{
|
|
10808
|
+
className: "gantt-pf-cellValue",
|
|
10809
|
+
onMouseEnter: (event) => {
|
|
10810
|
+
if (isParent || value === void 0) return;
|
|
10811
|
+
const compactValue = formatValue(value);
|
|
10812
|
+
const fullValue = formatTooltipValue(value);
|
|
10813
|
+
showOverflowTooltip(event.currentTarget, fullValue, compactValue !== fullValue);
|
|
10814
|
+
},
|
|
10815
|
+
onMouseLeave: hideOverflowTooltip,
|
|
10816
|
+
children: isParent ? "" : formatValue(value)
|
|
10817
|
+
}
|
|
10818
|
+
),
|
|
10819
|
+
showFillHandle && /* @__PURE__ */ jsx18(
|
|
10820
|
+
"span",
|
|
10821
|
+
{
|
|
10822
|
+
className: "gantt-pf-fillHandle",
|
|
10823
|
+
"aria-hidden": "true",
|
|
10824
|
+
onMouseDown: (event) => {
|
|
10825
|
+
event.preventDefault();
|
|
10826
|
+
event.stopPropagation();
|
|
10827
|
+
isSelectingRef.current = false;
|
|
10828
|
+
isFillDraggingRef.current = true;
|
|
10829
|
+
setFillRange(selectedRange);
|
|
10830
|
+
}
|
|
10831
|
+
}
|
|
10832
|
+
)
|
|
10833
|
+
]
|
|
10834
|
+
},
|
|
10835
|
+
`${task.id}:${dateKey}:${kind}`
|
|
10836
|
+
);
|
|
10837
|
+
});
|
|
10838
|
+
})
|
|
10839
|
+
}
|
|
10840
|
+
);
|
|
10841
|
+
}
|
|
10842
|
+
function arePlanFactRowsEqual(previous, next) {
|
|
10843
|
+
const previousRangeTouchesRow = doesRangeTouchRow(previous.renderedRangeBounds, previous.rowIndex);
|
|
10844
|
+
const nextRangeTouchesRow = doesRangeTouchRow(next.renderedRangeBounds, next.rowIndex);
|
|
10845
|
+
return previous.task === next.task && previous.rowIndex === next.rowIndex && previous.dateRange === next.dateRange && previous.dateKeys === next.dateKeys && previous.renderedDateIndices === next.renderedDateIndices && previous.rowHeight === next.rowHeight && previous.subrowHeight === next.subrowHeight && previous.dayWidth === next.dayWidth && previous.plannedRange === next.plannedRange && previous.todayDateIndex === next.todayDateIndex && previous.isParent === next.isParent && previous.isHighlighted === next.isHighlighted && previous.selectedTaskId === previous.task.id === (next.selectedTaskId === next.task.id) && getCellSignatureForTask(previous.activeCell, previous.task.id) === getCellSignatureForTask(next.activeCell, next.task.id) && getEditingCellSignatureForTask(previous.editingCell, previous.task.id) === getEditingCellSignatureForTask(next.editingCell, next.task.id) && getRangeAnchorSignatureForTask(previous.selectedRange, previous.task.id) === getRangeAnchorSignatureForTask(next.selectedRange, next.task.id) && previousRangeTouchesRow === nextRangeTouchesRow && (!nextRangeTouchesRow || areRangeBoundsEqual(previous.renderedRangeBounds, next.renderedRangeBounds));
|
|
10846
|
+
}
|
|
10847
|
+
var PlanFactRow = React15.memo(PlanFactRowInner, arePlanFactRowsEqual);
|
|
10848
|
+
function PlanFactMatrix({
|
|
10849
|
+
tasks,
|
|
10850
|
+
allTasks = tasks,
|
|
10851
|
+
dateRange,
|
|
10852
|
+
dayWidth,
|
|
10853
|
+
rowHeight,
|
|
10854
|
+
headerHeight,
|
|
10855
|
+
bodyMinHeight,
|
|
10856
|
+
selectedTaskId,
|
|
10857
|
+
onTaskSelect,
|
|
10858
|
+
onTasksChange,
|
|
10859
|
+
onCellCommit,
|
|
10860
|
+
highlightedTaskIds,
|
|
10861
|
+
filterMode = "highlight",
|
|
10862
|
+
visibleRowIndices,
|
|
10863
|
+
visibleDateIndices,
|
|
10864
|
+
todayDateIndex
|
|
10865
|
+
}) {
|
|
10866
|
+
const [activeCell, setActiveCell] = useState10(null);
|
|
10867
|
+
const [editingCell, setEditingCell] = useState10(null);
|
|
10868
|
+
const [selectedRange, setSelectedRange] = useState10(null);
|
|
10869
|
+
const [fillRange, setFillRange] = useState10(null);
|
|
10870
|
+
const [overflowTooltip, setOverflowTooltip] = useState10(null);
|
|
10871
|
+
const isSelectingRef = useRef10(false);
|
|
10872
|
+
const isFillDraggingRef = useRef10(false);
|
|
10873
|
+
const didDragSelectRef = useRef10(false);
|
|
10874
|
+
const pendingHoverCellRef = useRef10(null);
|
|
10875
|
+
const hoverFrameRef = useRef10(null);
|
|
10876
|
+
const rootRef = useRef10(null);
|
|
10877
|
+
const bodyRef = useRef10(null);
|
|
10878
|
+
const totalWidth = dateRange.length * dayWidth;
|
|
10879
|
+
const subrowHeight = rowHeight / 2;
|
|
10880
|
+
const renderedRowIndices = useMemo12(
|
|
10881
|
+
() => visibleRowIndices ?? tasks.map((_, index) => index),
|
|
10882
|
+
[tasks, visibleRowIndices]
|
|
10883
|
+
);
|
|
10884
|
+
const renderedDateIndices = useMemo12(
|
|
10885
|
+
() => visibleDateIndices ?? dateRange.map((_, index) => index),
|
|
10886
|
+
[dateRange, visibleDateIndices]
|
|
10887
|
+
);
|
|
10888
|
+
const parentTaskIds = useMemo12(() => {
|
|
10889
|
+
const ids = /* @__PURE__ */ new Set();
|
|
10890
|
+
for (const task of allTasks) {
|
|
10891
|
+
if (task.parentId) ids.add(task.parentId);
|
|
10892
|
+
}
|
|
10893
|
+
return ids;
|
|
10894
|
+
}, [allTasks]);
|
|
10895
|
+
const dateKeys = useMemo12(() => dateRange.map(formatDateKey), [dateRange]);
|
|
10896
|
+
const dateRangeStartMs = dateRange[0] ? getDateOnlyMs(dateRange[0]) : 0;
|
|
10897
|
+
const taskIndexById = useMemo12(() => {
|
|
10898
|
+
const indexById = /* @__PURE__ */ new Map();
|
|
10899
|
+
tasks.forEach((task, index) => indexById.set(task.id, index));
|
|
10900
|
+
return indexById;
|
|
10901
|
+
}, [tasks]);
|
|
10902
|
+
const taskById = useMemo12(
|
|
10903
|
+
() => new Map(tasks.map((task) => [task.id, task])),
|
|
10904
|
+
[tasks]
|
|
10905
|
+
);
|
|
10906
|
+
const monthSeparatorIndices = useMemo12(() => {
|
|
10907
|
+
const indices = [];
|
|
10908
|
+
for (let index = 1; index < dateRange.length; index += 1) {
|
|
10909
|
+
if (dateRange[index].getUTCDate() === 1) {
|
|
10910
|
+
indices.push(index);
|
|
10911
|
+
}
|
|
10912
|
+
}
|
|
10913
|
+
return indices;
|
|
10914
|
+
}, [dateRange]);
|
|
10915
|
+
const plannedRangeByTaskId = useMemo12(() => {
|
|
10916
|
+
const rangeByTaskId = /* @__PURE__ */ new Map();
|
|
10917
|
+
for (const task of tasks) {
|
|
10918
|
+
rangeByTaskId.set(task.id, getPlannedIndexRange(task, dateRangeStartMs, dateRange.length));
|
|
10919
|
+
}
|
|
10920
|
+
return rangeByTaskId;
|
|
10921
|
+
}, [dateRange.length, dateRangeStartMs, tasks]);
|
|
10922
|
+
const focusCell = useCallback9((cell) => {
|
|
10923
|
+
window.requestAnimationFrame(() => {
|
|
10924
|
+
const selector = [
|
|
10925
|
+
`[data-plan-fact-task-id="${escapeAttributeValue(cell.taskId)}"]`,
|
|
10926
|
+
`[data-plan-fact-date-index="${cell.dateIndex}"]`,
|
|
10927
|
+
`[data-plan-fact-kind="${cell.kind}"]`
|
|
10928
|
+
].join("");
|
|
10929
|
+
bodyRef.current?.querySelector(selector)?.focus();
|
|
10930
|
+
});
|
|
10931
|
+
}, []);
|
|
10932
|
+
const clearSelection = useCallback9(() => {
|
|
10933
|
+
if (hoverFrameRef.current !== null) {
|
|
10934
|
+
window.cancelAnimationFrame(hoverFrameRef.current);
|
|
10935
|
+
hoverFrameRef.current = null;
|
|
10936
|
+
}
|
|
10937
|
+
pendingHoverCellRef.current = null;
|
|
10938
|
+
isSelectingRef.current = false;
|
|
10939
|
+
isFillDraggingRef.current = false;
|
|
10940
|
+
didDragSelectRef.current = false;
|
|
10941
|
+
setActiveCell(null);
|
|
10942
|
+
setEditingCell(null);
|
|
10943
|
+
setSelectedRange(null);
|
|
10944
|
+
setFillRange(null);
|
|
10945
|
+
setOverflowTooltip(null);
|
|
10946
|
+
}, []);
|
|
10947
|
+
const hideOverflowTooltip = useCallback9(() => {
|
|
10948
|
+
setOverflowTooltip(null);
|
|
10949
|
+
}, []);
|
|
10950
|
+
const flushPendingHoverCell = useCallback9(() => {
|
|
10951
|
+
hoverFrameRef.current = null;
|
|
10952
|
+
const currentCell = pendingHoverCellRef.current;
|
|
10953
|
+
if (!currentCell) return;
|
|
10954
|
+
if (isFillDraggingRef.current && selectedRange) {
|
|
10955
|
+
setFillRange({ anchor: selectedRange.anchor, focus: currentCell });
|
|
10956
|
+
setActiveCell(currentCell);
|
|
10957
|
+
onTaskSelect?.(currentCell.taskId);
|
|
10958
|
+
return;
|
|
10959
|
+
}
|
|
10960
|
+
if (!isSelectingRef.current) return;
|
|
10961
|
+
didDragSelectRef.current = true;
|
|
10962
|
+
setSelectedRange((currentRange) => ({
|
|
10963
|
+
anchor: currentRange?.anchor ?? currentCell,
|
|
10964
|
+
focus: currentCell
|
|
10965
|
+
}));
|
|
10966
|
+
onTaskSelect?.(currentCell.taskId);
|
|
10967
|
+
}, [onTaskSelect, selectedRange]);
|
|
10968
|
+
const queueHoverCellUpdate = useCallback9((cell) => {
|
|
10969
|
+
pendingHoverCellRef.current = cell;
|
|
10970
|
+
if (hoverFrameRef.current !== null) return;
|
|
10971
|
+
hoverFrameRef.current = window.requestAnimationFrame(flushPendingHoverCell);
|
|
10972
|
+
}, [flushPendingHoverCell]);
|
|
10973
|
+
const showOverflowTooltip = useCallback9((target, label, force = false) => {
|
|
10974
|
+
if (!rootRef.current || !label) return;
|
|
10975
|
+
if (!force && target.scrollWidth <= target.clientWidth) {
|
|
10976
|
+
setOverflowTooltip(null);
|
|
10977
|
+
return;
|
|
10978
|
+
}
|
|
10979
|
+
const rootRect = rootRef.current.getBoundingClientRect();
|
|
10980
|
+
const targetRect = target.getBoundingClientRect();
|
|
10981
|
+
setOverflowTooltip({
|
|
10982
|
+
label,
|
|
10983
|
+
left: targetRect.left - rootRect.left + targetRect.width / 2,
|
|
10984
|
+
top: targetRect.top - rootRect.top
|
|
10985
|
+
});
|
|
10986
|
+
}, []);
|
|
10987
|
+
const selectSingleCell = useCallback9((cell) => {
|
|
10988
|
+
setActiveCell(cell);
|
|
10989
|
+
setSelectedRange({ anchor: cell, focus: cell });
|
|
10990
|
+
setFillRange(null);
|
|
10991
|
+
}, []);
|
|
10992
|
+
const getRangeBounds = useCallback9((range) => {
|
|
10993
|
+
const anchorTaskIndex = taskIndexById.get(range.anchor.taskId);
|
|
10994
|
+
const focusTaskIndex = taskIndexById.get(range.focus.taskId);
|
|
10995
|
+
if (anchorTaskIndex === void 0 || focusTaskIndex === void 0) {
|
|
10996
|
+
return null;
|
|
10997
|
+
}
|
|
10998
|
+
return {
|
|
10999
|
+
fromDateIndex: Math.min(range.anchor.dateIndex, range.focus.dateIndex),
|
|
11000
|
+
toDateIndex: Math.max(range.anchor.dateIndex, range.focus.dateIndex),
|
|
11001
|
+
fromSubrowIndex: Math.min(
|
|
11002
|
+
getSubrowIndex(anchorTaskIndex, range.anchor.kind),
|
|
11003
|
+
getSubrowIndex(focusTaskIndex, range.focus.kind)
|
|
11004
|
+
),
|
|
11005
|
+
toSubrowIndex: Math.max(
|
|
11006
|
+
getSubrowIndex(anchorTaskIndex, range.anchor.kind),
|
|
11007
|
+
getSubrowIndex(focusTaskIndex, range.focus.kind)
|
|
11008
|
+
)
|
|
11009
|
+
};
|
|
11010
|
+
}, [taskIndexById]);
|
|
11011
|
+
const renderedRange = fillRange ?? selectedRange;
|
|
11012
|
+
const renderedRangeBounds = useMemo12(
|
|
11013
|
+
() => renderedRange ? getRangeBounds(renderedRange) : null,
|
|
11014
|
+
[getRangeBounds, renderedRange]
|
|
11015
|
+
);
|
|
11016
|
+
const getCellFromPosition = useCallback9((subrowIndex, dateIndex) => {
|
|
11017
|
+
const task = tasks[Math.floor(subrowIndex / 2)];
|
|
11018
|
+
if (!task) return null;
|
|
11019
|
+
return {
|
|
11020
|
+
taskId: task.id,
|
|
11021
|
+
dateIndex,
|
|
11022
|
+
kind: subrowIndex % 2 === 0 ? "plan" : "fact"
|
|
11023
|
+
};
|
|
11024
|
+
}, [tasks]);
|
|
11025
|
+
const isCellInRange = useCallback9((cell, range) => {
|
|
11026
|
+
const bounds = getRangeBounds(range);
|
|
11027
|
+
if (!bounds) return false;
|
|
11028
|
+
const cellTaskIndex = taskIndexById.get(cell.taskId);
|
|
11029
|
+
if (cellTaskIndex === void 0) {
|
|
11030
|
+
return false;
|
|
11031
|
+
}
|
|
11032
|
+
const cellSubrowIndex = getSubrowIndex(cellTaskIndex, cell.kind);
|
|
11033
|
+
return cell.dateIndex >= bounds.fromDateIndex && cell.dateIndex <= bounds.toDateIndex && cellSubrowIndex >= bounds.fromSubrowIndex && cellSubrowIndex <= bounds.toSubrowIndex;
|
|
11034
|
+
}, [getRangeBounds, taskIndexById]);
|
|
11035
|
+
const commitCell = useCallback9((task, dateIndex, kind, value) => {
|
|
11036
|
+
const dateKey = dateKeys[dateIndex];
|
|
11037
|
+
const source = kind === "plan" ? task.planByDate : task.factByDate;
|
|
11038
|
+
const nextValues = { ...source ?? {} };
|
|
11039
|
+
if (value === void 0) {
|
|
11040
|
+
delete nextValues[dateKey];
|
|
11041
|
+
} else {
|
|
11042
|
+
nextValues[dateKey] = value;
|
|
11043
|
+
}
|
|
11044
|
+
const changedTask = {
|
|
11045
|
+
...task,
|
|
11046
|
+
[kind === "plan" ? "planByDate" : "factByDate"]: nextValues
|
|
11047
|
+
};
|
|
11048
|
+
onTasksChange?.([changedTask]);
|
|
11049
|
+
onCellCommit?.({
|
|
11050
|
+
task,
|
|
11051
|
+
date: dateRange[dateIndex],
|
|
11052
|
+
dateKey,
|
|
11053
|
+
kind,
|
|
11054
|
+
value
|
|
11055
|
+
});
|
|
11056
|
+
}, [dateKeys, dateRange, onCellCommit, onTasksChange]);
|
|
11057
|
+
const commitRangeCells = useCallback9((bounds, value, mode) => {
|
|
11058
|
+
const changedTasksById = /* @__PURE__ */ new Map();
|
|
11059
|
+
for (let subrowIndex = bounds.fromSubrowIndex; subrowIndex <= bounds.toSubrowIndex; subrowIndex += 1) {
|
|
11060
|
+
const task = tasks[Math.floor(subrowIndex / 2)];
|
|
11061
|
+
if (!task || parentTaskIds.has(task.id)) continue;
|
|
11062
|
+
const kind = subrowIndex % 2 === 0 ? "plan" : "fact";
|
|
11063
|
+
const currentChangedTask = changedTasksById.get(task.id) ?? task;
|
|
11064
|
+
let nextPlanByDate = currentChangedTask.planByDate;
|
|
11065
|
+
let nextFactByDate = currentChangedTask.factByDate;
|
|
11066
|
+
let didChange = false;
|
|
11067
|
+
for (let dateIndex = bounds.fromDateIndex; dateIndex <= bounds.toDateIndex; dateIndex += 1) {
|
|
11068
|
+
const dateKey = dateKeys[dateIndex];
|
|
11069
|
+
if (dateKey === void 0) continue;
|
|
11070
|
+
const currentValues = kind === "plan" ? nextPlanByDate : nextFactByDate;
|
|
11071
|
+
const currentValue = currentValues?.[dateKey];
|
|
11072
|
+
const nextValue = mode === "clear" ? void 0 : value;
|
|
11073
|
+
if (currentValue === nextValue) continue;
|
|
11074
|
+
if (kind === "plan") {
|
|
11075
|
+
nextPlanByDate = { ...nextPlanByDate ?? {} };
|
|
11076
|
+
if (nextValue === void 0) {
|
|
11077
|
+
delete nextPlanByDate[dateKey];
|
|
11078
|
+
} else {
|
|
11079
|
+
nextPlanByDate[dateKey] = nextValue;
|
|
11080
|
+
}
|
|
11081
|
+
} else {
|
|
11082
|
+
nextFactByDate = { ...nextFactByDate ?? {} };
|
|
11083
|
+
if (nextValue === void 0) {
|
|
11084
|
+
delete nextFactByDate[dateKey];
|
|
11085
|
+
} else {
|
|
11086
|
+
nextFactByDate[dateKey] = nextValue;
|
|
11087
|
+
}
|
|
11088
|
+
}
|
|
11089
|
+
didChange = true;
|
|
11090
|
+
}
|
|
11091
|
+
if (didChange) {
|
|
11092
|
+
changedTasksById.set(task.id, {
|
|
11093
|
+
...currentChangedTask,
|
|
11094
|
+
...nextPlanByDate !== currentChangedTask.planByDate ? { planByDate: nextPlanByDate ?? {} } : {},
|
|
11095
|
+
...nextFactByDate !== currentChangedTask.factByDate ? { factByDate: nextFactByDate ?? {} } : {}
|
|
11096
|
+
});
|
|
11097
|
+
}
|
|
11098
|
+
}
|
|
11099
|
+
const changedTasks = Array.from(changedTasksById.values());
|
|
11100
|
+
if (changedTasks.length > 0) {
|
|
11101
|
+
onTasksChange?.(changedTasks);
|
|
11102
|
+
}
|
|
11103
|
+
}, [dateKeys, onTasksChange, parentTaskIds, tasks]);
|
|
11104
|
+
const clearSelectedCells = useCallback9(() => {
|
|
11105
|
+
const activeRange = fillRange ?? selectedRange;
|
|
11106
|
+
if (!activeRange) {
|
|
11107
|
+
if (!activeCell) return;
|
|
11108
|
+
const task = taskById.get(activeCell.taskId);
|
|
11109
|
+
if (!task || parentTaskIds.has(task.id)) return;
|
|
11110
|
+
commitCell(task, activeCell.dateIndex, activeCell.kind, void 0);
|
|
11111
|
+
return;
|
|
11112
|
+
}
|
|
11113
|
+
const bounds = getRangeBounds(activeRange);
|
|
11114
|
+
if (bounds) {
|
|
11115
|
+
commitRangeCells(bounds, void 0, "clear");
|
|
11116
|
+
}
|
|
11117
|
+
}, [activeCell, commitCell, commitRangeCells, fillRange, getRangeBounds, parentTaskIds, selectedRange, taskById]);
|
|
11118
|
+
const commitSelectedCells = useCallback9((value) => {
|
|
11119
|
+
const activeRange = fillRange ?? selectedRange;
|
|
11120
|
+
if (!activeRange) {
|
|
11121
|
+
if (!activeCell) return;
|
|
11122
|
+
const task = taskById.get(activeCell.taskId);
|
|
11123
|
+
if (!task || parentTaskIds.has(task.id)) return;
|
|
11124
|
+
commitCell(task, activeCell.dateIndex, activeCell.kind, value);
|
|
11125
|
+
return;
|
|
11126
|
+
}
|
|
11127
|
+
const bounds = getRangeBounds(activeRange);
|
|
11128
|
+
if (bounds) {
|
|
11129
|
+
commitRangeCells(bounds, value, "set");
|
|
11130
|
+
}
|
|
11131
|
+
}, [activeCell, commitCell, commitRangeCells, fillRange, getRangeBounds, parentTaskIds, selectedRange, taskById]);
|
|
11132
|
+
const getCellValue = useCallback9((cell) => {
|
|
11133
|
+
const task = taskById.get(cell.taskId);
|
|
11134
|
+
if (!task) return void 0;
|
|
11135
|
+
const dateKey = dateKeys[cell.dateIndex];
|
|
11136
|
+
return cell.kind === "plan" ? task.planByDate?.[dateKey] : task.factByDate?.[dateKey];
|
|
11137
|
+
}, [dateKeys, taskById]);
|
|
11138
|
+
const applyFillRange = useCallback9((nextFillRange) => {
|
|
11139
|
+
const targetRange = nextFillRange ?? fillRange;
|
|
11140
|
+
if (!selectedRange || !targetRange) return;
|
|
11141
|
+
const sourceBounds = getRangeBounds(selectedRange);
|
|
11142
|
+
const targetBounds = getRangeBounds(targetRange);
|
|
11143
|
+
if (!sourceBounds || !targetBounds) return;
|
|
11144
|
+
const sourceDateSpan = sourceBounds.toDateIndex - sourceBounds.fromDateIndex + 1;
|
|
11145
|
+
const sourceSubrowSpan = sourceBounds.toSubrowIndex - sourceBounds.fromSubrowIndex + 1;
|
|
11146
|
+
const changedTasksById = /* @__PURE__ */ new Map();
|
|
11147
|
+
for (let subrowIndex = targetBounds.fromSubrowIndex; subrowIndex <= targetBounds.toSubrowIndex; subrowIndex += 1) {
|
|
11148
|
+
const targetCellForRow = getCellFromPosition(subrowIndex, targetBounds.fromDateIndex);
|
|
11149
|
+
if (!targetCellForRow || parentTaskIds.has(targetCellForRow.taskId)) continue;
|
|
11150
|
+
const originalTask = taskById.get(targetCellForRow.taskId);
|
|
11151
|
+
if (!originalTask) continue;
|
|
11152
|
+
let changedTask = changedTasksById.get(originalTask.id) ?? originalTask;
|
|
11153
|
+
let nextPlanByDate = changedTask.planByDate;
|
|
11154
|
+
let nextFactByDate = changedTask.factByDate;
|
|
11155
|
+
let didChange = false;
|
|
11156
|
+
for (let dateIndex = targetBounds.fromDateIndex; dateIndex <= targetBounds.toDateIndex; dateIndex += 1) {
|
|
11157
|
+
const targetCell = getCellFromPosition(subrowIndex, dateIndex);
|
|
11158
|
+
if (!targetCell || isCellInRange(targetCell, selectedRange)) continue;
|
|
11159
|
+
const sourceSubrowIndex = sourceBounds.fromSubrowIndex + ((subrowIndex - sourceBounds.fromSubrowIndex) % sourceSubrowSpan + sourceSubrowSpan) % sourceSubrowSpan;
|
|
11160
|
+
const sourceDateIndex = sourceBounds.fromDateIndex + ((dateIndex - sourceBounds.fromDateIndex) % sourceDateSpan + sourceDateSpan) % sourceDateSpan;
|
|
11161
|
+
const sourceCell = getCellFromPosition(sourceSubrowIndex, sourceDateIndex);
|
|
11162
|
+
if (!sourceCell) continue;
|
|
11163
|
+
const nextValue = getCellValue(sourceCell);
|
|
11164
|
+
const dateKey = dateKeys[dateIndex];
|
|
11165
|
+
const currentValues = targetCell.kind === "plan" ? nextPlanByDate : nextFactByDate;
|
|
11166
|
+
if (currentValues?.[dateKey] === nextValue) continue;
|
|
11167
|
+
if (targetCell.kind === "plan") {
|
|
11168
|
+
nextPlanByDate = { ...nextPlanByDate ?? {} };
|
|
11169
|
+
if (nextValue === void 0) {
|
|
11170
|
+
delete nextPlanByDate[dateKey];
|
|
11171
|
+
} else {
|
|
11172
|
+
nextPlanByDate[dateKey] = nextValue;
|
|
11173
|
+
}
|
|
11174
|
+
} else {
|
|
11175
|
+
nextFactByDate = { ...nextFactByDate ?? {} };
|
|
11176
|
+
if (nextValue === void 0) {
|
|
11177
|
+
delete nextFactByDate[dateKey];
|
|
11178
|
+
} else {
|
|
11179
|
+
nextFactByDate[dateKey] = nextValue;
|
|
11180
|
+
}
|
|
11181
|
+
}
|
|
11182
|
+
didChange = true;
|
|
11183
|
+
}
|
|
11184
|
+
if (didChange) {
|
|
11185
|
+
changedTasksById.set(originalTask.id, {
|
|
11186
|
+
...changedTask,
|
|
11187
|
+
...nextPlanByDate !== changedTask.planByDate ? { planByDate: nextPlanByDate ?? {} } : {},
|
|
11188
|
+
...nextFactByDate !== changedTask.factByDate ? { factByDate: nextFactByDate ?? {} } : {}
|
|
11189
|
+
});
|
|
11190
|
+
}
|
|
11191
|
+
}
|
|
11192
|
+
const changedTasks = Array.from(changedTasksById.values());
|
|
11193
|
+
if (changedTasks.length > 0) {
|
|
11194
|
+
onTasksChange?.(changedTasks);
|
|
11195
|
+
}
|
|
11196
|
+
setSelectedRange(targetRange);
|
|
11197
|
+
setActiveCell(targetRange.anchor);
|
|
11198
|
+
setFillRange(null);
|
|
11199
|
+
}, [
|
|
11200
|
+
dateKeys,
|
|
11201
|
+
fillRange,
|
|
11202
|
+
getCellFromPosition,
|
|
11203
|
+
getCellValue,
|
|
11204
|
+
getRangeBounds,
|
|
11205
|
+
isCellInRange,
|
|
11206
|
+
onTasksChange,
|
|
11207
|
+
parentTaskIds,
|
|
11208
|
+
selectedRange,
|
|
11209
|
+
taskById
|
|
11210
|
+
]);
|
|
11211
|
+
const moveActiveCell = useCallback9((cell, direction) => {
|
|
11212
|
+
const taskIndex = tasks.findIndex((task) => task.id === cell.taskId);
|
|
11213
|
+
if (taskIndex < 0) return;
|
|
11214
|
+
let nextCell = { ...cell };
|
|
11215
|
+
if (direction === "left") {
|
|
11216
|
+
nextCell.dateIndex = Math.max(0, cell.dateIndex - 1);
|
|
11217
|
+
} else if (direction === "right") {
|
|
11218
|
+
nextCell.dateIndex = Math.min(dateRange.length - 1, cell.dateIndex + 1);
|
|
11219
|
+
} else if (direction === "up") {
|
|
11220
|
+
if (cell.kind === "fact") {
|
|
11221
|
+
nextCell.kind = "plan";
|
|
11222
|
+
} else {
|
|
11223
|
+
const previousEditableTaskIndex = findEditableTaskIndex(tasks, parentTaskIds, taskIndex - 1, -1);
|
|
11224
|
+
if (previousEditableTaskIndex === null) return;
|
|
11225
|
+
const previousTask = tasks[previousEditableTaskIndex];
|
|
11226
|
+
nextCell = { taskId: previousTask.id, dateIndex: cell.dateIndex, kind: "fact" };
|
|
11227
|
+
}
|
|
11228
|
+
} else if (direction === "down") {
|
|
11229
|
+
if (cell.kind === "plan") {
|
|
11230
|
+
nextCell.kind = "fact";
|
|
11231
|
+
} else {
|
|
11232
|
+
const nextEditableTaskIndex = findEditableTaskIndex(tasks, parentTaskIds, taskIndex + 1, 1);
|
|
11233
|
+
if (nextEditableTaskIndex === null) return;
|
|
11234
|
+
const nextTask = tasks[nextEditableTaskIndex];
|
|
11235
|
+
nextCell = { taskId: nextTask.id, dateIndex: cell.dateIndex, kind: "plan" };
|
|
11236
|
+
}
|
|
11237
|
+
}
|
|
11238
|
+
setActiveCell(nextCell);
|
|
11239
|
+
setSelectedRange({ anchor: nextCell, focus: nextCell });
|
|
11240
|
+
onTaskSelect?.(nextCell.taskId);
|
|
11241
|
+
focusCell(nextCell);
|
|
11242
|
+
}, [dateRange.length, focusCell, onTaskSelect, parentTaskIds, tasks]);
|
|
11243
|
+
const extendSelectedRange = useCallback9((cell, direction) => {
|
|
11244
|
+
const taskIndex = tasks.findIndex((task) => task.id === cell.taskId);
|
|
11245
|
+
if (taskIndex < 0) return;
|
|
11246
|
+
let nextCell = { ...cell };
|
|
11247
|
+
if (direction === "left") {
|
|
11248
|
+
nextCell.dateIndex = Math.max(0, cell.dateIndex - 1);
|
|
11249
|
+
} else if (direction === "right") {
|
|
11250
|
+
nextCell.dateIndex = Math.min(dateRange.length - 1, cell.dateIndex + 1);
|
|
11251
|
+
} else if (direction === "up") {
|
|
11252
|
+
if (cell.kind === "fact") {
|
|
11253
|
+
nextCell.kind = "plan";
|
|
11254
|
+
} else {
|
|
11255
|
+
const previousEditableTaskIndex = findEditableTaskIndex(tasks, parentTaskIds, taskIndex - 1, -1);
|
|
11256
|
+
if (previousEditableTaskIndex === null) return;
|
|
11257
|
+
const previousTask = tasks[previousEditableTaskIndex];
|
|
11258
|
+
nextCell = { taskId: previousTask.id, dateIndex: cell.dateIndex, kind: "fact" };
|
|
11259
|
+
}
|
|
11260
|
+
} else if (direction === "down") {
|
|
11261
|
+
if (cell.kind === "plan") {
|
|
11262
|
+
nextCell.kind = "fact";
|
|
11263
|
+
} else {
|
|
11264
|
+
const nextEditableTaskIndex = findEditableTaskIndex(tasks, parentTaskIds, taskIndex + 1, 1);
|
|
11265
|
+
if (nextEditableTaskIndex === null) return;
|
|
11266
|
+
const nextTask = tasks[nextEditableTaskIndex];
|
|
11267
|
+
nextCell = { taskId: nextTask.id, dateIndex: cell.dateIndex, kind: "plan" };
|
|
11268
|
+
}
|
|
11269
|
+
}
|
|
11270
|
+
setActiveCell((currentActiveCell) => currentActiveCell ?? cell);
|
|
11271
|
+
setFillRange(null);
|
|
11272
|
+
setSelectedRange((currentRange) => ({
|
|
11273
|
+
anchor: currentRange?.anchor ?? cell,
|
|
11274
|
+
focus: nextCell
|
|
11275
|
+
}));
|
|
11276
|
+
onTaskSelect?.(nextCell.taskId);
|
|
11277
|
+
focusCell(selectedRange?.anchor ?? cell);
|
|
11278
|
+
}, [dateRange.length, focusCell, onTaskSelect, parentTaskIds, selectedRange, tasks]);
|
|
11279
|
+
useEffect9(() => {
|
|
11280
|
+
const endSelection = () => {
|
|
11281
|
+
let pendingFillRange = null;
|
|
11282
|
+
if (hoverFrameRef.current !== null) {
|
|
11283
|
+
window.cancelAnimationFrame(hoverFrameRef.current);
|
|
11284
|
+
hoverFrameRef.current = null;
|
|
11285
|
+
const pendingCell = pendingHoverCellRef.current;
|
|
11286
|
+
if (pendingCell && isFillDraggingRef.current && selectedRange) {
|
|
11287
|
+
pendingFillRange = { anchor: selectedRange.anchor, focus: pendingCell };
|
|
11288
|
+
}
|
|
11289
|
+
flushPendingHoverCell();
|
|
11290
|
+
}
|
|
11291
|
+
if (isFillDraggingRef.current) {
|
|
11292
|
+
isFillDraggingRef.current = false;
|
|
11293
|
+
applyFillRange(pendingFillRange);
|
|
11294
|
+
}
|
|
11295
|
+
isSelectingRef.current = false;
|
|
11296
|
+
};
|
|
11297
|
+
window.addEventListener("mouseup", endSelection);
|
|
11298
|
+
return () => {
|
|
11299
|
+
window.removeEventListener("mouseup", endSelection);
|
|
11300
|
+
};
|
|
11301
|
+
}, [applyFillRange, flushPendingHoverCell]);
|
|
11302
|
+
useEffect9(() => () => {
|
|
11303
|
+
if (hoverFrameRef.current !== null) {
|
|
11304
|
+
window.cancelAnimationFrame(hoverFrameRef.current);
|
|
11305
|
+
}
|
|
11306
|
+
}, []);
|
|
11307
|
+
useEffect9(() => {
|
|
11308
|
+
const handleKeyDown = (event) => {
|
|
11309
|
+
if (event.key !== "Escape") return;
|
|
11310
|
+
clearSelection();
|
|
11311
|
+
};
|
|
11312
|
+
const handleMouseDown = (event) => {
|
|
11313
|
+
const target = event.target;
|
|
11314
|
+
if (target instanceof Node && rootRef.current?.contains(target)) {
|
|
11315
|
+
return;
|
|
11316
|
+
}
|
|
11317
|
+
clearSelection();
|
|
11318
|
+
};
|
|
11319
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
11320
|
+
document.addEventListener("mousedown", handleMouseDown);
|
|
11321
|
+
return () => {
|
|
11322
|
+
window.removeEventListener("keydown", handleKeyDown);
|
|
11323
|
+
document.removeEventListener("mousedown", handleMouseDown);
|
|
11324
|
+
};
|
|
11325
|
+
}, [clearSelection]);
|
|
11326
|
+
return /* @__PURE__ */ jsxs14(
|
|
11327
|
+
"div",
|
|
11328
|
+
{
|
|
11329
|
+
ref: rootRef,
|
|
11330
|
+
className: "gantt-pf-root",
|
|
11331
|
+
style: {
|
|
11332
|
+
width: `${totalWidth}px`,
|
|
11333
|
+
["--gantt-pf-day-width"]: `${dayWidth}px`
|
|
11334
|
+
},
|
|
11335
|
+
children: [
|
|
11336
|
+
/* @__PURE__ */ jsxs14("div", { className: "gantt-pf-header", style: { width: `${totalWidth}px`, height: `${headerHeight}px` }, children: [
|
|
11337
|
+
/* @__PURE__ */ jsx18(
|
|
11338
|
+
TimeScaleHeader_default,
|
|
11339
|
+
{
|
|
11340
|
+
days: dateRange,
|
|
11341
|
+
dayWidth,
|
|
11342
|
+
headerHeight: headerHeight - 1,
|
|
11343
|
+
viewMode: "day"
|
|
11344
|
+
}
|
|
11345
|
+
),
|
|
11346
|
+
todayDateIndex !== void 0 && todayDateIndex >= 0 && /* @__PURE__ */ jsx18(
|
|
11347
|
+
"span",
|
|
11348
|
+
{
|
|
11349
|
+
className: "gantt-pf-headerTodayLine",
|
|
11350
|
+
"aria-hidden": "true",
|
|
11351
|
+
style: {
|
|
11352
|
+
left: `${todayDateIndex * dayWidth}px`,
|
|
11353
|
+
top: `${Math.max(0, headerHeight / 2)}px`
|
|
11354
|
+
}
|
|
11355
|
+
}
|
|
11356
|
+
)
|
|
11357
|
+
] }),
|
|
11358
|
+
/* @__PURE__ */ jsx18("div", { className: "gantt-pf-monthSeparatorLayer", "aria-hidden": "true", children: monthSeparatorIndices.map((dateIndex) => /* @__PURE__ */ jsx18(
|
|
11359
|
+
"span",
|
|
11360
|
+
{
|
|
11361
|
+
className: "gantt-pf-monthSeparator",
|
|
11362
|
+
style: {
|
|
11363
|
+
left: `${Math.round(dateIndex * dayWidth)}px`,
|
|
11364
|
+
top: `${Math.max(0, headerHeight / 2)}px`
|
|
11365
|
+
}
|
|
11366
|
+
},
|
|
11367
|
+
`month-separator-${dateIndex}`
|
|
11368
|
+
)) }),
|
|
11369
|
+
/* @__PURE__ */ jsx18(
|
|
11370
|
+
"div",
|
|
11371
|
+
{
|
|
11372
|
+
ref: bodyRef,
|
|
11373
|
+
className: "gantt-pf-body",
|
|
11374
|
+
style: {
|
|
11375
|
+
height: `${tasks.length * rowHeight}px`,
|
|
11376
|
+
minHeight: bodyMinHeight,
|
|
11377
|
+
width: `${totalWidth}px`
|
|
11378
|
+
},
|
|
11379
|
+
children: renderedRowIndices.map((rowIndex) => {
|
|
11380
|
+
const task = tasks[rowIndex];
|
|
11381
|
+
if (!task) return null;
|
|
11382
|
+
const isParent = parentTaskIds.has(task.id);
|
|
11383
|
+
const isHighlighted = filterMode === "highlight" && !!highlightedTaskIds?.has(task.id);
|
|
11384
|
+
return /* @__PURE__ */ jsx18(
|
|
11385
|
+
PlanFactRow,
|
|
11386
|
+
{
|
|
11387
|
+
task,
|
|
11388
|
+
rowIndex,
|
|
11389
|
+
dateRange,
|
|
11390
|
+
dateKeys,
|
|
11391
|
+
renderedDateIndices,
|
|
11392
|
+
rowHeight,
|
|
11393
|
+
subrowHeight,
|
|
11394
|
+
dayWidth,
|
|
11395
|
+
plannedRange: plannedRangeByTaskId.get(task.id) ?? null,
|
|
11396
|
+
todayDateIndex,
|
|
11397
|
+
isParent,
|
|
11398
|
+
isHighlighted,
|
|
11399
|
+
selectedTaskId,
|
|
11400
|
+
activeCell,
|
|
11401
|
+
editingCell,
|
|
11402
|
+
selectedRange,
|
|
11403
|
+
renderedRangeBounds,
|
|
11404
|
+
didDragSelectRef,
|
|
11405
|
+
isSelectingRef,
|
|
11406
|
+
isFillDraggingRef,
|
|
11407
|
+
onTaskSelect,
|
|
11408
|
+
selectSingleCell,
|
|
11409
|
+
queueHoverCellUpdate,
|
|
11410
|
+
setActiveCell,
|
|
11411
|
+
setEditingCell,
|
|
11412
|
+
setFillRange,
|
|
11413
|
+
clearSelectedCells,
|
|
11414
|
+
commitCell,
|
|
11415
|
+
commitSelectedCells,
|
|
11416
|
+
moveActiveCell,
|
|
11417
|
+
extendSelectedRange,
|
|
11418
|
+
focusCell,
|
|
11419
|
+
showOverflowTooltip,
|
|
11420
|
+
hideOverflowTooltip
|
|
11421
|
+
},
|
|
11422
|
+
task.id
|
|
11423
|
+
);
|
|
11424
|
+
})
|
|
11425
|
+
}
|
|
11426
|
+
),
|
|
11427
|
+
overflowTooltip && /* @__PURE__ */ jsx18(
|
|
11428
|
+
"div",
|
|
11429
|
+
{
|
|
11430
|
+
className: "gantt-pf-overflowTooltip",
|
|
11431
|
+
role: "tooltip",
|
|
11432
|
+
"aria-hidden": "true",
|
|
11433
|
+
style: {
|
|
11434
|
+
left: `${overflowTooltip.left}px`,
|
|
11435
|
+
top: `${overflowTooltip.top}px`
|
|
11436
|
+
},
|
|
11437
|
+
children: overflowTooltip.label
|
|
11438
|
+
}
|
|
11439
|
+
)
|
|
11440
|
+
]
|
|
11441
|
+
}
|
|
11442
|
+
);
|
|
11443
|
+
}
|
|
11444
|
+
|
|
10450
11445
|
// src/components/GanttChart/print.ts
|
|
10451
11446
|
function getPrintDocumentTitle({
|
|
10452
11447
|
header,
|
|
@@ -10855,9 +11850,60 @@ function createTaskPreviewPositionStore() {
|
|
|
10855
11850
|
}
|
|
10856
11851
|
|
|
10857
11852
|
// src/components/GanttChart/GanttChart.tsx
|
|
10858
|
-
import { Fragment as Fragment4, jsx as
|
|
11853
|
+
import { Fragment as Fragment4, jsx as jsx19, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
10859
11854
|
var SCROLL_TO_ROW_CONTEXT_ROWS = 2;
|
|
10860
11855
|
var TASK_ROW_OVERSCAN = 8;
|
|
11856
|
+
var PLAN_FACT_COLUMN_OVERSCAN = 24;
|
|
11857
|
+
var PLAN_FACT_COLUMN_WINDOW_STEP = 14;
|
|
11858
|
+
function getFullMonthDays(tasks) {
|
|
11859
|
+
if (!tasks || tasks.length === 0) {
|
|
11860
|
+
return getMultiMonthDays(tasks);
|
|
11861
|
+
}
|
|
11862
|
+
let minDate = null;
|
|
11863
|
+
let maxDate = null;
|
|
11864
|
+
for (const task of tasks) {
|
|
11865
|
+
const start = parseUTCDate(task.startDate);
|
|
11866
|
+
const end = parseUTCDate(task.endDate);
|
|
11867
|
+
if (!minDate || start.getTime() < minDate.getTime()) {
|
|
11868
|
+
minDate = start;
|
|
11869
|
+
}
|
|
11870
|
+
if (!maxDate || end.getTime() > maxDate.getTime()) {
|
|
11871
|
+
maxDate = end;
|
|
11872
|
+
}
|
|
11873
|
+
}
|
|
11874
|
+
if (!minDate || !maxDate) {
|
|
11875
|
+
return getMultiMonthDays(tasks);
|
|
11876
|
+
}
|
|
11877
|
+
const startOfMonth2 = new Date(Date.UTC(minDate.getUTCFullYear(), minDate.getUTCMonth(), 1));
|
|
11878
|
+
const endOfMonth = new Date(Date.UTC(maxDate.getUTCFullYear(), maxDate.getUTCMonth() + 1, 0));
|
|
11879
|
+
const days = [];
|
|
11880
|
+
const current = new Date(startOfMonth2);
|
|
11881
|
+
while (current.getTime() <= endOfMonth.getTime()) {
|
|
11882
|
+
days.push(new Date(Date.UTC(
|
|
11883
|
+
current.getUTCFullYear(),
|
|
11884
|
+
current.getUTCMonth(),
|
|
11885
|
+
current.getUTCDate()
|
|
11886
|
+
)));
|
|
11887
|
+
current.setUTCDate(current.getUTCDate() + 1);
|
|
11888
|
+
}
|
|
11889
|
+
return days;
|
|
11890
|
+
}
|
|
11891
|
+
function getPlanFactRangeTasks(tasks) {
|
|
11892
|
+
const rangeTasks = [];
|
|
11893
|
+
for (const task of tasks) {
|
|
11894
|
+
rangeTasks.push({ startDate: task.startDate, endDate: task.endDate });
|
|
11895
|
+
for (const dateKey of Object.keys(task.planByDate ?? {})) {
|
|
11896
|
+
rangeTasks.push({ startDate: dateKey, endDate: dateKey });
|
|
11897
|
+
}
|
|
11898
|
+
for (const dateKey of Object.keys(task.factByDate ?? {})) {
|
|
11899
|
+
rangeTasks.push({ startDate: dateKey, endDate: dateKey });
|
|
11900
|
+
}
|
|
11901
|
+
}
|
|
11902
|
+
return rangeTasks;
|
|
11903
|
+
}
|
|
11904
|
+
function clampScrollValue(value, max) {
|
|
11905
|
+
return Math.min(max, Math.max(0, value));
|
|
11906
|
+
}
|
|
10861
11907
|
function arePositionMapsEqual(left, right) {
|
|
10862
11908
|
if (left.size !== right.size) return false;
|
|
10863
11909
|
for (const [taskId, leftPosition] of left) {
|
|
@@ -10894,9 +11940,9 @@ function arePreviewTaskMapsEqual(left, right) {
|
|
|
10894
11940
|
}
|
|
10895
11941
|
function GanttChartInner(props, ref) {
|
|
10896
11942
|
if (props.mode === "resource-planner") {
|
|
10897
|
-
return /* @__PURE__ */
|
|
11943
|
+
return /* @__PURE__ */ jsx19(ResourceTimelineChart, { ...props });
|
|
10898
11944
|
}
|
|
10899
|
-
return /* @__PURE__ */
|
|
11945
|
+
return /* @__PURE__ */ jsx19(
|
|
10900
11946
|
TaskGanttChart,
|
|
10901
11947
|
{
|
|
10902
11948
|
...props,
|
|
@@ -10906,6 +11952,7 @@ function GanttChartInner(props, ref) {
|
|
|
10906
11952
|
}
|
|
10907
11953
|
function TaskGanttChartInner(props, ref) {
|
|
10908
11954
|
const isTableMatrixMode = props.mode === "table-matrix";
|
|
11955
|
+
const isPlanFactMode = props.mode === "plan-fact";
|
|
10909
11956
|
const {
|
|
10910
11957
|
tasks,
|
|
10911
11958
|
rowHeight = 40,
|
|
@@ -10955,47 +12002,52 @@ function TaskGanttChartInner(props, ref) {
|
|
|
10955
12002
|
onTaskDateChangeModeChange: externalOnTaskDateChangeModeChange
|
|
10956
12003
|
} = props;
|
|
10957
12004
|
const dayWidth = !isTableMatrixMode ? props.dayWidth ?? 40 : 40;
|
|
10958
|
-
const viewMode = !isTableMatrixMode ? props.viewMode ?? "day" : "day";
|
|
10959
|
-
const customDays = !isTableMatrixMode ? props.customDays : void 0;
|
|
10960
|
-
const isWeekend3 = !isTableMatrixMode ? props.isWeekend : void 0;
|
|
10961
|
-
const businessDays = !isTableMatrixMode ? props.businessDays ?? true : true;
|
|
12005
|
+
const viewMode = !isTableMatrixMode && !isPlanFactMode ? props.viewMode ?? "day" : "day";
|
|
12006
|
+
const customDays = !isTableMatrixMode && !isPlanFactMode ? props.customDays : void 0;
|
|
12007
|
+
const isWeekend3 = !isTableMatrixMode && !isPlanFactMode ? props.isWeekend : void 0;
|
|
12008
|
+
const businessDays = !isTableMatrixMode && !isPlanFactMode ? props.businessDays ?? true : true;
|
|
10962
12009
|
const matrixColumns = isTableMatrixMode ? props.matrixColumns : [];
|
|
10963
12010
|
const matrixColumnGroups = isTableMatrixMode ? props.matrixColumnGroups : void 0;
|
|
10964
12011
|
const onMatrixCellClick = isTableMatrixMode ? props.onMatrixCellClick : void 0;
|
|
10965
12012
|
const matrixDateOverlay = isTableMatrixMode ? props.matrixDateOverlay : void 0;
|
|
10966
|
-
const
|
|
10967
|
-
const
|
|
10968
|
-
const
|
|
10969
|
-
const
|
|
10970
|
-
const
|
|
10971
|
-
const
|
|
10972
|
-
const
|
|
12013
|
+
const onPlanFactCellCommit = isPlanFactMode ? props.onPlanFactCellCommit : void 0;
|
|
12014
|
+
const containerRef = useRef11(null);
|
|
12015
|
+
const scrollContainerRef = useRef11(null);
|
|
12016
|
+
const scrollContentRef = useRef11(null);
|
|
12017
|
+
const clearSelectedTaskTimeoutRef = useRef11(null);
|
|
12018
|
+
const hasAutoScrolledToTodayRef = useRef11(false);
|
|
12019
|
+
const previewPositionStoreRef = useRef11(null);
|
|
12020
|
+
const renderedTaskIdsRef = useRef11(/* @__PURE__ */ new Set());
|
|
10973
12021
|
if (previewPositionStoreRef.current === null) {
|
|
10974
12022
|
previewPositionStoreRef.current = createTaskPreviewPositionStore();
|
|
10975
12023
|
}
|
|
10976
12024
|
const previewPositionStore = previewPositionStoreRef.current;
|
|
10977
|
-
const [selectedTaskId, setSelectedTaskId] =
|
|
10978
|
-
const [taskListHasRightShadow, setTaskListHasRightShadow] =
|
|
10979
|
-
const [internalTaskDateChangeMode, setInternalTaskDateChangeMode] =
|
|
10980
|
-
const [scrollViewport, setScrollViewport] =
|
|
10981
|
-
const [
|
|
10982
|
-
const [
|
|
10983
|
-
const [
|
|
12025
|
+
const [selectedTaskId, setSelectedTaskId] = useState11(null);
|
|
12026
|
+
const [taskListHasRightShadow, setTaskListHasRightShadow] = useState11(false);
|
|
12027
|
+
const [internalTaskDateChangeMode, setInternalTaskDateChangeMode] = useState11("preserve-duration");
|
|
12028
|
+
const [scrollViewport, setScrollViewport] = useState11({ scrollTop: 0, viewportHeight: 0 });
|
|
12029
|
+
const [planFactDateWindow, setPlanFactDateWindow] = useState11(null);
|
|
12030
|
+
const [selectedChip, setSelectedChip] = useState11(null);
|
|
12031
|
+
const [activeTimelineTooltip, setActiveTimelineTooltip] = useState11(null);
|
|
12032
|
+
const [internalCollapsedParentIds, setInternalCollapsedParentIds] = useState11(/* @__PURE__ */ new Set());
|
|
10984
12033
|
const collapsedParentIds = externalCollapsedParentIds ?? internalCollapsedParentIds;
|
|
10985
|
-
const [editingTaskId, setEditingTaskId] =
|
|
12034
|
+
const [editingTaskId, setEditingTaskId] = useState11(null);
|
|
10986
12035
|
const taskDateChangeMode = externalTaskDateChangeMode ?? internalTaskDateChangeMode;
|
|
10987
12036
|
const handleTaskDateChangeMode = externalOnTaskDateChangeModeChange ?? setInternalTaskDateChangeMode;
|
|
10988
|
-
const resolvedRowContentLines = Math.max(1, Math.floor(rowContentLines));
|
|
10989
|
-
const effectiveRowHeight =
|
|
12037
|
+
const resolvedRowContentLines = isPlanFactMode ? Math.max(2, Math.floor(rowContentLines)) : Math.max(1, Math.floor(rowContentLines));
|
|
12038
|
+
const effectiveRowHeight = useMemo13(
|
|
10990
12039
|
() => Math.max(rowHeight, 10 + resolvedRowContentLines * 18),
|
|
10991
12040
|
[resolvedRowContentLines, rowHeight]
|
|
10992
12041
|
);
|
|
10993
|
-
const normalizedTasks =
|
|
10994
|
-
const isCustomWeekend =
|
|
12042
|
+
const normalizedTasks = useMemo13(() => normalizeHierarchyTasks(tasks), [tasks]);
|
|
12043
|
+
const isCustomWeekend = useMemo13(
|
|
10995
12044
|
() => createCustomDayPredicate({ customDays, isWeekend: isWeekend3 }),
|
|
10996
12045
|
[customDays, isWeekend3]
|
|
10997
12046
|
);
|
|
10998
|
-
const dateRangeTasks =
|
|
12047
|
+
const dateRangeTasks = useMemo13(() => {
|
|
12048
|
+
if (isPlanFactMode) {
|
|
12049
|
+
return getPlanFactRangeTasks(normalizedTasks);
|
|
12050
|
+
}
|
|
10999
12051
|
if (!showBaseline) {
|
|
11000
12052
|
return normalizedTasks;
|
|
11001
12053
|
}
|
|
@@ -11004,22 +12056,25 @@ function TaskGanttChartInner(props, ref) {
|
|
|
11004
12056
|
startDate: task.baselineStartDate && parseUTCDate(task.baselineStartDate).getTime() < parseUTCDate(task.startDate).getTime() ? task.baselineStartDate : task.startDate,
|
|
11005
12057
|
endDate: task.baselineEndDate && parseUTCDate(task.baselineEndDate).getTime() > parseUTCDate(task.endDate).getTime() ? task.baselineEndDate : task.endDate
|
|
11006
12058
|
}));
|
|
11007
|
-
}, [normalizedTasks, showBaseline]);
|
|
11008
|
-
const dateRange =
|
|
11009
|
-
|
|
11010
|
-
|
|
11011
|
-
|
|
12059
|
+
}, [isPlanFactMode, normalizedTasks, showBaseline]);
|
|
12060
|
+
const dateRange = useMemo13(
|
|
12061
|
+
() => isPlanFactMode ? getFullMonthDays(dateRangeTasks) : getMultiMonthDays(dateRangeTasks),
|
|
12062
|
+
[dateRangeTasks, isPlanFactMode]
|
|
12063
|
+
);
|
|
12064
|
+
const [validationResult, setValidationResult] = useState11(null);
|
|
12065
|
+
const [cascadeOverrides, setCascadeOverrides] = useState11(/* @__PURE__ */ new Map());
|
|
12066
|
+
const gridWidth = useMemo13(
|
|
11012
12067
|
() => Math.round(dateRange.length * dayWidth),
|
|
11013
12068
|
[dateRange.length, dayWidth]
|
|
11014
12069
|
);
|
|
11015
|
-
const matrixWidth =
|
|
12070
|
+
const matrixWidth = useMemo13(
|
|
11016
12071
|
() => matrixColumns.reduce((sum, column) => {
|
|
11017
12072
|
if (typeof column.width !== "number") return void 0;
|
|
11018
12073
|
return sum !== void 0 ? sum + column.width : void 0;
|
|
11019
12074
|
}, 0),
|
|
11020
12075
|
[matrixColumns]
|
|
11021
12076
|
);
|
|
11022
|
-
const visibleTasks =
|
|
12077
|
+
const visibleTasks = useMemo13(() => {
|
|
11023
12078
|
const parentMap = new Map(normalizedTasks.map((t) => [t.id, t.parentId]));
|
|
11024
12079
|
function isAnyAncestorCollapsed(parentId) {
|
|
11025
12080
|
let current = parentId;
|
|
@@ -11035,11 +12090,11 @@ function TaskGanttChartInner(props, ref) {
|
|
|
11035
12090
|
}
|
|
11036
12091
|
return tasks2;
|
|
11037
12092
|
}, [normalizedTasks, collapsedParentIds, filterMode, taskFilter]);
|
|
11038
|
-
const matchedTaskIds =
|
|
12093
|
+
const matchedTaskIds = useMemo13(() => {
|
|
11039
12094
|
if (!taskFilter) return /* @__PURE__ */ new Set();
|
|
11040
12095
|
return new Set(visibleTasks.filter(taskFilter).map((task) => task.id));
|
|
11041
12096
|
}, [visibleTasks, taskFilter]);
|
|
11042
|
-
const taskListHighlightedTaskIds =
|
|
12097
|
+
const taskListHighlightedTaskIds = useMemo13(() => {
|
|
11043
12098
|
if (filterMode === "hide") {
|
|
11044
12099
|
return /* @__PURE__ */ new Set();
|
|
11045
12100
|
}
|
|
@@ -11050,33 +12105,34 @@ function TaskGanttChartInner(props, ref) {
|
|
|
11050
12105
|
matchedTaskIds.forEach((taskId) => mergedHighlightedTaskIds.add(taskId));
|
|
11051
12106
|
return mergedHighlightedTaskIds;
|
|
11052
12107
|
}, [filterMode, highlightedTaskIds, matchedTaskIds]);
|
|
11053
|
-
const totalGridHeight =
|
|
12108
|
+
const totalGridHeight = useMemo13(
|
|
11054
12109
|
() => visibleTasks.length * effectiveRowHeight,
|
|
11055
12110
|
[effectiveRowHeight, visibleTasks.length]
|
|
11056
12111
|
);
|
|
11057
12112
|
const timelineHeaderHeight = headerHeight + 1;
|
|
11058
|
-
const tableBodyMinHeight =
|
|
11059
|
-
if (!isTableMatrixMode || containerHeight === void 0) {
|
|
12113
|
+
const tableBodyMinHeight = useMemo13(() => {
|
|
12114
|
+
if (!isTableMatrixMode && !isPlanFactMode || containerHeight === void 0) {
|
|
11060
12115
|
return void 0;
|
|
11061
12116
|
}
|
|
11062
12117
|
if (typeof containerHeight === "number") {
|
|
11063
12118
|
return Math.max(0, containerHeight - timelineHeaderHeight);
|
|
11064
12119
|
}
|
|
11065
12120
|
return `calc(${containerHeight} - ${timelineHeaderHeight}px)`;
|
|
11066
|
-
}, [containerHeight, isTableMatrixMode, timelineHeaderHeight]);
|
|
11067
|
-
const monthStart =
|
|
12121
|
+
}, [containerHeight, isPlanFactMode, isTableMatrixMode, timelineHeaderHeight]);
|
|
12122
|
+
const monthStart = useMemo13(() => {
|
|
11068
12123
|
if (dateRange.length === 0) {
|
|
11069
12124
|
return new Date(Date.UTC((/* @__PURE__ */ new Date()).getUTCFullYear(), (/* @__PURE__ */ new Date()).getUTCMonth(), 1));
|
|
11070
12125
|
}
|
|
11071
12126
|
const firstDay = dateRange[0];
|
|
11072
12127
|
return new Date(Date.UTC(firstDay.getUTCFullYear(), firstDay.getUTCMonth(), 1));
|
|
11073
12128
|
}, [dateRange]);
|
|
11074
|
-
const
|
|
12129
|
+
const todayIndex = useMemo13(() => {
|
|
11075
12130
|
const now = /* @__PURE__ */ new Date();
|
|
11076
12131
|
const today = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()));
|
|
11077
|
-
return dateRange.
|
|
12132
|
+
return dateRange.findIndex((day) => day.getTime() === today.getTime());
|
|
11078
12133
|
}, [dateRange]);
|
|
11079
|
-
const
|
|
12134
|
+
const todayInRange = todayIndex !== -1;
|
|
12135
|
+
const visibleTimelineMarkers = useMemo13(() => {
|
|
11080
12136
|
if (isTableMatrixMode || !timelineMarkers || timelineMarkers.length === 0 || dateRange.length === 0) {
|
|
11081
12137
|
return [];
|
|
11082
12138
|
}
|
|
@@ -11087,22 +12143,22 @@ function TaskGanttChartInner(props, ref) {
|
|
|
11087
12143
|
return markerDate >= rangeStartMs && markerDate <= rangeEndMs;
|
|
11088
12144
|
});
|
|
11089
12145
|
}, [dateRange, isTableMatrixMode, timelineMarkers]);
|
|
11090
|
-
|
|
12146
|
+
useEffect10(() => {
|
|
11091
12147
|
if (isTableMatrixMode) return;
|
|
11092
12148
|
if (hasAutoScrolledToTodayRef.current) return;
|
|
11093
12149
|
const container = scrollContainerRef.current;
|
|
11094
12150
|
if (!container || dateRange.length === 0) return;
|
|
11095
12151
|
const now = /* @__PURE__ */ new Date();
|
|
11096
12152
|
const today = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()));
|
|
11097
|
-
const
|
|
11098
|
-
if (
|
|
11099
|
-
const todayOffset =
|
|
12153
|
+
const todayIndex2 = dateRange.findIndex((day) => day.getTime() === today.getTime());
|
|
12154
|
+
if (todayIndex2 === -1) return;
|
|
12155
|
+
const todayOffset = todayIndex2 * dayWidth;
|
|
11100
12156
|
const containerWidth = container.clientWidth;
|
|
11101
12157
|
const scrollLeft = Math.round(todayOffset + dayWidth / 2 - containerWidth * 0.3);
|
|
11102
12158
|
container.scrollLeft = Math.max(0, scrollLeft);
|
|
11103
12159
|
hasAutoScrolledToTodayRef.current = true;
|
|
11104
12160
|
}, [dateRange, dayWidth, isTableMatrixMode]);
|
|
11105
|
-
|
|
12161
|
+
useEffect10(() => {
|
|
11106
12162
|
const container = scrollContainerRef.current;
|
|
11107
12163
|
if (!container) return;
|
|
11108
12164
|
let frameId = null;
|
|
@@ -11110,13 +12166,33 @@ function TaskGanttChartInner(props, ref) {
|
|
|
11110
12166
|
frameId = null;
|
|
11111
12167
|
const nextHasRightShadow = container.scrollLeft > 0;
|
|
11112
12168
|
const nextViewportHeight = Math.max(0, container.clientHeight - timelineHeaderHeight);
|
|
12169
|
+
const nextViewportWidth = Math.max(0, container.clientWidth - (showTaskList ? taskListWidth : 0));
|
|
11113
12170
|
const nextScrollTop = container.scrollTop;
|
|
12171
|
+
const nextScrollLeft = container.scrollLeft;
|
|
12172
|
+
const nextChartScrollLeft = Math.max(0, nextScrollLeft);
|
|
11114
12173
|
setTaskListHasRightShadow(
|
|
11115
12174
|
(previous) => previous === nextHasRightShadow ? previous : nextHasRightShadow
|
|
11116
12175
|
);
|
|
11117
12176
|
setScrollViewport(
|
|
11118
12177
|
(previous) => previous.scrollTop === nextScrollTop && previous.viewportHeight === nextViewportHeight ? previous : { scrollTop: nextScrollTop, viewportHeight: nextViewportHeight }
|
|
11119
12178
|
);
|
|
12179
|
+
setPlanFactDateWindow((previous) => {
|
|
12180
|
+
if (!isPlanFactMode || dateRange.length === 0 || nextViewportWidth <= 0) {
|
|
12181
|
+
return previous === null ? previous : null;
|
|
12182
|
+
}
|
|
12183
|
+
const firstVisibleColumn = Math.max(0, Math.floor(nextChartScrollLeft / dayWidth));
|
|
12184
|
+
const visibleColumnCount = Math.max(1, Math.ceil(nextViewportWidth / dayWidth));
|
|
12185
|
+
const lastVisibleColumn = Math.min(dateRange.length - 1, firstVisibleColumn + visibleColumnCount - 1);
|
|
12186
|
+
const rangeStart = Math.max(
|
|
12187
|
+
0,
|
|
12188
|
+
Math.floor(Math.max(0, firstVisibleColumn - PLAN_FACT_COLUMN_OVERSCAN) / PLAN_FACT_COLUMN_WINDOW_STEP) * PLAN_FACT_COLUMN_WINDOW_STEP
|
|
12189
|
+
);
|
|
12190
|
+
const rangeEnd = Math.min(
|
|
12191
|
+
dateRange.length - 1,
|
|
12192
|
+
Math.ceil((lastVisibleColumn + PLAN_FACT_COLUMN_OVERSCAN + 1) / PLAN_FACT_COLUMN_WINDOW_STEP) * PLAN_FACT_COLUMN_WINDOW_STEP - 1
|
|
12193
|
+
);
|
|
12194
|
+
return previous?.start === rangeStart && previous.end === rangeEnd ? previous : { start: rangeStart, end: rangeEnd };
|
|
12195
|
+
});
|
|
11120
12196
|
};
|
|
11121
12197
|
const scheduleUpdate = () => {
|
|
11122
12198
|
if (frameId !== null) return;
|
|
@@ -11137,21 +12213,21 @@ function TaskGanttChartInner(props, ref) {
|
|
|
11137
12213
|
container.removeEventListener("scroll", scheduleUpdate);
|
|
11138
12214
|
window.removeEventListener("resize", scheduleUpdate);
|
|
11139
12215
|
};
|
|
11140
|
-
}, [timelineHeaderHeight]);
|
|
11141
|
-
const scrollToToday =
|
|
12216
|
+
}, [dateRange.length, dayWidth, isPlanFactMode, showTaskList, taskListWidth, timelineHeaderHeight]);
|
|
12217
|
+
const scrollToToday = useCallback10(() => {
|
|
11142
12218
|
if (isTableMatrixMode) return;
|
|
11143
12219
|
const container = scrollContainerRef.current;
|
|
11144
12220
|
if (!container || dateRange.length === 0) return;
|
|
11145
12221
|
const now = /* @__PURE__ */ new Date();
|
|
11146
12222
|
const today = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()));
|
|
11147
|
-
const
|
|
11148
|
-
if (
|
|
11149
|
-
const todayOffset =
|
|
12223
|
+
const todayIndex2 = dateRange.findIndex((day) => day.getTime() === today.getTime());
|
|
12224
|
+
if (todayIndex2 === -1) return;
|
|
12225
|
+
const todayOffset = todayIndex2 * dayWidth;
|
|
11150
12226
|
const containerWidth = container.clientWidth;
|
|
11151
12227
|
const scrollLeft = Math.round(todayOffset + dayWidth / 2 - containerWidth * 0.3);
|
|
11152
12228
|
container.scrollTo({ left: Math.max(0, scrollLeft), behavior: "smooth" });
|
|
11153
12229
|
}, [dateRange, dayWidth, isTableMatrixMode]);
|
|
11154
|
-
const scrollToTask =
|
|
12230
|
+
const scrollToTask = useCallback10((taskId) => {
|
|
11155
12231
|
if (isTableMatrixMode) {
|
|
11156
12232
|
const container2 = scrollContainerRef.current;
|
|
11157
12233
|
if (!container2) return;
|
|
@@ -11178,7 +12254,7 @@ function TaskGanttChartInner(props, ref) {
|
|
|
11178
12254
|
const scrollLeft = Math.round(taskOffset - dayWidth * 2);
|
|
11179
12255
|
container.scrollTo({ left: Math.max(0, scrollLeft), behavior: "smooth" });
|
|
11180
12256
|
}, [dateRange, dayWidth, effectiveRowHeight, isTableMatrixMode, tasks, visibleTasks]);
|
|
11181
|
-
const scrollToRow =
|
|
12257
|
+
const scrollToRow = useCallback10((taskId, options = {}) => {
|
|
11182
12258
|
const container = scrollContainerRef.current;
|
|
11183
12259
|
if (!container) return;
|
|
11184
12260
|
const task = tasks.find((t) => t.id === taskId);
|
|
@@ -11207,21 +12283,21 @@ function TaskGanttChartInner(props, ref) {
|
|
|
11207
12283
|
}
|
|
11208
12284
|
container.scrollTo({ top: scrollTop, behavior });
|
|
11209
12285
|
}, [effectiveRowHeight, tasks, visibleTasks]);
|
|
11210
|
-
const [dragGuideLines, setDragGuideLines] =
|
|
11211
|
-
const [draggedTaskOverride, setDraggedTaskOverride] =
|
|
11212
|
-
const [previewTasksById, setPreviewTasksById] =
|
|
11213
|
-
|
|
12286
|
+
const [dragGuideLines, setDragGuideLines] = useState11(null);
|
|
12287
|
+
const [draggedTaskOverride, setDraggedTaskOverride] = useState11(null);
|
|
12288
|
+
const [previewTasksById, setPreviewTasksById] = useState11(/* @__PURE__ */ new Map());
|
|
12289
|
+
useEffect10(() => {
|
|
11214
12290
|
const result = validateDependencies(tasks);
|
|
11215
12291
|
setValidationResult(result);
|
|
11216
12292
|
onValidateDependencies?.(result);
|
|
11217
12293
|
}, [tasks, onValidateDependencies]);
|
|
11218
|
-
|
|
12294
|
+
useEffect10(() => () => {
|
|
11219
12295
|
if (clearSelectedTaskTimeoutRef.current !== null) {
|
|
11220
12296
|
window.clearTimeout(clearSelectedTaskTimeoutRef.current);
|
|
11221
12297
|
}
|
|
11222
12298
|
previewPositionStore.clear();
|
|
11223
12299
|
}, [previewPositionStore]);
|
|
11224
|
-
const handleTaskChange =
|
|
12300
|
+
const handleTaskChange = useCallback10((updatedTasks) => {
|
|
11225
12301
|
const updatedTask = updatedTasks[0];
|
|
11226
12302
|
if (!updatedTask) return;
|
|
11227
12303
|
const originalTask = tasks.find((t) => t.id === updatedTask.id);
|
|
@@ -11267,7 +12343,7 @@ function TaskGanttChartInner(props, ref) {
|
|
|
11267
12343
|
const cascadedTasks = disableConstraints ? [updatedTask] : universalCascade(updatedTask, newStart, newEnd, sourceTasks, businessDays, isCustomWeekend);
|
|
11268
12344
|
onTasksChange?.(cascadedTasks);
|
|
11269
12345
|
}, [tasks, onTasksChange, disableConstraints, editingTaskId, businessDays, isCustomWeekend]);
|
|
11270
|
-
const handleDelete =
|
|
12346
|
+
const handleDelete = useCallback10((taskId) => {
|
|
11271
12347
|
const toDelete = /* @__PURE__ */ new Set([taskId]);
|
|
11272
12348
|
function collectDescendants(parentId) {
|
|
11273
12349
|
const children = getChildren(parentId, tasks);
|
|
@@ -11292,10 +12368,10 @@ function TaskGanttChartInner(props, ref) {
|
|
|
11292
12368
|
}
|
|
11293
12369
|
toDelete.forEach((id) => onDelete?.(id));
|
|
11294
12370
|
}, [tasks, onTasksChange, onDelete]);
|
|
11295
|
-
const handleInsertAfter =
|
|
12371
|
+
const handleInsertAfter = useCallback10((taskId, newTask) => {
|
|
11296
12372
|
onInsertAfter?.(taskId, newTask);
|
|
11297
12373
|
}, [onInsertAfter]);
|
|
11298
|
-
const handleReorder =
|
|
12374
|
+
const handleReorder = useCallback10((reorderedTasks, movedTaskId, inferredParentId) => {
|
|
11299
12375
|
let updated = reorderedTasks;
|
|
11300
12376
|
if (movedTaskId) {
|
|
11301
12377
|
updated = updated.map((t) => {
|
|
@@ -11312,7 +12388,7 @@ function TaskGanttChartInner(props, ref) {
|
|
|
11312
12388
|
}
|
|
11313
12389
|
onTasksChange?.(normalized);
|
|
11314
12390
|
}, [onTasksChange, onReorder]);
|
|
11315
|
-
const dependencyOverrides =
|
|
12391
|
+
const dependencyOverrides = useMemo13(() => {
|
|
11316
12392
|
const map = new Map(cascadeOverrides);
|
|
11317
12393
|
if (draggedTaskOverride) {
|
|
11318
12394
|
map.set(draggedTaskOverride.taskId, {
|
|
@@ -11322,7 +12398,7 @@ function TaskGanttChartInner(props, ref) {
|
|
|
11322
12398
|
}
|
|
11323
12399
|
return map;
|
|
11324
12400
|
}, [cascadeOverrides, draggedTaskOverride]);
|
|
11325
|
-
const handleCascadeProgress =
|
|
12401
|
+
const handleCascadeProgress = useCallback10((overrides, previewTasks = []) => {
|
|
11326
12402
|
previewPositionStore.setPositions(overrides);
|
|
11327
12403
|
const renderedTaskIds = renderedTaskIdsRef.current;
|
|
11328
12404
|
const renderedOverrides = /* @__PURE__ */ new Map();
|
|
@@ -11337,26 +12413,26 @@ function TaskGanttChartInner(props, ref) {
|
|
|
11337
12413
|
return arePreviewTaskMapsEqual(current, next) ? current : next;
|
|
11338
12414
|
});
|
|
11339
12415
|
}, [previewPositionStore]);
|
|
11340
|
-
const previewNormalizedTasks =
|
|
12416
|
+
const previewNormalizedTasks = useMemo13(() => {
|
|
11341
12417
|
if (previewTasksById.size === 0) return normalizedTasks;
|
|
11342
12418
|
return normalizedTasks.map((task) => previewTasksById.get(task.id) ?? task);
|
|
11343
12419
|
}, [normalizedTasks, previewTasksById]);
|
|
11344
|
-
const previewVisibleTasks =
|
|
12420
|
+
const previewVisibleTasks = useMemo13(() => {
|
|
11345
12421
|
if (previewTasksById.size === 0) return visibleTasks;
|
|
11346
12422
|
return visibleTasks.map((task) => previewTasksById.get(task.id) ?? task);
|
|
11347
12423
|
}, [visibleTasks, previewTasksById]);
|
|
11348
|
-
const visibleTaskIndexMap =
|
|
12424
|
+
const visibleTaskIndexMap = useMemo13(
|
|
11349
12425
|
() => new Map(visibleTasks.map((task, index) => [task.id, index])),
|
|
11350
12426
|
[visibleTasks]
|
|
11351
12427
|
);
|
|
11352
|
-
const forcedRenderedTaskIds =
|
|
12428
|
+
const forcedRenderedTaskIds = useMemo13(() => {
|
|
11353
12429
|
const ids = /* @__PURE__ */ new Set();
|
|
11354
12430
|
if (draggedTaskOverride) {
|
|
11355
12431
|
ids.add(draggedTaskOverride.taskId);
|
|
11356
12432
|
}
|
|
11357
12433
|
return ids;
|
|
11358
12434
|
}, [draggedTaskOverride]);
|
|
11359
|
-
const visibleTaskWindowIndices =
|
|
12435
|
+
const visibleTaskWindowIndices = useMemo13(() => {
|
|
11360
12436
|
const totalTasks = visibleTasks.length;
|
|
11361
12437
|
if (totalTasks === 0) {
|
|
11362
12438
|
return [];
|
|
@@ -11382,35 +12458,44 @@ function TaskGanttChartInner(props, ref) {
|
|
|
11382
12458
|
}
|
|
11383
12459
|
return Array.from(indices).sort((left, right) => left - right);
|
|
11384
12460
|
}, [effectiveRowHeight, forcedRenderedTaskIds, scrollViewport, visibleTaskIndexMap, visibleTasks.length]);
|
|
11385
|
-
const
|
|
12461
|
+
const visiblePlanFactDateIndices = useMemo13(() => {
|
|
12462
|
+
if (!isPlanFactMode || dateRange.length === 0 || !planFactDateWindow) {
|
|
12463
|
+
return void 0;
|
|
12464
|
+
}
|
|
12465
|
+
return Array.from(
|
|
12466
|
+
{ length: planFactDateWindow.end - planFactDateWindow.start + 1 },
|
|
12467
|
+
(_, index) => planFactDateWindow.start + index
|
|
12468
|
+
);
|
|
12469
|
+
}, [dateRange.length, isPlanFactMode, planFactDateWindow]);
|
|
12470
|
+
const renderedChartTasks = useMemo13(
|
|
11386
12471
|
() => visibleTaskWindowIndices.map((index) => {
|
|
11387
12472
|
const task = previewVisibleTasks[index];
|
|
11388
12473
|
return task ? { index, task } : null;
|
|
11389
12474
|
}).filter((entry) => entry !== null),
|
|
11390
12475
|
[previewVisibleTasks, visibleTaskWindowIndices]
|
|
11391
12476
|
);
|
|
11392
|
-
const renderedDependencyTasks =
|
|
12477
|
+
const renderedDependencyTasks = useMemo13(
|
|
11393
12478
|
() => renderedChartTasks.map(({ task }) => task),
|
|
11394
12479
|
[renderedChartTasks]
|
|
11395
12480
|
);
|
|
11396
|
-
renderedTaskIdsRef.current =
|
|
12481
|
+
renderedTaskIdsRef.current = useMemo13(
|
|
11397
12482
|
() => new Set(renderedChartTasks.map(({ task }) => task.id)),
|
|
11398
12483
|
[renderedChartTasks]
|
|
11399
12484
|
);
|
|
11400
|
-
const handleCascade =
|
|
12485
|
+
const handleCascade = useCallback10((cascadedTasks) => {
|
|
11401
12486
|
onTasksChange?.(cascadedTasks);
|
|
11402
12487
|
}, [tasks, onTasksChange]);
|
|
11403
|
-
const handleTaskSelect =
|
|
12488
|
+
const handleTaskSelect = useCallback10((taskId) => {
|
|
11404
12489
|
setSelectedTaskId(taskId);
|
|
11405
12490
|
}, []);
|
|
11406
|
-
const hoveredRowElementsRef =
|
|
11407
|
-
const clearHoveredRows =
|
|
12491
|
+
const hoveredRowElementsRef = useRef11([]);
|
|
12492
|
+
const clearHoveredRows = useCallback10(() => {
|
|
11408
12493
|
for (const element of hoveredRowElementsRef.current) {
|
|
11409
|
-
element.classList.remove("gantt-tl-row-hovered", "gantt-tr-row-hovered", "gantt-mx-row-hovered");
|
|
12494
|
+
element.classList.remove("gantt-tl-row-hovered", "gantt-tr-row-hovered", "gantt-mx-row-hovered", "gantt-pf-row-hovered");
|
|
11410
12495
|
}
|
|
11411
12496
|
hoveredRowElementsRef.current = [];
|
|
11412
12497
|
}, []);
|
|
11413
|
-
const applyHoveredRows =
|
|
12498
|
+
const applyHoveredRows = useCallback10((taskId) => {
|
|
11414
12499
|
const root = scrollContentRef.current;
|
|
11415
12500
|
if (!root) return;
|
|
11416
12501
|
clearHoveredRows();
|
|
@@ -11427,10 +12512,13 @@ function TaskGanttChartInner(props, ref) {
|
|
|
11427
12512
|
if (element.classList.contains("gantt-mx-row")) {
|
|
11428
12513
|
element.classList.add("gantt-mx-row-hovered");
|
|
11429
12514
|
}
|
|
12515
|
+
if (element.classList.contains("gantt-pf-row")) {
|
|
12516
|
+
element.classList.add("gantt-pf-row-hovered");
|
|
12517
|
+
}
|
|
11430
12518
|
}
|
|
11431
12519
|
hoveredRowElementsRef.current = nextHoveredRows;
|
|
11432
12520
|
}, [clearHoveredRows]);
|
|
11433
|
-
const handleSharedRowHover =
|
|
12521
|
+
const handleSharedRowHover = useCallback10((event) => {
|
|
11434
12522
|
const target = event.target;
|
|
11435
12523
|
const row = target.closest("[data-gantt-task-row-id]");
|
|
11436
12524
|
const taskId = row?.dataset.ganttTaskRowId;
|
|
@@ -11440,7 +12528,7 @@ function TaskGanttChartInner(props, ref) {
|
|
|
11440
12528
|
}
|
|
11441
12529
|
applyHoveredRows(taskId);
|
|
11442
12530
|
}, [applyHoveredRows]);
|
|
11443
|
-
const handleToggleCollapse = externalOnToggleCollapse ??
|
|
12531
|
+
const handleToggleCollapse = externalOnToggleCollapse ?? useCallback10((parentId) => {
|
|
11444
12532
|
setInternalCollapsedParentIds((prev) => {
|
|
11445
12533
|
const next = new Set(prev);
|
|
11446
12534
|
if (next.has(parentId)) {
|
|
@@ -11451,20 +12539,20 @@ function TaskGanttChartInner(props, ref) {
|
|
|
11451
12539
|
return next;
|
|
11452
12540
|
});
|
|
11453
12541
|
}, []);
|
|
11454
|
-
const allParentIds =
|
|
12542
|
+
const allParentIds = useMemo13(() => {
|
|
11455
12543
|
return new Set(
|
|
11456
12544
|
normalizedTasks.filter((t) => isTaskParent(t.id, normalizedTasks)).map((t) => t.id)
|
|
11457
12545
|
);
|
|
11458
12546
|
}, [normalizedTasks]);
|
|
11459
|
-
const handleCollapseAll =
|
|
12547
|
+
const handleCollapseAll = useCallback10(() => {
|
|
11460
12548
|
if (externalCollapsedParentIds) return;
|
|
11461
12549
|
setInternalCollapsedParentIds(allParentIds);
|
|
11462
12550
|
}, [allParentIds, externalCollapsedParentIds]);
|
|
11463
|
-
const handleExpandAll =
|
|
12551
|
+
const handleExpandAll = useCallback10(() => {
|
|
11464
12552
|
if (externalCollapsedParentIds) return;
|
|
11465
12553
|
setInternalCollapsedParentIds(/* @__PURE__ */ new Set());
|
|
11466
12554
|
}, [externalCollapsedParentIds]);
|
|
11467
|
-
const exportToPdf =
|
|
12555
|
+
const exportToPdf = useCallback10(async (options) => {
|
|
11468
12556
|
const sourceContainer = containerRef.current;
|
|
11469
12557
|
const sourceContent = scrollContentRef.current;
|
|
11470
12558
|
if (!sourceContainer || !sourceContent || typeof window === "undefined" || typeof document === "undefined") {
|
|
@@ -11523,7 +12611,7 @@ function TaskGanttChartInner(props, ref) {
|
|
|
11523
12611
|
}
|
|
11524
12612
|
return depth;
|
|
11525
12613
|
}
|
|
11526
|
-
const handlePromoteTask =
|
|
12614
|
+
const handlePromoteTask = useCallback10((taskId) => {
|
|
11527
12615
|
if (onPromoteTask) {
|
|
11528
12616
|
onPromoteTask(taskId);
|
|
11529
12617
|
return;
|
|
@@ -11555,7 +12643,7 @@ function TaskGanttChartInner(props, ref) {
|
|
|
11555
12643
|
]);
|
|
11556
12644
|
onTasksChange?.(reorderedTasks);
|
|
11557
12645
|
}, [tasks, onTasksChange, onPromoteTask]);
|
|
11558
|
-
const handleDemoteTask =
|
|
12646
|
+
const handleDemoteTask = useCallback10((taskId, newParentId) => {
|
|
11559
12647
|
if (onDemoteTask) {
|
|
11560
12648
|
onDemoteTask(taskId, newParentId);
|
|
11561
12649
|
return;
|
|
@@ -11596,7 +12684,7 @@ function TaskGanttChartInner(props, ref) {
|
|
|
11596
12684
|
};
|
|
11597
12685
|
onTasksChange?.([updatedDemotedTask]);
|
|
11598
12686
|
}, [tasks, onTasksChange, onDemoteTask]);
|
|
11599
|
-
const handleUngroupTask =
|
|
12687
|
+
const handleUngroupTask = useCallback10((taskId) => {
|
|
11600
12688
|
if (onUngroupTask) {
|
|
11601
12689
|
onUngroupTask(taskId);
|
|
11602
12690
|
return;
|
|
@@ -11621,8 +12709,8 @@ function TaskGanttChartInner(props, ref) {
|
|
|
11621
12709
|
onTasksChange?.(changedTasks);
|
|
11622
12710
|
}
|
|
11623
12711
|
}, [tasks, onTasksChange, onUngroupTask]);
|
|
11624
|
-
const panStateRef =
|
|
11625
|
-
const handlePanStart =
|
|
12712
|
+
const panStateRef = useRef11(null);
|
|
12713
|
+
const handlePanStart = useCallback10((e) => {
|
|
11626
12714
|
if (e.button !== 0) return;
|
|
11627
12715
|
const target = e.target;
|
|
11628
12716
|
if (target.closest("[data-taskbar]")) return;
|
|
@@ -11635,7 +12723,10 @@ function TaskGanttChartInner(props, ref) {
|
|
|
11635
12723
|
startX: e.clientX,
|
|
11636
12724
|
startY: e.clientY,
|
|
11637
12725
|
scrollX: container.scrollLeft,
|
|
11638
|
-
scrollY: container.scrollTop
|
|
12726
|
+
scrollY: container.scrollTop,
|
|
12727
|
+
currentX: e.clientX,
|
|
12728
|
+
currentY: e.clientY,
|
|
12729
|
+
frameId: null
|
|
11639
12730
|
};
|
|
11640
12731
|
if (document.activeElement instanceof HTMLElement) {
|
|
11641
12732
|
document.activeElement.blur();
|
|
@@ -11643,17 +12734,38 @@ function TaskGanttChartInner(props, ref) {
|
|
|
11643
12734
|
container.style.cursor = "grabbing";
|
|
11644
12735
|
e.preventDefault();
|
|
11645
12736
|
}, []);
|
|
11646
|
-
|
|
11647
|
-
const
|
|
12737
|
+
useEffect10(() => {
|
|
12738
|
+
const flushPanMove = () => {
|
|
11648
12739
|
const pan = panStateRef.current;
|
|
11649
12740
|
if (!pan?.active) return;
|
|
12741
|
+
pan.frameId = null;
|
|
11650
12742
|
const container = scrollContainerRef.current;
|
|
11651
12743
|
if (!container) return;
|
|
11652
|
-
|
|
11653
|
-
|
|
12744
|
+
const maxScrollLeft = Math.max(0, container.scrollWidth - container.clientWidth);
|
|
12745
|
+
const maxScrollTop = Math.max(0, container.scrollHeight - container.clientHeight);
|
|
12746
|
+
const nextScrollLeft = clampScrollValue(pan.scrollX - (pan.currentX - pan.startX), maxScrollLeft);
|
|
12747
|
+
const nextScrollTop = clampScrollValue(pan.scrollY - (pan.currentY - pan.startY), maxScrollTop);
|
|
12748
|
+
if (Math.abs(container.scrollLeft - nextScrollLeft) > 0.5) {
|
|
12749
|
+
container.scrollLeft = nextScrollLeft;
|
|
12750
|
+
}
|
|
12751
|
+
if (Math.abs(container.scrollTop - nextScrollTop) > 0.5) {
|
|
12752
|
+
container.scrollTop = nextScrollTop;
|
|
12753
|
+
}
|
|
12754
|
+
};
|
|
12755
|
+
const handlePanMove = (e) => {
|
|
12756
|
+
const pan = panStateRef.current;
|
|
12757
|
+
if (!pan?.active) return;
|
|
12758
|
+
pan.currentX = e.clientX;
|
|
12759
|
+
pan.currentY = e.clientY;
|
|
12760
|
+
if (pan.frameId !== null) return;
|
|
12761
|
+
pan.frameId = window.requestAnimationFrame(flushPanMove);
|
|
11654
12762
|
};
|
|
11655
12763
|
const handlePanEnd = () => {
|
|
11656
|
-
|
|
12764
|
+
const pan = panStateRef.current;
|
|
12765
|
+
if (!pan?.active) return;
|
|
12766
|
+
if (pan.frameId !== null) {
|
|
12767
|
+
window.cancelAnimationFrame(pan.frameId);
|
|
12768
|
+
}
|
|
11657
12769
|
panStateRef.current = null;
|
|
11658
12770
|
const container = scrollContainerRef.current;
|
|
11659
12771
|
if (container) container.style.cursor = "";
|
|
@@ -11665,19 +12777,19 @@ function TaskGanttChartInner(props, ref) {
|
|
|
11665
12777
|
window.removeEventListener("mouseup", handlePanEnd);
|
|
11666
12778
|
};
|
|
11667
12779
|
}, []);
|
|
11668
|
-
return /* @__PURE__ */
|
|
12780
|
+
return /* @__PURE__ */ jsx19(
|
|
11669
12781
|
"div",
|
|
11670
12782
|
{
|
|
11671
12783
|
ref: containerRef,
|
|
11672
|
-
className: isTableMatrixMode ? "gantt-container gantt-container-tableMatrix" : "gantt-container",
|
|
11673
|
-
children: /* @__PURE__ */
|
|
12784
|
+
className: isTableMatrixMode ? "gantt-container gantt-container-tableMatrix" : isPlanFactMode ? "gantt-container gantt-container-planFact" : "gantt-container",
|
|
12785
|
+
children: /* @__PURE__ */ jsx19(
|
|
11674
12786
|
"div",
|
|
11675
12787
|
{
|
|
11676
12788
|
ref: scrollContainerRef,
|
|
11677
12789
|
className: "gantt-scrollContainer",
|
|
11678
12790
|
style: { height: containerHeight ?? "auto", cursor: "grab" },
|
|
11679
12791
|
onMouseDown: handlePanStart,
|
|
11680
|
-
children: /* @__PURE__ */
|
|
12792
|
+
children: /* @__PURE__ */ jsxs15(
|
|
11681
12793
|
"div",
|
|
11682
12794
|
{
|
|
11683
12795
|
ref: scrollContentRef,
|
|
@@ -11685,7 +12797,7 @@ function TaskGanttChartInner(props, ref) {
|
|
|
11685
12797
|
onMouseOver: handleSharedRowHover,
|
|
11686
12798
|
onMouseLeave: clearHoveredRows,
|
|
11687
12799
|
children: [
|
|
11688
|
-
/* @__PURE__ */
|
|
12800
|
+
/* @__PURE__ */ jsx19(
|
|
11689
12801
|
TaskList,
|
|
11690
12802
|
{
|
|
11691
12803
|
tasks: normalizedTasks,
|
|
@@ -11738,17 +12850,17 @@ function TaskGanttChartInner(props, ref) {
|
|
|
11738
12850
|
visibleRowIndices: visibleTaskWindowIndices
|
|
11739
12851
|
}
|
|
11740
12852
|
),
|
|
11741
|
-
/* @__PURE__ */
|
|
12853
|
+
/* @__PURE__ */ jsx19(
|
|
11742
12854
|
"div",
|
|
11743
12855
|
{
|
|
11744
|
-
className: isTableMatrixMode || showChart ? "gantt-chartSurface" : "gantt-chartSurface gantt-chart-hidden",
|
|
12856
|
+
className: isTableMatrixMode || isPlanFactMode || showChart ? "gantt-chartSurface" : "gantt-chartSurface gantt-chart-hidden",
|
|
11745
12857
|
style: {
|
|
11746
|
-
minWidth: isTableMatrixMode ? matrixWidth !== void 0 ? `${matrixWidth}px` : void 0 : `${gridWidth}px`,
|
|
11747
|
-
width: isTableMatrixMode ? matrixWidth !== void 0 ? `${matrixWidth}px` : "max-content" : void 0,
|
|
11748
|
-
flex: isTableMatrixMode ? "0 0 auto" : 1,
|
|
11749
|
-
display: isTableMatrixMode || showChart ? void 0 : "none"
|
|
12858
|
+
minWidth: isTableMatrixMode ? matrixWidth !== void 0 ? `${matrixWidth}px` : void 0 : isPlanFactMode ? `${gridWidth}px` : `${gridWidth}px`,
|
|
12859
|
+
width: isTableMatrixMode ? matrixWidth !== void 0 ? `${matrixWidth}px` : "max-content" : isPlanFactMode ? `${gridWidth}px` : void 0,
|
|
12860
|
+
flex: isTableMatrixMode || isPlanFactMode ? "0 0 auto" : 1,
|
|
12861
|
+
display: isTableMatrixMode || isPlanFactMode || showChart ? void 0 : "none"
|
|
11750
12862
|
},
|
|
11751
|
-
children: isTableMatrixMode ? /* @__PURE__ */
|
|
12863
|
+
children: isTableMatrixMode ? /* @__PURE__ */ jsx19(
|
|
11752
12864
|
TableMatrix,
|
|
11753
12865
|
{
|
|
11754
12866
|
tasks: visibleTasks,
|
|
@@ -11765,14 +12877,34 @@ function TaskGanttChartInner(props, ref) {
|
|
|
11765
12877
|
highlightedTaskIds: taskListHighlightedTaskIds,
|
|
11766
12878
|
filterMode
|
|
11767
12879
|
}
|
|
11768
|
-
) : /* @__PURE__ */
|
|
11769
|
-
|
|
12880
|
+
) : isPlanFactMode ? /* @__PURE__ */ jsx19(
|
|
12881
|
+
PlanFactMatrix,
|
|
12882
|
+
{
|
|
12883
|
+
tasks: visibleTasks,
|
|
12884
|
+
allTasks: normalizedTasks,
|
|
12885
|
+
dateRange,
|
|
12886
|
+
dayWidth,
|
|
12887
|
+
rowHeight: effectiveRowHeight,
|
|
12888
|
+
headerHeight: timelineHeaderHeight,
|
|
12889
|
+
bodyMinHeight: tableBodyMinHeight,
|
|
12890
|
+
selectedTaskId,
|
|
12891
|
+
onTaskSelect: handleTaskSelect,
|
|
12892
|
+
onTasksChange: handleTaskChange,
|
|
12893
|
+
onCellCommit: onPlanFactCellCommit,
|
|
12894
|
+
highlightedTaskIds: taskListHighlightedTaskIds,
|
|
12895
|
+
filterMode,
|
|
12896
|
+
visibleRowIndices: visibleTaskWindowIndices,
|
|
12897
|
+
visibleDateIndices: visiblePlanFactDateIndices,
|
|
12898
|
+
todayDateIndex: todayInRange ? todayIndex : void 0
|
|
12899
|
+
}
|
|
12900
|
+
) : /* @__PURE__ */ jsxs15(Fragment4, { children: [
|
|
12901
|
+
/* @__PURE__ */ jsxs15(
|
|
11770
12902
|
"div",
|
|
11771
12903
|
{
|
|
11772
12904
|
className: "gantt-stickyHeader",
|
|
11773
12905
|
style: { width: `${gridWidth}px`, height: `${timelineHeaderHeight}px` },
|
|
11774
12906
|
children: [
|
|
11775
|
-
/* @__PURE__ */
|
|
12907
|
+
/* @__PURE__ */ jsx19(
|
|
11776
12908
|
TimeScaleHeader_default,
|
|
11777
12909
|
{
|
|
11778
12910
|
days: dateRange,
|
|
@@ -11785,7 +12917,7 @@ function TaskGanttChartInner(props, ref) {
|
|
|
11785
12917
|
onTimelineHoverEnd: () => setActiveTimelineTooltip(null)
|
|
11786
12918
|
}
|
|
11787
12919
|
),
|
|
11788
|
-
activeTimelineTooltip && /* @__PURE__ */
|
|
12920
|
+
activeTimelineTooltip && /* @__PURE__ */ jsx19("div", { className: "gantt-timelineTooltipLayer", "aria-hidden": "true", children: /* @__PURE__ */ jsx19(
|
|
11789
12921
|
"div",
|
|
11790
12922
|
{
|
|
11791
12923
|
className: "gantt-timelineTooltip",
|
|
@@ -11799,7 +12931,7 @@ function TaskGanttChartInner(props, ref) {
|
|
|
11799
12931
|
]
|
|
11800
12932
|
}
|
|
11801
12933
|
),
|
|
11802
|
-
/* @__PURE__ */
|
|
12934
|
+
/* @__PURE__ */ jsxs15(
|
|
11803
12935
|
"div",
|
|
11804
12936
|
{
|
|
11805
12937
|
className: "gantt-taskArea",
|
|
@@ -11809,7 +12941,7 @@ function TaskGanttChartInner(props, ref) {
|
|
|
11809
12941
|
height: `${totalGridHeight}px`
|
|
11810
12942
|
},
|
|
11811
12943
|
children: [
|
|
11812
|
-
/* @__PURE__ */
|
|
12944
|
+
/* @__PURE__ */ jsx19(
|
|
11813
12945
|
GridBackground_default,
|
|
11814
12946
|
{
|
|
11815
12947
|
dateRange,
|
|
@@ -11819,7 +12951,7 @@ function TaskGanttChartInner(props, ref) {
|
|
|
11819
12951
|
isCustomWeekend
|
|
11820
12952
|
}
|
|
11821
12953
|
),
|
|
11822
|
-
todayInRange && /* @__PURE__ */
|
|
12954
|
+
todayInRange && /* @__PURE__ */ jsx19(
|
|
11823
12955
|
TodayIndicator_default,
|
|
11824
12956
|
{
|
|
11825
12957
|
monthStart,
|
|
@@ -11828,7 +12960,7 @@ function TaskGanttChartInner(props, ref) {
|
|
|
11828
12960
|
onHoverEnd: () => setActiveTimelineTooltip(null)
|
|
11829
12961
|
}
|
|
11830
12962
|
),
|
|
11831
|
-
visibleTimelineMarkers.length > 0 && /* @__PURE__ */
|
|
12963
|
+
visibleTimelineMarkers.length > 0 && /* @__PURE__ */ jsx19(
|
|
11832
12964
|
TimelineMarkers_default,
|
|
11833
12965
|
{
|
|
11834
12966
|
rangeStart: monthStart,
|
|
@@ -11839,7 +12971,7 @@ function TaskGanttChartInner(props, ref) {
|
|
|
11839
12971
|
onHoverEnd: () => setActiveTimelineTooltip(null)
|
|
11840
12972
|
}
|
|
11841
12973
|
),
|
|
11842
|
-
/* @__PURE__ */
|
|
12974
|
+
/* @__PURE__ */ jsx19(
|
|
11843
12975
|
DependencyLines_default,
|
|
11844
12976
|
{
|
|
11845
12977
|
tasks: renderedDependencyTasks,
|
|
@@ -11857,7 +12989,7 @@ function TaskGanttChartInner(props, ref) {
|
|
|
11857
12989
|
weekendPredicate: isCustomWeekend
|
|
11858
12990
|
}
|
|
11859
12991
|
),
|
|
11860
|
-
dragGuideLines && /* @__PURE__ */
|
|
12992
|
+
dragGuideLines && /* @__PURE__ */ jsx19(
|
|
11861
12993
|
DragGuideLines_default,
|
|
11862
12994
|
{
|
|
11863
12995
|
isDragging: dragGuideLines.isDragging,
|
|
@@ -11867,7 +12999,7 @@ function TaskGanttChartInner(props, ref) {
|
|
|
11867
12999
|
totalHeight: totalGridHeight
|
|
11868
13000
|
}
|
|
11869
13001
|
),
|
|
11870
|
-
renderedChartTasks.map(({ task, index }) => /* @__PURE__ */
|
|
13002
|
+
renderedChartTasks.map(({ task, index }) => /* @__PURE__ */ jsx19(
|
|
11871
13003
|
"div",
|
|
11872
13004
|
{
|
|
11873
13005
|
style: {
|
|
@@ -11877,7 +13009,7 @@ function TaskGanttChartInner(props, ref) {
|
|
|
11877
13009
|
right: 0,
|
|
11878
13010
|
height: `${effectiveRowHeight}px`
|
|
11879
13011
|
},
|
|
11880
|
-
children: /* @__PURE__ */
|
|
13012
|
+
children: /* @__PURE__ */ jsx19(
|
|
11881
13013
|
TaskRow_default,
|
|
11882
13014
|
{
|
|
11883
13015
|
task,
|
|
@@ -11933,9 +13065,9 @@ var GanttChart = forwardRef(GanttChartInner);
|
|
|
11933
13065
|
GanttChart.displayName = "GanttChart";
|
|
11934
13066
|
|
|
11935
13067
|
// src/components/ui/Button.tsx
|
|
11936
|
-
import
|
|
11937
|
-
import { jsx as
|
|
11938
|
-
var Button =
|
|
13068
|
+
import React17 from "react";
|
|
13069
|
+
import { jsx as jsx20 } from "react/jsx-runtime";
|
|
13070
|
+
var Button = React17.forwardRef(
|
|
11939
13071
|
({ className, variant = "default", size = "default", children, ...props }, ref) => {
|
|
11940
13072
|
const classes = [
|
|
11941
13073
|
"gantt-btn",
|
|
@@ -11943,7 +13075,7 @@ var Button = React16.forwardRef(
|
|
|
11943
13075
|
size !== "default" ? `gantt-btn-${size}` : "",
|
|
11944
13076
|
className || ""
|
|
11945
13077
|
].filter(Boolean).join(" ");
|
|
11946
|
-
return /* @__PURE__ */
|
|
13078
|
+
return /* @__PURE__ */ jsx20("button", { ref, className: classes, ...props, children });
|
|
11947
13079
|
}
|
|
11948
13080
|
);
|
|
11949
13081
|
Button.displayName = "Button";
|
|
@@ -11990,6 +13122,7 @@ export {
|
|
|
11990
13122
|
GanttChart,
|
|
11991
13123
|
GridBackground_default as GridBackground,
|
|
11992
13124
|
Input,
|
|
13125
|
+
PlanFactMatrix,
|
|
11993
13126
|
Popover,
|
|
11994
13127
|
PopoverContent,
|
|
11995
13128
|
PopoverTrigger,
|