gantt-lib 0.135.8 → 0.136.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/README.md +22 -0
- package/dist/core/scheduling/index.d.mts +1 -1
- package/dist/core/scheduling/index.d.ts +1 -1
- package/dist/{index-DR8Q6-de.d.mts → index-D99kbU4p.d.mts} +5 -0
- package/dist/{index-DR8Q6-de.d.ts → index-D99kbU4p.d.ts} +5 -0
- package/dist/index.css.map +1 -1
- package/dist/index.d.mts +20 -3
- package/dist/index.d.ts +20 -3
- package/dist/index.js +480 -155
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +674 -351
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +248 -24
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -42,6 +42,8 @@ __export(index_exports, {
|
|
|
42
42
|
GenerationSkeletonRows: () => GenerationSkeleton_default,
|
|
43
43
|
GridBackground: () => GridBackground_default,
|
|
44
44
|
Input: () => Input,
|
|
45
|
+
MIN_EDGE_ZONE_PX: () => MIN_EDGE_ZONE_PX,
|
|
46
|
+
MIN_MOVE_ZONE_PX: () => MIN_MOVE_ZONE_PX,
|
|
45
47
|
PlanFactMatrix: () => PlanFactMatrix,
|
|
46
48
|
Popover: () => Popover,
|
|
47
49
|
PopoverContent: () => PopoverContent,
|
|
@@ -3304,6 +3306,7 @@ var TimeScaleHeader_default = TimeScaleHeader;
|
|
|
3304
3306
|
|
|
3305
3307
|
// src/components/TaskRow/TaskRow.tsx
|
|
3306
3308
|
var import_react3 = __toESM(require("react"));
|
|
3309
|
+
var import_react_dom = require("react-dom");
|
|
3307
3310
|
|
|
3308
3311
|
// src/utils/geometry.ts
|
|
3309
3312
|
var getUTCDayDifference = (date1, date2) => {
|
|
@@ -3389,19 +3392,20 @@ var pixelsToDate = (pixels, monthStart, dayWidth) => {
|
|
|
3389
3392
|
var calculateGridWidth = (daysInMonth, dayWidth) => {
|
|
3390
3393
|
return Math.round(daysInMonth * dayWidth);
|
|
3391
3394
|
};
|
|
3395
|
+
var MIN_EDGE_ZONE_PX = 8;
|
|
3396
|
+
var MIN_MOVE_ZONE_PX = 16;
|
|
3392
3397
|
var detectEdgeZone = (clientX, taskBarElement, edgeZoneWidth = 12) => {
|
|
3393
3398
|
const rect = taskBarElement.getBoundingClientRect();
|
|
3394
3399
|
const relativeX = Math.round(clientX - rect.left);
|
|
3395
3400
|
const width = Math.round(rect.width);
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
|
|
3400
|
-
|
|
3401
|
-
if (relativeX >= 0 && relativeX <= edgeZoneWidth) {
|
|
3401
|
+
const effectiveZone = Math.max(
|
|
3402
|
+
MIN_EDGE_ZONE_PX,
|
|
3403
|
+
Math.min(edgeZoneWidth, (width - MIN_MOVE_ZONE_PX) / 2)
|
|
3404
|
+
);
|
|
3405
|
+
if (relativeX >= 0 && relativeX <= effectiveZone) {
|
|
3402
3406
|
return "left";
|
|
3403
3407
|
}
|
|
3404
|
-
if (relativeX >= width -
|
|
3408
|
+
if (relativeX >= width - effectiveZone && relativeX <= width) {
|
|
3405
3409
|
return "right";
|
|
3406
3410
|
}
|
|
3407
3411
|
return "move";
|
|
@@ -4021,8 +4025,7 @@ var useTaskDrag = (options) => {
|
|
|
4021
4025
|
locked = false,
|
|
4022
4026
|
disableTaskDrag = false,
|
|
4023
4027
|
businessDays = true,
|
|
4024
|
-
weekendPredicate
|
|
4025
|
-
viewMode = "day"
|
|
4028
|
+
weekendPredicate
|
|
4026
4029
|
} = options;
|
|
4027
4030
|
const rawHookTask = allTasks.find((t) => t.id === taskId);
|
|
4028
4031
|
const hookTask = rawHookTask ? normalizeTaskDatesForType(rawHookTask) : void 0;
|
|
@@ -4294,23 +4297,18 @@ var useTaskDrag = (options) => {
|
|
|
4294
4297
|
if (effectiveLocked) return;
|
|
4295
4298
|
const target = e.currentTarget;
|
|
4296
4299
|
const currentTask = allTasks.find((t) => t.id === taskId);
|
|
4297
|
-
const isSingleDayTask = !!currentTask && !isMilestoneTask(currentTask) && !isTaskParent(taskId, allTasks) && currentWidth <= dayWidth && viewMode === "day";
|
|
4298
4300
|
let mode = null;
|
|
4299
|
-
|
|
4300
|
-
|
|
4301
|
-
|
|
4302
|
-
|
|
4303
|
-
|
|
4304
|
-
|
|
4305
|
-
|
|
4306
|
-
|
|
4307
|
-
|
|
4308
|
-
|
|
4309
|
-
|
|
4310
|
-
case "move":
|
|
4311
|
-
mode = "move";
|
|
4312
|
-
break;
|
|
4313
|
-
}
|
|
4301
|
+
const edgeZone = detectEdgeZone(e.clientX, target, edgeZoneWidth);
|
|
4302
|
+
switch (edgeZone) {
|
|
4303
|
+
case "left":
|
|
4304
|
+
mode = "resize-left";
|
|
4305
|
+
break;
|
|
4306
|
+
case "right":
|
|
4307
|
+
mode = "resize-right";
|
|
4308
|
+
break;
|
|
4309
|
+
case "move":
|
|
4310
|
+
mode = "move";
|
|
4311
|
+
break;
|
|
4314
4312
|
}
|
|
4315
4313
|
if (mode === "resize-left" || mode === "resize-right") {
|
|
4316
4314
|
if (currentTask && isMilestoneTask(currentTask)) {
|
|
@@ -4360,7 +4358,7 @@ var useTaskDrag = (options) => {
|
|
|
4360
4358
|
cascadeContext: shouldBuildCascadeContext ? createCascadeContext(allTasks) : void 0,
|
|
4361
4359
|
scheduleIntentMode: Boolean(onScheduleIntent)
|
|
4362
4360
|
};
|
|
4363
|
-
}, [edgeZoneWidth, currentLeft, currentWidth, dayWidth, monthStart, taskId, onDragStateChange, handleProgress, handleComplete, handleCancel, allTasks, disableConstraints, deferCascadePreview, onCascadeProgress, onCascade, effectiveLocked
|
|
4361
|
+
}, [edgeZoneWidth, currentLeft, currentWidth, dayWidth, monthStart, taskId, onDragStateChange, handleProgress, handleComplete, handleCancel, allTasks, disableConstraints, deferCascadePreview, onCascadeProgress, onCascade, effectiveLocked]);
|
|
4364
4362
|
const handleMouseDown = (0, import_react2.useCallback)((e) => {
|
|
4365
4363
|
startDrag(e);
|
|
4366
4364
|
}, [startDrag]);
|
|
@@ -4379,14 +4377,13 @@ var useTaskDrag = (options) => {
|
|
|
4379
4377
|
}
|
|
4380
4378
|
const target = e.currentTarget;
|
|
4381
4379
|
const currentTask = allTasks.find((t) => t.id === taskId);
|
|
4382
|
-
|
|
4383
|
-
if (isSingleDayTask || currentTask && isMilestoneTask(currentTask)) {
|
|
4380
|
+
if (currentTask && isMilestoneTask(currentTask)) {
|
|
4384
4381
|
setHoverCursor("grab");
|
|
4385
4382
|
return;
|
|
4386
4383
|
}
|
|
4387
4384
|
const edgeZone = detectEdgeZone(e.clientX, target, edgeZoneWidth);
|
|
4388
4385
|
setHoverCursor(edgeZone === "move" ? "grab" : "ew-resize");
|
|
4389
|
-
}, [disableTaskDrag, locked, isDragging, allTasks, taskId,
|
|
4386
|
+
}, [disableTaskDrag, locked, isDragging, allTasks, taskId, edgeZoneWidth]);
|
|
4390
4387
|
const handleMouseLeave = (0, import_react2.useCallback)(() => {
|
|
4391
4388
|
setHoverCursor(disableTaskDrag ? "grab" : locked ? "not-allowed" : isDragging ? "grabbing" : "grab");
|
|
4392
4389
|
}, [disableTaskDrag, locked, isDragging]);
|
|
@@ -4417,12 +4414,35 @@ var useTaskDrag = (options) => {
|
|
|
4417
4414
|
|
|
4418
4415
|
// src/components/TaskRow/TaskRow.tsx
|
|
4419
4416
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
4417
|
+
var formatCompositePreviewDate = (date) => {
|
|
4418
|
+
const month = new Intl.DateTimeFormat("ru-RU", { month: "short", timeZone: "UTC" }).format(date).replace(/\.$/, "");
|
|
4419
|
+
const yearSuffix = date.getUTCFullYear() === (/* @__PURE__ */ new Date()).getFullYear() ? "" : ` ${String(date.getUTCFullYear()).slice(-2)}`;
|
|
4420
|
+
return `${date.getUTCDate()} ${month}${yearSuffix}`;
|
|
4421
|
+
};
|
|
4420
4422
|
var arePropsEqual = (prevProps, nextProps) => {
|
|
4421
|
-
return prevProps.task.id === nextProps.task.id && prevProps.task.name === nextProps.task.name && prevProps.task.startDate === nextProps.task.startDate && prevProps.task.endDate === nextProps.task.endDate && prevProps.task.baselineStartDate === nextProps.task.baselineStartDate && prevProps.task.baselineEndDate === nextProps.task.baselineEndDate && prevProps.task.type === nextProps.task.type && prevProps.task.color === nextProps.task.color && prevProps.task.progress === nextProps.task.progress && prevProps.task.accepted === nextProps.task.accepted && prevProps.monthStart.getTime() === nextProps.monthStart.getTime() && prevProps.dayWidth === nextProps.dayWidth && prevProps.rowHeight === nextProps.rowHeight && prevProps.overridePosition?.left === nextProps.overridePosition?.left && prevProps.overridePosition?.width === nextProps.overridePosition?.width && prevProps.previewPositionStore === nextProps.previewPositionStore && prevProps.allTasks === nextProps.allTasks && prevProps.disableConstraints === nextProps.disableConstraints && prevProps.deferCascadePreview === nextProps.deferCascadePreview && prevProps.task.locked === nextProps.task.locked && prevProps.task.synced === nextProps.task.synced && prevProps.task.divider === nextProps.task.divider && prevProps.highlightExpiredTasks === nextProps.highlightExpiredTasks && prevProps.isCritical === nextProps.isCritical && prevProps.showBaseline === nextProps.showBaseline && prevProps.isFilterMatch === nextProps.isFilterMatch && prevProps.businessDays === nextProps.businessDays && prevProps.customDays === nextProps.customDays && prevProps.isWeekend === nextProps.isWeekend && prevProps.disableTaskDrag === nextProps.disableTaskDrag && prevProps.disableDependencyEditing === nextProps.disableDependencyEditing && prevProps.isDependencyDragActive === nextProps.isDependencyDragActive && prevProps.viewMode === nextProps.viewMode && prevProps.showTaskDateLabels === nextProps.showTaskDateLabels && prevProps.showTaskNames === nextProps.showTaskNames;
|
|
4423
|
+
return prevProps.task.id === nextProps.task.id && prevProps.task.name === nextProps.task.name && prevProps.task.startDate === nextProps.task.startDate && prevProps.task.endDate === nextProps.task.endDate && prevProps.task.baselineStartDate === nextProps.task.baselineStartDate && prevProps.task.baselineEndDate === nextProps.task.baselineEndDate && prevProps.task.type === nextProps.task.type && prevProps.task.color === nextProps.task.color && prevProps.task.progress === nextProps.task.progress && prevProps.task.accepted === nextProps.task.accepted && prevProps.monthStart.getTime() === nextProps.monthStart.getTime() && prevProps.dayWidth === nextProps.dayWidth && prevProps.rowHeight === nextProps.rowHeight && prevProps.overridePosition?.left === nextProps.overridePosition?.left && prevProps.overridePosition?.width === nextProps.overridePosition?.width && prevProps.previewPositionStore === nextProps.previewPositionStore && prevProps.allTasks === nextProps.allTasks && prevProps.disableConstraints === nextProps.disableConstraints && prevProps.deferCascadePreview === nextProps.deferCascadePreview && prevProps.task.locked === nextProps.task.locked && prevProps.task.synced === nextProps.task.synced && prevProps.task.divider === nextProps.task.divider && prevProps.highlightExpiredTasks === nextProps.highlightExpiredTasks && prevProps.isCritical === nextProps.isCritical && prevProps.showBaseline === nextProps.showBaseline && prevProps.onCompositeToggle === nextProps.onCompositeToggle && prevProps.compactDetail === nextProps.compactDetail && prevProps.compositeParentColor === nextProps.compositeParentColor && prevProps.compositeExpanded === nextProps.compositeExpanded && prevProps.isFilterMatch === nextProps.isFilterMatch && prevProps.businessDays === nextProps.businessDays && prevProps.customDays === nextProps.customDays && prevProps.isWeekend === nextProps.isWeekend && prevProps.disableTaskDrag === nextProps.disableTaskDrag && prevProps.disableDependencyEditing === nextProps.disableDependencyEditing && prevProps.isDependencyDragActive === nextProps.isDependencyDragActive && prevProps.viewMode === nextProps.viewMode && prevProps.showTaskDateLabels === nextProps.showTaskDateLabels && prevProps.showTaskNames === nextProps.showTaskNames;
|
|
4422
4424
|
};
|
|
4423
4425
|
var TaskRow = import_react3.default.memo(
|
|
4424
|
-
({ task, monthStart, dayWidth, rowHeight, onTasksChange, onScheduleIntent, onDragStateChange, rowIndex, allTasks, enableAutoSchedule, disableConstraints, deferCascadePreview = false, overridePosition, previewPositionStore, onCascadeProgress, onCascade, divider, highlightExpiredTasks, isCritical = false, showBaseline = false, isFilterMatch = false, businessDays, customDays, isWeekend: isWeekend3, disableTaskDrag = false, disableDependencyEditing = false, onDependencyPortPointerDown, isDependencyDragActive = false, viewMode = "day", showTaskDateLabels = true, showTaskNames = true }) => {
|
|
4426
|
+
({ task, monthStart, dayWidth, rowHeight, onTasksChange, onScheduleIntent, onDragStateChange, rowIndex, allTasks, enableAutoSchedule, disableConstraints, deferCascadePreview = false, overridePosition, previewPositionStore, onCascadeProgress, onCascade, divider, highlightExpiredTasks, isCritical = false, showBaseline = false, isFilterMatch = false, businessDays, customDays, isWeekend: isWeekend3, disableTaskDrag = false, disableDependencyEditing = false, onDependencyPortPointerDown, isDependencyDragActive = false, viewMode = "day", showTaskDateLabels = true, showTaskNames = true, onCompositeToggle, compactDetail = false, compositeParentColor, compositeExpanded = false }) => {
|
|
4425
4427
|
const defaultParentBarColor = "#782FC4";
|
|
4428
|
+
const [showCompositePreview, setShowCompositePreview] = (0, import_react3.useState)(false);
|
|
4429
|
+
const [compositePreviewPosition, setCompositePreviewPosition] = (0, import_react3.useState)(null);
|
|
4430
|
+
const pointerStart = (0, import_react3.useRef)(null);
|
|
4431
|
+
const suppressCompositeClick = (0, import_react3.useRef)(false);
|
|
4432
|
+
const compositeChildren = (0, import_react3.useMemo)(
|
|
4433
|
+
() => task.composite ? (allTasks ?? []).filter((child) => child.parentId === task.id) : [],
|
|
4434
|
+
[allTasks, task.composite, task.id]
|
|
4435
|
+
);
|
|
4436
|
+
(0, import_react3.useEffect)(() => {
|
|
4437
|
+
if (!showCompositePreview) return;
|
|
4438
|
+
const hide = () => setShowCompositePreview(false);
|
|
4439
|
+
window.addEventListener("scroll", hide, true);
|
|
4440
|
+
window.addEventListener("resize", hide);
|
|
4441
|
+
return () => {
|
|
4442
|
+
window.removeEventListener("scroll", hide, true);
|
|
4443
|
+
window.removeEventListener("resize", hide);
|
|
4444
|
+
};
|
|
4445
|
+
}, [showCompositePreview]);
|
|
4426
4446
|
const { divider: taskDivider } = task;
|
|
4427
4447
|
const normalizedTask = (0, import_react3.useMemo)(() => normalizeTaskDatesForType(task), [task]);
|
|
4428
4448
|
const milestone = (0, import_react3.useMemo)(() => isMilestoneTask(normalizedTask), [normalizedTask]);
|
|
@@ -4439,6 +4459,7 @@ var TaskRow = import_react3.default.memo(
|
|
|
4439
4459
|
const isParent = (0, import_react3.useMemo)(() => {
|
|
4440
4460
|
return allTasks ? isTaskParent(task.id, allTasks) : false;
|
|
4441
4461
|
}, [allTasks, task.id]);
|
|
4462
|
+
const isVisualParent = isParent && !task.composite;
|
|
4442
4463
|
const childCount = (0, import_react3.useMemo)(() => {
|
|
4443
4464
|
return allTasks ? getChildren(task.id, allTasks).length : 0;
|
|
4444
4465
|
}, [allTasks, task.id]);
|
|
@@ -4484,19 +4505,19 @@ var TaskRow = import_react3.default.memo(
|
|
|
4484
4505
|
if (isExpired) {
|
|
4485
4506
|
return "color-mix(in srgb, var(--gantt-expired-color) 40%, black)";
|
|
4486
4507
|
}
|
|
4487
|
-
const baseColor =
|
|
4508
|
+
const baseColor = isVisualParent ? task.color || defaultParentBarColor : task.color || "var(--gantt-task-bar-default-color)";
|
|
4488
4509
|
return `color-mix(in srgb, ${baseColor} 40%, black)`;
|
|
4489
|
-
}, [defaultParentBarColor, isCritical, isExpired,
|
|
4510
|
+
}, [defaultParentBarColor, isCritical, isExpired, isVisualParent, task.color]);
|
|
4490
4511
|
const barStyle = (0, import_react3.useMemo)(() => {
|
|
4491
4512
|
const parentBarColor = task.color || defaultParentBarColor;
|
|
4492
4513
|
if (isCritical && !isExpired) {
|
|
4493
4514
|
const c = criticalBarColor;
|
|
4494
|
-
if (
|
|
4515
|
+
if (isVisualParent) {
|
|
4495
4516
|
return { backgroundColor: c, "--gantt-parent-bar-color": c };
|
|
4496
4517
|
}
|
|
4497
4518
|
return { backgroundColor: c };
|
|
4498
4519
|
}
|
|
4499
|
-
if (
|
|
4520
|
+
if (isVisualParent) {
|
|
4500
4521
|
if (progressWidth >= 100) {
|
|
4501
4522
|
const c = isExpired ? "color-mix(in srgb, var(--gantt-expired-color) 40%, black)" : `color-mix(in srgb, ${parentBarColor} 40%, black)`;
|
|
4502
4523
|
return { backgroundColor: c, "--gantt-parent-bar-color": c };
|
|
@@ -4507,7 +4528,7 @@ var TaskRow = import_react3.default.memo(
|
|
|
4507
4528
|
return { backgroundColor: progressColor };
|
|
4508
4529
|
}
|
|
4509
4530
|
return { backgroundColor: barColor };
|
|
4510
|
-
}, [isCritical, defaultParentBarColor, isExpired,
|
|
4531
|
+
}, [isCritical, defaultParentBarColor, isExpired, isVisualParent, progressWidth, barColor, progressColor, task.color]);
|
|
4511
4532
|
const handleDragEnd = (result) => {
|
|
4512
4533
|
const updatedTask = {
|
|
4513
4534
|
...normalizedTask,
|
|
@@ -4581,6 +4602,25 @@ var TaskRow = import_react3.default.memo(
|
|
|
4581
4602
|
}, [displayLeft, dayWidth, milestoneGeometry.size]);
|
|
4582
4603
|
const visualLeft = milestone ? displayMilestoneGeometry.left : displayLeft;
|
|
4583
4604
|
const visualWidth = milestone ? displayMilestoneGeometry.size : displayWidth;
|
|
4605
|
+
const compositeSegments = (0, import_react3.useMemo)(() => {
|
|
4606
|
+
if (!task.composite || width <= 0) return [];
|
|
4607
|
+
const laneEnds = [];
|
|
4608
|
+
return compositeChildren.map((child) => {
|
|
4609
|
+
const segment = calculateTaskBar(parseUTCDate(child.startDate), parseUTCDate(child.endDate), monthStart, dayWidth);
|
|
4610
|
+
let lane = laneEnds.findIndex((end) => end <= segment.left);
|
|
4611
|
+
if (lane < 0) lane = laneEnds.length;
|
|
4612
|
+
laneEnds[lane] = segment.left + segment.width;
|
|
4613
|
+
return {
|
|
4614
|
+
id: child.id,
|
|
4615
|
+
name: child.name,
|
|
4616
|
+
left: (segment.left - left) / width * 100,
|
|
4617
|
+
width: segment.width / width * 100,
|
|
4618
|
+
lane
|
|
4619
|
+
};
|
|
4620
|
+
});
|
|
4621
|
+
}, [task.composite, compositeChildren, monthStart, dayWidth, left, width, displayLeft]);
|
|
4622
|
+
const compositeLaneCount = Math.max(1, ...compositeSegments.map((segment) => segment.lane + 1));
|
|
4623
|
+
const showCompositeSegments = task.composite && compositeSegments.length > 0 && visualWidth / compositeSegments.length >= 22;
|
|
4584
4624
|
const shouldRenderBaseline = showBaseline && baselineGeometry !== null;
|
|
4585
4625
|
const hasPreviewPosition = isDragging || effectiveOverridePosition !== void 0;
|
|
4586
4626
|
const currentStartDate = hasPreviewPosition ? pixelsToDate(displayLeft, monthStart, dayWidth) : taskStartDate;
|
|
@@ -4598,17 +4638,20 @@ var TaskRow = import_react3.default.memo(
|
|
|
4598
4638
|
if (lastDigit >= 2 && lastDigit <= 4) return `${count} \u0440\u0430\u0431\u043E\u0442\u044B`;
|
|
4599
4639
|
return `${count} \u0440\u0430\u0431\u043E\u0442`;
|
|
4600
4640
|
};
|
|
4601
|
-
const estimatedTextWidth =
|
|
4602
|
-
const showProgressInside = !milestone && progressWidth > 0 && displayWidth > estimatedTextWidth;
|
|
4603
|
-
const MIN_DURATION_WIDTH =
|
|
4604
|
-
const showDurationInside = !milestone && durationDays >= 2 && displayWidth > MIN_DURATION_WIDTH;
|
|
4641
|
+
const estimatedTextWidth = isVisualParent ? 120 : durationDays >= 10 ? 76 : 62;
|
|
4642
|
+
const showProgressInside = !milestone && progressWidth > 0 && displayWidth > (compactDetail ? 28 : estimatedTextWidth);
|
|
4643
|
+
const MIN_DURATION_WIDTH = isVisualParent ? 80 : task.composite ? 92 : 50;
|
|
4644
|
+
const showDurationInside = !compactDetail && !milestone && durationDays >= 2 && displayWidth > MIN_DURATION_WIDTH;
|
|
4605
4645
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
4606
4646
|
"div",
|
|
4607
4647
|
{
|
|
4608
4648
|
"data-filter-match": isFilterMatch ? "true" : "false",
|
|
4609
4649
|
"data-gantt-task-row-id": task.id,
|
|
4610
|
-
className: `gantt-tr-row ${isFilterMatch ? "gantt-tr-row-filter-match" : ""}`,
|
|
4611
|
-
style: {
|
|
4650
|
+
className: `gantt-tr-row ${compactDetail ? "gantt-tr-row-compositeDetail" : ""} ${isFilterMatch ? "gantt-tr-row-filter-match" : ""}`,
|
|
4651
|
+
style: {
|
|
4652
|
+
height: `${rowHeight}px`,
|
|
4653
|
+
"--gantt-tr-composite-detail-color": compositeParentColor ?? "var(--gantt-task-bar-default-color, #8b5cf6)"
|
|
4654
|
+
},
|
|
4612
4655
|
children: [
|
|
4613
4656
|
taskDivider === "top" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "gantt-tr-divider gantt-tr-divider-top" }),
|
|
4614
4657
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "gantt-tr-taskContainer", children: [
|
|
@@ -4626,7 +4669,11 @@ var TaskRow = import_react3.default.memo(
|
|
|
4626
4669
|
"div",
|
|
4627
4670
|
{
|
|
4628
4671
|
"data-taskbar": true,
|
|
4629
|
-
|
|
4672
|
+
role: task.composite ? "button" : void 0,
|
|
4673
|
+
tabIndex: task.composite ? 0 : void 0,
|
|
4674
|
+
"aria-label": task.composite ? `${task.name}: ${compositeExpanded ? "\u0441\u0432\u0435\u0440\u043D\u0443\u0442\u044C" : "\u0440\u0430\u0441\u043A\u0440\u044B\u0442\u044C"} \u0434\u0435\u0442\u0430\u043B\u0438` : void 0,
|
|
4675
|
+
"aria-expanded": task.composite ? compositeExpanded : void 0,
|
|
4676
|
+
className: `gantt-tr-taskBar ${isDragging ? "gantt-tr-dragging" : ""} ${task.locked ? "gantt-tr-locked" : ""} ${task.synced === false ? "gantt-tr-unsynced" : ""} ${isVisualParent ? "gantt-tr-parentBar" : ""} ${task.composite ? "gantt-tr-compositeBar" : ""} ${milestone ? "gantt-tr-milestone" : ""} ${isCritical ? "gantt-tr-critical" : ""}`,
|
|
4630
4677
|
style: {
|
|
4631
4678
|
left: `${visualLeft}px`,
|
|
4632
4679
|
...barStyle,
|
|
@@ -4636,14 +4683,57 @@ var TaskRow = import_react3.default.memo(
|
|
|
4636
4683
|
padding: 0
|
|
4637
4684
|
} : {
|
|
4638
4685
|
width: `${visualWidth}px`,
|
|
4639
|
-
height:
|
|
4686
|
+
height: compactDetail ? "18px" : isVisualParent ? "var(--gantt-parent-bar-height, 14px)" : "var(--gantt-task-bar-height)"
|
|
4640
4687
|
},
|
|
4641
4688
|
cursor: dragHandleProps.style.cursor,
|
|
4642
4689
|
userSelect: dragHandleProps.style.userSelect
|
|
4643
4690
|
},
|
|
4644
4691
|
onMouseDown: dragHandleProps.onMouseDown,
|
|
4645
4692
|
onMouseMove: dragHandleProps.onMouseMove,
|
|
4646
|
-
onMouseLeave:
|
|
4693
|
+
onMouseLeave: () => {
|
|
4694
|
+
dragHandleProps.onMouseLeave();
|
|
4695
|
+
setShowCompositePreview(false);
|
|
4696
|
+
},
|
|
4697
|
+
onMouseEnter: task.composite ? (event) => {
|
|
4698
|
+
const rect = event.currentTarget.getBoundingClientRect();
|
|
4699
|
+
const previewWidth = 220;
|
|
4700
|
+
const previewHeight = Math.min(340, 68 + Math.min(compositeChildren.length, 12) * 20);
|
|
4701
|
+
setCompositePreviewPosition({
|
|
4702
|
+
left: Math.max(8, Math.min(rect.left, window.innerWidth - previewWidth - 8)),
|
|
4703
|
+
top: rect.bottom + previewHeight + 8 < window.innerHeight ? rect.bottom + 6 : Math.max(8, rect.top - previewHeight - 6)
|
|
4704
|
+
});
|
|
4705
|
+
setShowCompositePreview(true);
|
|
4706
|
+
} : void 0,
|
|
4707
|
+
onMouseDownCapture: task.composite ? (event) => {
|
|
4708
|
+
suppressCompositeClick.current = Boolean(event.target.closest(".gantt-tr-resizeHandle"));
|
|
4709
|
+
pointerStart.current = { x: event.clientX, y: event.clientY };
|
|
4710
|
+
} : void 0,
|
|
4711
|
+
onMouseMoveCapture: task.composite ? (event) => {
|
|
4712
|
+
const start = pointerStart.current;
|
|
4713
|
+
if (start && Math.hypot(event.clientX - start.x, event.clientY - start.y) >= 4) {
|
|
4714
|
+
suppressCompositeClick.current = true;
|
|
4715
|
+
}
|
|
4716
|
+
} : void 0,
|
|
4717
|
+
onMouseUpCapture: task.composite ? (event) => {
|
|
4718
|
+
const start = pointerStart.current;
|
|
4719
|
+
if (start && Math.hypot(event.clientX - start.x, event.clientY - start.y) >= 4) {
|
|
4720
|
+
suppressCompositeClick.current = true;
|
|
4721
|
+
}
|
|
4722
|
+
pointerStart.current = null;
|
|
4723
|
+
} : void 0,
|
|
4724
|
+
onClick: task.composite ? () => {
|
|
4725
|
+
if (!isDragging && !suppressCompositeClick.current) {
|
|
4726
|
+
setShowCompositePreview(false);
|
|
4727
|
+
onCompositeToggle?.("click");
|
|
4728
|
+
}
|
|
4729
|
+
suppressCompositeClick.current = false;
|
|
4730
|
+
} : void 0,
|
|
4731
|
+
onKeyDown: task.composite ? (event) => {
|
|
4732
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
4733
|
+
event.preventDefault();
|
|
4734
|
+
onCompositeToggle?.("keyboard");
|
|
4735
|
+
}
|
|
4736
|
+
} : void 0,
|
|
4647
4737
|
children: [
|
|
4648
4738
|
!milestone && progressWidth > 0 && progressWidth < 100 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
4649
4739
|
"div",
|
|
@@ -4652,14 +4742,28 @@ var TaskRow = import_react3.default.memo(
|
|
|
4652
4742
|
style: {
|
|
4653
4743
|
width: `${progressWidth}%`,
|
|
4654
4744
|
backgroundColor: progressColor,
|
|
4655
|
-
...
|
|
4745
|
+
...isVisualParent && {
|
|
4656
4746
|
borderRadius: "var(--gantt-parent-bar-radius, 8px) 0 0 0"
|
|
4657
4747
|
}
|
|
4658
4748
|
}
|
|
4659
4749
|
}
|
|
4660
4750
|
),
|
|
4661
4751
|
!milestone && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "gantt-tr-resizeHandle gantt-tr-resizeHandleLeft" }),
|
|
4662
|
-
|
|
4752
|
+
showCompositeSegments && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "gantt-tr-compositeSegments", "aria-hidden": "true", children: compositeSegments.map((segment) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
4753
|
+
"span",
|
|
4754
|
+
{
|
|
4755
|
+
className: "gantt-tr-compositeSegment",
|
|
4756
|
+
style: {
|
|
4757
|
+
left: `${segment.left}%`,
|
|
4758
|
+
width: `${segment.width}%`,
|
|
4759
|
+
top: `${segment.lane / compositeLaneCount * 100}%`,
|
|
4760
|
+
height: `${100 / compositeLaneCount}%`
|
|
4761
|
+
}
|
|
4762
|
+
},
|
|
4763
|
+
segment.id
|
|
4764
|
+
)) }),
|
|
4765
|
+
task.composite && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "gantt-tr-compositeHoverChevron", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { className: `gantt-tr-compositeChevron${compositeExpanded ? " gantt-tr-compositeChevron-open" : ""}`, viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m7 4 6 6-6 6", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }) }),
|
|
4766
|
+
showDurationInside && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "gantt-tr-taskDuration", children: isVisualParent ? getChildCountLabel(childCount) : `${durationDays} \u0434` }),
|
|
4663
4767
|
progressWidth > 0 && showProgressInside && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "gantt-tr-progressText", children: [
|
|
4664
4768
|
progressWidth,
|
|
4665
4769
|
"%"
|
|
@@ -4668,6 +4772,41 @@ var TaskRow = import_react3.default.memo(
|
|
|
4668
4772
|
]
|
|
4669
4773
|
}
|
|
4670
4774
|
),
|
|
4775
|
+
task.composite && showCompositePreview && compositePreviewPosition && compositeChildren.length > 0 && !isDragging && typeof document !== "undefined" && (0, import_react_dom.createPortal)(
|
|
4776
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
4777
|
+
"div",
|
|
4778
|
+
{
|
|
4779
|
+
className: "gantt-tr-compositePreview",
|
|
4780
|
+
style: { left: `${compositePreviewPosition.left}px`, top: `${compositePreviewPosition.top}px` },
|
|
4781
|
+
role: "tooltip",
|
|
4782
|
+
children: [
|
|
4783
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "gantt-tr-compositePreviewAxis", children: [
|
|
4784
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: formatCompositePreviewDate(currentStartDate) }),
|
|
4785
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: formatCompositePreviewDate(currentEndDate) })
|
|
4786
|
+
] }),
|
|
4787
|
+
compositeChildren.slice(0, 12).map((child) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "gantt-tr-compositePreviewRow", children: [
|
|
4788
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: child.name }),
|
|
4789
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "gantt-tr-compositePreviewTrack", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
4790
|
+
"span",
|
|
4791
|
+
{
|
|
4792
|
+
className: "gantt-tr-compositePreviewBar",
|
|
4793
|
+
style: {
|
|
4794
|
+
left: `${Math.max(0, (parseUTCDate(child.startDate).getTime() - taskStartDate.getTime()) / (taskEndDate.getTime() - taskStartDate.getTime() + 864e5) * 100)}%`,
|
|
4795
|
+
width: `${Math.max(2, (parseUTCDate(child.endDate).getTime() - parseUTCDate(child.startDate).getTime() + 864e5) / (taskEndDate.getTime() - taskStartDate.getTime() + 864e5) * 100)}%`,
|
|
4796
|
+
backgroundColor: barColor
|
|
4797
|
+
}
|
|
4798
|
+
}
|
|
4799
|
+
) })
|
|
4800
|
+
] }, child.id)),
|
|
4801
|
+
compositeChildren.length > 12 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
|
|
4802
|
+
"+",
|
|
4803
|
+
compositeChildren.length - 12
|
|
4804
|
+
] })
|
|
4805
|
+
]
|
|
4806
|
+
}
|
|
4807
|
+
),
|
|
4808
|
+
document.body
|
|
4809
|
+
),
|
|
4671
4810
|
!disableDependencyEditing && onDependencyPortPointerDown && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
4672
4811
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
4673
4812
|
"button",
|
|
@@ -4676,8 +4815,8 @@ var TaskRow = import_react3.default.memo(
|
|
|
4676
4815
|
"data-gantt-dependency-port": true,
|
|
4677
4816
|
"data-task-id": task.id,
|
|
4678
4817
|
"data-port-side": "left",
|
|
4679
|
-
className: `gantt-tr-dependencyPort gantt-tr-dependencyPortLeft ${milestone ? "gantt-tr-dependencyPortMilestone" : ""} ${
|
|
4680
|
-
style: { left: `${visualLeft -
|
|
4818
|
+
className: `gantt-tr-dependencyPort gantt-tr-dependencyPortLeft ${milestone ? "gantt-tr-dependencyPortMilestone" : ""} ${isVisualParent ? "gantt-tr-dependencyPortParent" : ""} ${isDependencyDragActive ? "gantt-tr-dependencyPortDragActive" : ""}`,
|
|
4819
|
+
style: { left: `${visualLeft - 24}px` },
|
|
4681
4820
|
"aria-label": `\u041D\u0430\u0447\u0430\u0442\u044C \u0441\u0432\u044F\u0437\u044C \u043E\u0442 \u043B\u0435\u0432\u043E\u0433\u043E \u043A\u0440\u0430\u044F: ${task.name}`,
|
|
4682
4821
|
title: "\u041F\u043E\u0442\u044F\u043D\u0438\u0442\u0435 \u043A \u043A\u0440\u0430\u044E \u0434\u0440\u0443\u0433\u043E\u0439 \u043F\u043E\u043B\u043E\u0441\u044B, \u0447\u0442\u043E\u0431\u044B \u0441\u043E\u0437\u0434\u0430\u0442\u044C \u0441\u0432\u044F\u0437\u044C",
|
|
4683
4822
|
onPointerDown: (event) => onDependencyPortPointerDown(task.id, "left", event)
|
|
@@ -4690,7 +4829,7 @@ var TaskRow = import_react3.default.memo(
|
|
|
4690
4829
|
"data-gantt-dependency-port": true,
|
|
4691
4830
|
"data-task-id": task.id,
|
|
4692
4831
|
"data-port-side": "right",
|
|
4693
|
-
className: `gantt-tr-dependencyPort gantt-tr-dependencyPortRight ${milestone ? "gantt-tr-dependencyPortMilestone" : ""} ${
|
|
4832
|
+
className: `gantt-tr-dependencyPort gantt-tr-dependencyPortRight ${milestone ? "gantt-tr-dependencyPortMilestone" : ""} ${isVisualParent ? "gantt-tr-dependencyPortParent" : ""} ${isDependencyDragActive ? "gantt-tr-dependencyPortDragActive" : ""}`,
|
|
4694
4833
|
style: { left: `${visualLeft + visualWidth}px` },
|
|
4695
4834
|
"aria-label": `\u041D\u0430\u0447\u0430\u0442\u044C \u0441\u0432\u044F\u0437\u044C \u043E\u0442 \u043F\u0440\u0430\u0432\u043E\u0433\u043E \u043A\u0440\u0430\u044F: ${task.name}`,
|
|
4696
4835
|
title: "\u041F\u043E\u0442\u044F\u043D\u0438\u0442\u0435 \u043A \u043A\u0440\u0430\u044E \u0434\u0440\u0443\u0433\u043E\u0439 \u043F\u043E\u043B\u043E\u0441\u044B, \u0447\u0442\u043E\u0431\u044B \u0441\u043E\u0437\u0434\u0430\u0442\u044C \u0441\u0432\u044F\u0437\u044C",
|
|
@@ -4729,6 +4868,14 @@ var TaskRow = import_react3.default.memo(
|
|
|
4729
4868
|
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zM12 17c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zm3.1-9H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2z" })
|
|
4730
4869
|
}
|
|
4731
4870
|
),
|
|
4871
|
+
!showDurationInside && !milestone && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
4872
|
+
"span",
|
|
4873
|
+
{
|
|
4874
|
+
className: `gantt-tr-externalDuration gantt-tr-durationBeforeBar${compactDetail ? " gantt-tr-compositeDuration" : ""}`,
|
|
4875
|
+
style: { left: `${visualLeft - 46}px`, color: isParent ? task.color || defaultParentBarColor : barColor },
|
|
4876
|
+
children: isVisualParent ? getChildCountLabel(childCount) : `${durationDays} \u0434`
|
|
4877
|
+
}
|
|
4878
|
+
),
|
|
4732
4879
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
4733
4880
|
"div",
|
|
4734
4881
|
{
|
|
@@ -4738,7 +4885,6 @@ var TaskRow = import_react3.default.memo(
|
|
|
4738
4885
|
color: isParent ? task.color || defaultParentBarColor : barColor
|
|
4739
4886
|
},
|
|
4740
4887
|
children: [
|
|
4741
|
-
!showDurationInside && !milestone && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "gantt-tr-externalDuration", children: isParent ? getChildCountLabel(childCount) : `${durationDays} \u0434` }),
|
|
4742
4888
|
progressWidth > 0 && !showProgressInside && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "gantt-tr-externalProgress", children: [
|
|
4743
4889
|
progressWidth,
|
|
4744
4890
|
"%"
|
|
@@ -5042,6 +5188,8 @@ var DependencyLines = import_react7.default.memo(({
|
|
|
5042
5188
|
gridWidth,
|
|
5043
5189
|
totalHeight,
|
|
5044
5190
|
rowIndexByTaskId,
|
|
5191
|
+
rowTops,
|
|
5192
|
+
rowHeights,
|
|
5045
5193
|
dragOverrides,
|
|
5046
5194
|
selectedDep,
|
|
5047
5195
|
criticalTaskIds,
|
|
@@ -5065,7 +5213,8 @@ var DependencyLines = import_react7.default.memo(({
|
|
|
5065
5213
|
left: computed.left,
|
|
5066
5214
|
right: computed.right,
|
|
5067
5215
|
centerX: computed.centerX,
|
|
5068
|
-
rowTop: rowIndex * rowHeight,
|
|
5216
|
+
rowTop: rowTops?.[rowIndex] ?? rowIndex * rowHeight,
|
|
5217
|
+
rowHeight: rowHeights?.[rowIndex] ?? rowHeight,
|
|
5069
5218
|
isVirtual: false
|
|
5070
5219
|
});
|
|
5071
5220
|
});
|
|
@@ -5085,6 +5234,7 @@ var DependencyLines = import_react7.default.memo(({
|
|
|
5085
5234
|
right: computed.right,
|
|
5086
5235
|
centerX: computed.centerX,
|
|
5087
5236
|
rowTop: ancestorPosition.rowTop,
|
|
5237
|
+
rowHeight: ancestorPosition.rowHeight,
|
|
5088
5238
|
isVirtual: true
|
|
5089
5239
|
});
|
|
5090
5240
|
}
|
|
@@ -5098,18 +5248,19 @@ var DependencyLines = import_react7.default.memo(({
|
|
|
5098
5248
|
const override = dragOverrides?.get(task.id);
|
|
5099
5249
|
const computed = resolveTaskHorizontalGeometry(task, monthStart, dayWidth, override);
|
|
5100
5250
|
const rowIndex = rowIndexByTaskId?.get(task.id);
|
|
5101
|
-
const rowTop = rowIndex !== void 0 ? rowIndex * rowHeight : 0;
|
|
5251
|
+
const rowTop = rowIndex !== void 0 ? rowTops?.[rowIndex] ?? rowIndex * rowHeight : 0;
|
|
5102
5252
|
positions.set(task.id, {
|
|
5103
5253
|
left: computed.left,
|
|
5104
5254
|
right: computed.right,
|
|
5105
5255
|
centerX: computed.centerX,
|
|
5106
5256
|
rowTop,
|
|
5257
|
+
rowHeight: rowIndex !== void 0 ? rowHeights?.[rowIndex] ?? rowHeight : rowHeight,
|
|
5107
5258
|
isVirtual: false
|
|
5108
5259
|
});
|
|
5109
5260
|
}
|
|
5110
5261
|
}
|
|
5111
5262
|
return { taskPositions: positions, taskIndices: indices, hiddenTaskIds: hidden };
|
|
5112
|
-
}, [tasks, tasksForPositions, allTasks, collapsedParentIds, monthStart, dayWidth, rowHeight, dragOverrides, rowIndexByTaskId]);
|
|
5263
|
+
}, [tasks, tasksForPositions, allTasks, collapsedParentIds, monthStart, dayWidth, rowHeight, rowTops, rowHeights, dragOverrides, rowIndexByTaskId]);
|
|
5113
5264
|
const tasksForCycleDetection = allTasks ?? tasks;
|
|
5114
5265
|
const cycleInfo = (0, import_react7.useMemo)(() => {
|
|
5115
5266
|
const result = detectCycles(tasksForCycleDetection);
|
|
@@ -5151,7 +5302,9 @@ var DependencyLines = import_react7.default.memo(({
|
|
|
5151
5302
|
continue;
|
|
5152
5303
|
}
|
|
5153
5304
|
}
|
|
5154
|
-
|
|
5305
|
+
const predecessorVisibleId = predecessor.isVirtual ? findVisibleAncestor(taskMap.get(edge.predecessorId), collapsedParentIds, taskMap)?.id : edge.predecessorId;
|
|
5306
|
+
const successorVisibleId = successor.isVirtual ? findVisibleAncestor(taskMap.get(edge.successorId), collapsedParentIds, taskMap)?.id : edge.successorId;
|
|
5307
|
+
if (!renderedTaskIdSet.has(predecessorVisibleId ?? "") && !renderedTaskIdSet.has(successorVisibleId ?? "")) {
|
|
5155
5308
|
continue;
|
|
5156
5309
|
}
|
|
5157
5310
|
const isVirtual = predecessor.isVirtual || successor.isVirtual;
|
|
@@ -5165,9 +5318,9 @@ var DependencyLines = import_react7.default.memo(({
|
|
|
5165
5318
|
let toY;
|
|
5166
5319
|
if (reverseOrder) {
|
|
5167
5320
|
fromY = predecessor.rowTop + 10;
|
|
5168
|
-
toY = successor.rowTop + rowHeight - 6;
|
|
5321
|
+
toY = successor.rowTop + successor.rowHeight - 6;
|
|
5169
5322
|
} else {
|
|
5170
|
-
fromY = predecessor.rowTop + rowHeight - 10;
|
|
5323
|
+
fromY = predecessor.rowTop + predecessor.rowHeight - 10;
|
|
5171
5324
|
toY = successor.rowTop + 6;
|
|
5172
5325
|
}
|
|
5173
5326
|
let fromX = predecessorTask && isMilestoneTask(predecessorTask) ? predecessor.centerX : edge.type === "SS" || edge.type === "SF" ? predecessor.left : predecessor.right;
|
|
@@ -5394,18 +5547,18 @@ var LINK_TYPE_LABELS_RU = {
|
|
|
5394
5547
|
FF: "\u041E\u041E",
|
|
5395
5548
|
SF: "\u041D\u041E"
|
|
5396
5549
|
};
|
|
5550
|
+
var fmt = (n) => Math.round(n * 100) / 100;
|
|
5397
5551
|
function getPath(drag) {
|
|
5398
5552
|
const from = drag.source;
|
|
5399
5553
|
const to = drag.current;
|
|
5400
5554
|
const direction = to.y >= from.y ? 1 : -1;
|
|
5401
5555
|
const bend = Math.max(18, Math.abs(to.y - from.y) * 0.45);
|
|
5402
|
-
const middleX = Math.round((from.x + to.x) / 2);
|
|
5403
5556
|
if (Math.abs(to.y - from.y) < 2) {
|
|
5404
|
-
return `M ${
|
|
5557
|
+
return `M ${fmt(from.x)} ${fmt(from.y)} H ${fmt(to.x)}`;
|
|
5405
5558
|
}
|
|
5406
5559
|
return [
|
|
5407
|
-
`M ${
|
|
5408
|
-
`C ${
|
|
5560
|
+
`M ${fmt(from.x)} ${fmt(from.y)}`,
|
|
5561
|
+
`C ${fmt(from.x)} ${fmt(from.y + bend * direction)}, ${fmt(to.x)} ${fmt(to.y - bend * direction)}, ${fmt(to.x)} ${fmt(to.y)}`
|
|
5409
5562
|
].join(" ");
|
|
5410
5563
|
}
|
|
5411
5564
|
var DependencyCreationOverlay = ({ drag, width, height }) => {
|
|
@@ -6845,6 +6998,7 @@ var TaskListRow = import_react11.default.memo(
|
|
|
6845
6998
|
taskListMenuCommands = [],
|
|
6846
6999
|
hideTaskListRowActions = false,
|
|
6847
7000
|
rowClassName,
|
|
7001
|
+
compositeParentColor,
|
|
6848
7002
|
getTaskListNamePrefixIcon,
|
|
6849
7003
|
taskDateChangeMode = "preserve-duration",
|
|
6850
7004
|
onTaskDateChangeModeChange,
|
|
@@ -6929,6 +7083,35 @@ var TaskListRow = import_react11.default.memo(
|
|
|
6929
7083
|
[businessDays, weekendPredicate]
|
|
6930
7084
|
);
|
|
6931
7085
|
const isCollapsed = collapsedParentIds.has(task.id);
|
|
7086
|
+
const [compositeIconMode, setCompositeIconMode] = (0, import_react11.useState)(
|
|
7087
|
+
() => isCollapsed ? "composite" : "down"
|
|
7088
|
+
);
|
|
7089
|
+
const compositeIconModeRef = (0, import_react11.useRef)(compositeIconMode);
|
|
7090
|
+
const [compositeIconAnimation, setCompositeIconAnimation] = (0, import_react11.useState)(null);
|
|
7091
|
+
const [compositeIconAnimationPhase, setCompositeIconAnimationPhase] = (0, import_react11.useState)(null);
|
|
7092
|
+
(0, import_react11.useEffect)(() => {
|
|
7093
|
+
const nextMode = isCollapsed ? "composite" : "down";
|
|
7094
|
+
if (nextMode === compositeIconModeRef.current) {
|
|
7095
|
+
setCompositeIconAnimation(null);
|
|
7096
|
+
setCompositeIconAnimationPhase(null);
|
|
7097
|
+
return;
|
|
7098
|
+
}
|
|
7099
|
+
setCompositeIconAnimation(isCollapsed ? "closing" : "opening");
|
|
7100
|
+
setCompositeIconAnimationPhase("outgoing");
|
|
7101
|
+
const swapTimeoutId = window.setTimeout(() => {
|
|
7102
|
+
compositeIconModeRef.current = nextMode;
|
|
7103
|
+
setCompositeIconMode(nextMode);
|
|
7104
|
+
setCompositeIconAnimationPhase("incoming");
|
|
7105
|
+
}, 120);
|
|
7106
|
+
const finishTimeoutId = window.setTimeout(() => {
|
|
7107
|
+
setCompositeIconAnimation(null);
|
|
7108
|
+
setCompositeIconAnimationPhase(null);
|
|
7109
|
+
}, 240);
|
|
7110
|
+
return () => {
|
|
7111
|
+
window.clearTimeout(swapTimeoutId);
|
|
7112
|
+
window.clearTimeout(finishTimeoutId);
|
|
7113
|
+
};
|
|
7114
|
+
}, [isCollapsed]);
|
|
6932
7115
|
const getHierarchyLineColor = (0, import_react11.useCallback)((columnDepth) => {
|
|
6933
7116
|
return columnDepth % 2 === 0 ? "#93c5fd" : "var(--gantt-hierarchy-line-color)";
|
|
6934
7117
|
}, []);
|
|
@@ -7037,6 +7220,7 @@ var TaskListRow = import_react11.default.memo(
|
|
|
7037
7220
|
);
|
|
7038
7221
|
const handleNameDoubleClick = (0, import_react11.useCallback)(
|
|
7039
7222
|
(e) => {
|
|
7223
|
+
if (task.composite) return;
|
|
7040
7224
|
if (disableTaskNameEditing) return;
|
|
7041
7225
|
e.stopPropagation();
|
|
7042
7226
|
nameConfirmedRef.current = false;
|
|
@@ -7044,7 +7228,7 @@ var TaskListRow = import_react11.default.memo(
|
|
|
7044
7228
|
setNameValue(task.name);
|
|
7045
7229
|
setEditingColumnId("name");
|
|
7046
7230
|
},
|
|
7047
|
-
[task.name, disableTaskNameEditing]
|
|
7231
|
+
[task.name, task.composite, disableTaskNameEditing]
|
|
7048
7232
|
);
|
|
7049
7233
|
const handleRowKeyDown = (0, import_react11.useCallback)(
|
|
7050
7234
|
(e) => {
|
|
@@ -7693,7 +7877,7 @@ var TaskListRow = import_react11.default.memo(
|
|
|
7693
7877
|
]
|
|
7694
7878
|
}
|
|
7695
7879
|
);
|
|
7696
|
-
const nameTriggerPaddingLeft = isParent ? `${nestingDepth * 20 + 28}px` : nestingDepth > 0 ? `${nestingDepth * 20 + 8}px` : void 0;
|
|
7880
|
+
const nameTriggerPaddingLeft = isParent && !task.composite ? `${nestingDepth * 20 + 28}px` : nestingDepth > 0 ? `${nestingDepth * 20 + 8}px` : void 0;
|
|
7697
7881
|
const nameInputPaddingLeft = nestingDepth > 0 ? `${nestingDepth * 20 + 8}px` : void 0;
|
|
7698
7882
|
const nestedDropIndicatorLeft = (() => {
|
|
7699
7883
|
const numberColumnWidth = resolvedColumns?.find((col) => col.id === "number")?.width ?? 40;
|
|
@@ -7791,36 +7975,35 @@ var TaskListRow = import_react11.default.memo(
|
|
|
7791
7975
|
}
|
|
7792
7976
|
)
|
|
7793
7977
|
] }),
|
|
7794
|
-
|
|
7795
|
-
|
|
7796
|
-
|
|
7797
|
-
|
|
7798
|
-
|
|
7799
|
-
|
|
7800
|
-
|
|
7801
|
-
|
|
7802
|
-
|
|
7803
|
-
|
|
7804
|
-
|
|
7805
|
-
|
|
7806
|
-
|
|
7807
|
-
}
|
|
7808
|
-
}
|
|
7809
|
-
),
|
|
7810
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
7811
|
-
"button",
|
|
7812
|
-
{
|
|
7813
|
-
type: "button",
|
|
7814
|
-
className: `gantt-tl-collapse-btn ${isCollapsed ? "gantt-tl-collapse-btn-collapsed" : ""}`,
|
|
7815
|
-
onClick: handleToggleCollapse,
|
|
7816
|
-
style: { left: `${nestingDepth * 20 + 1}px` },
|
|
7817
|
-
"aria-label": isCollapsed ? "Expand children" : "Collapse children",
|
|
7818
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ChevronRightIcon, {})
|
|
7978
|
+
task.composite && !isFilterHideMode && !isCollapsed && !editingName && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
7979
|
+
"span",
|
|
7980
|
+
{
|
|
7981
|
+
"data-testid": "gantt-tl-parent-connector-tail",
|
|
7982
|
+
style: {
|
|
7983
|
+
position: "absolute",
|
|
7984
|
+
left: `${nestingDepth * 20 + 9}px`,
|
|
7985
|
+
top: `${rowHeight / 2 + 7}px`,
|
|
7986
|
+
height: `${rowHeight / 2 - 7}px`,
|
|
7987
|
+
width: "1.5px",
|
|
7988
|
+
background: getHierarchyLineColor(nestingDepth),
|
|
7989
|
+
borderRadius: "1px",
|
|
7990
|
+
pointerEvents: "none"
|
|
7819
7991
|
}
|
|
7820
|
-
|
|
7821
|
-
|
|
7992
|
+
}
|
|
7993
|
+
),
|
|
7994
|
+
isParent && !task.composite && !editingName && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_jsx_runtime14.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
7995
|
+
"button",
|
|
7996
|
+
{
|
|
7997
|
+
type: "button",
|
|
7998
|
+
className: `gantt-tl-collapse-btn ${isCollapsed ? "gantt-tl-collapse-btn-collapsed" : ""}`,
|
|
7999
|
+
onClick: handleToggleCollapse,
|
|
8000
|
+
style: { left: `${nestingDepth * 20 - 2}px` },
|
|
8001
|
+
"aria-label": isCollapsed ? "Expand children" : "Collapse children",
|
|
8002
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ChevronRightIcon, {})
|
|
8003
|
+
}
|
|
8004
|
+
) })
|
|
7822
8005
|
] }),
|
|
7823
|
-
!isChild && isParent && !editingName && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
|
|
8006
|
+
!isChild && isParent && !task.composite && !editingName && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
|
|
7824
8007
|
!isFilterHideMode && !isCollapsed && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
7825
8008
|
"span",
|
|
7826
8009
|
{
|
|
@@ -7843,7 +8026,7 @@ var TaskListRow = import_react11.default.memo(
|
|
|
7843
8026
|
type: "button",
|
|
7844
8027
|
className: `gantt-tl-collapse-btn ${isCollapsed ? "gantt-tl-collapse-btn-collapsed" : ""}`,
|
|
7845
8028
|
onClick: handleToggleCollapse,
|
|
7846
|
-
style: { left: `${nestingDepth * 20
|
|
8029
|
+
style: { left: `${nestingDepth * 20 - 2}px` },
|
|
7847
8030
|
"aria-label": isCollapsed ? "Expand children" : "Collapse children",
|
|
7848
8031
|
children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ChevronRightIcon, {})
|
|
7849
8032
|
}
|
|
@@ -7862,27 +8045,57 @@ var TaskListRow = import_react11.default.memo(
|
|
|
7862
8045
|
style: { paddingLeft: nameInputPaddingLeft },
|
|
7863
8046
|
onClick: (e) => e.stopPropagation()
|
|
7864
8047
|
}
|
|
7865
|
-
) : /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
7866
|
-
|
|
7867
|
-
|
|
7868
|
-
|
|
7869
|
-
|
|
7870
|
-
"gantt-tl-
|
|
7871
|
-
|
|
7872
|
-
|
|
7873
|
-
|
|
7874
|
-
|
|
7875
|
-
|
|
7876
|
-
|
|
7877
|
-
|
|
7878
|
-
|
|
7879
|
-
|
|
7880
|
-
|
|
7881
|
-
|
|
7882
|
-
|
|
7883
|
-
|
|
7884
|
-
|
|
7885
|
-
|
|
8048
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
|
|
8049
|
+
task.composite && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
8050
|
+
"button",
|
|
8051
|
+
{
|
|
8052
|
+
type: "button",
|
|
8053
|
+
className: "gantt-tl-compositeToggle",
|
|
8054
|
+
onClick: handleToggleCollapse,
|
|
8055
|
+
style: { left: `${nestingDepth * 20 - 3}px` },
|
|
8056
|
+
"aria-label": isCollapsed ? `\u0420\u0430\u0441\u043A\u0440\u044B\u0442\u044C ${task.name}` : `\u0421\u0432\u0435\u0440\u043D\u0443\u0442\u044C ${task.name}`,
|
|
8057
|
+
"aria-expanded": !isCollapsed,
|
|
8058
|
+
title: isCollapsed ? "\u0420\u0430\u0441\u043A\u0440\u044B\u0442\u044C \u044D\u0442\u0430\u0436\u0438" : "\u0421\u0432\u0435\u0440\u043D\u0443\u0442\u044C \u044D\u0442\u0430\u0436\u0438",
|
|
8059
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
8060
|
+
"svg",
|
|
8061
|
+
{
|
|
8062
|
+
className: compositeIconAnimation && compositeIconAnimationPhase ? `gantt-tl-compositeGlyph-${compositeIconMode}-${compositeIconAnimation}-${compositeIconAnimationPhase}` : void 0,
|
|
8063
|
+
viewBox: "0 0 24 24",
|
|
8064
|
+
fill: "none",
|
|
8065
|
+
stroke: "currentColor",
|
|
8066
|
+
strokeWidth: "2",
|
|
8067
|
+
strokeLinecap: "round",
|
|
8068
|
+
strokeLinejoin: "round",
|
|
8069
|
+
"aria-hidden": "true",
|
|
8070
|
+
children: compositeIconMode === "composite" ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
|
|
8071
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: "M21 5H11" }),
|
|
8072
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: "M21 12H11" }),
|
|
8073
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: "M21 19H11" }),
|
|
8074
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: "m3 8 4 4-4 4" })
|
|
8075
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: "m6 9 6 6 6-6" })
|
|
8076
|
+
}
|
|
8077
|
+
)
|
|
8078
|
+
}
|
|
8079
|
+
),
|
|
8080
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
8081
|
+
"button",
|
|
8082
|
+
{
|
|
8083
|
+
type: "button",
|
|
8084
|
+
className: `gantt-tl-name-trigger${disableTaskNameEditing ? " gantt-tl-name-locked" : ""}`,
|
|
8085
|
+
title: task.name,
|
|
8086
|
+
onClick: handleNameClick,
|
|
8087
|
+
onDoubleClick: handleNameDoubleClick,
|
|
8088
|
+
style: {
|
|
8089
|
+
paddingLeft: task.composite ? `${nestingDepth * 20 + 30}px` : nameTriggerPaddingLeft,
|
|
8090
|
+
paddingRight: task.color ? "20px" : void 0
|
|
8091
|
+
},
|
|
8092
|
+
children: [
|
|
8093
|
+
taskListNamePrefixIcon ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "gantt-tl-name-trigger-icon", "aria-hidden": "true", children: taskListNamePrefixIcon }) : null,
|
|
8094
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "gantt-tl-name-trigger-text", children: task.name })
|
|
8095
|
+
]
|
|
8096
|
+
}
|
|
8097
|
+
)
|
|
8098
|
+
] }),
|
|
7886
8099
|
!editingName && task.color && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
7887
8100
|
"span",
|
|
7888
8101
|
{
|
|
@@ -8499,8 +8712,9 @@ var TaskListRow = import_react11.default.memo(
|
|
|
8499
8712
|
isDragOver && isNestedDropTarget ? "gantt-tl-row-drag-over-nested" : "",
|
|
8500
8713
|
isDragOver && isDirectChildDropTarget ? "gantt-tl-row-drag-over-direct-child" : "",
|
|
8501
8714
|
isChild ? "gantt-tl-row-child" : "",
|
|
8502
|
-
isParent ? "gantt-tl-row-parent" : "",
|
|
8503
|
-
|
|
8715
|
+
isParent && !task.composite ? "gantt-tl-row-parent" : "",
|
|
8716
|
+
task.composite ? "gantt-tl-row-composite" : "",
|
|
8717
|
+
isParent && !task.composite && fillParentRow ? "gantt-tl-row-parent-filled" : "",
|
|
8504
8718
|
`gantt-tl-row-level-${rowFillLevel}`,
|
|
8505
8719
|
isTotalRow ? "gantt-tl-row-total" : "",
|
|
8506
8720
|
rowClassName ?? ""
|
|
@@ -8508,6 +8722,7 @@ var TaskListRow = import_react11.default.memo(
|
|
|
8508
8722
|
style: {
|
|
8509
8723
|
height: `${rowHeight}px`,
|
|
8510
8724
|
position: "relative",
|
|
8725
|
+
"--gantt-tl-composite-detail-color": compositeParentColor ?? "var(--gantt-task-bar-default-color, #8b5cf6)",
|
|
8511
8726
|
"--gantt-tl-nested-drop-left": nestedDropIndicatorLeft,
|
|
8512
8727
|
"--gantt-tl-nested-inside-drop-left": nestedInsideDropIndicatorLeft
|
|
8513
8728
|
},
|
|
@@ -8733,6 +8948,7 @@ var GenerationSkeletonRows = ({
|
|
|
8733
8948
|
rowHeight,
|
|
8734
8949
|
variant,
|
|
8735
8950
|
startIndex = 0,
|
|
8951
|
+
startTop,
|
|
8736
8952
|
taskListLayout,
|
|
8737
8953
|
chartDayWidth = 40,
|
|
8738
8954
|
chartStartDayOffset = 0,
|
|
@@ -8773,7 +8989,7 @@ var GenerationSkeletonRows = ({
|
|
|
8773
8989
|
"div",
|
|
8774
8990
|
{
|
|
8775
8991
|
className: "gantt-generation-skeleton-row",
|
|
8776
|
-
style: { top: `${
|
|
8992
|
+
style: { top: `${(startTop ?? startIndex * rowHeight) + index * rowHeight}px`, height: `${rowHeight}px` },
|
|
8777
8993
|
children: variant === "task-list" ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_jsx_runtime16.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: `gantt-generation-skeleton-label ${shortShape ? "gantt-generation-skeleton-label-short" : ""} ${mediumShape ? "gantt-generation-skeleton-label-medium" : ""}` }) }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: `gantt-generation-skeleton-bar ${parentShape ? "gantt-generation-skeleton-bar-parent" : ""} ${shortShape ? "gantt-generation-skeleton-bar-short" : ""}`, style: chartBarStyle })
|
|
8778
8994
|
},
|
|
8779
8995
|
rowIndex
|
|
@@ -9033,6 +9249,8 @@ var SelectAllCheckbox = ({
|
|
|
9033
9249
|
var TaskList = ({
|
|
9034
9250
|
tasks,
|
|
9035
9251
|
rowHeight,
|
|
9252
|
+
rowTops,
|
|
9253
|
+
rowHeights,
|
|
9036
9254
|
headerHeight,
|
|
9037
9255
|
taskListWidth,
|
|
9038
9256
|
onTasksChange,
|
|
@@ -9160,14 +9378,22 @@ var TaskList = ({
|
|
|
9160
9378
|
return tasks2;
|
|
9161
9379
|
}, [orderedTasks, collapsedParentIds, filterMode, filteredTaskIds, isFilterActive, criticalPathMode, criticalTaskIds]);
|
|
9162
9380
|
const totalHeight = (0, import_react14.useMemo)(
|
|
9163
|
-
() => (visibleTasks.length + Math.max(0, Math.floor(skeletonRowCount))
|
|
9164
|
-
[rowHeight, skeletonRowCount, visibleTasks.length]
|
|
9381
|
+
() => (rowTops && rowHeights && visibleTasks.length > 0 ? rowTops[visibleTasks.length - 1] + rowHeights[visibleTasks.length - 1] : visibleTasks.length * rowHeight) + Math.max(0, Math.floor(skeletonRowCount)) * rowHeight,
|
|
9382
|
+
[rowHeight, rowTops, rowHeights, skeletonRowCount, visibleTasks.length]
|
|
9165
9383
|
);
|
|
9166
9384
|
const visibleTaskNumberMap = (0, import_react14.useMemo)(
|
|
9167
9385
|
() => Object.fromEntries(buildTaskNumberMap(visibleTasks)),
|
|
9168
9386
|
[visibleTasks]
|
|
9169
9387
|
);
|
|
9170
9388
|
const visibleTaskIds = (0, import_react14.useMemo)(() => visibleTasks.map((task) => task.id), [visibleTasks]);
|
|
9389
|
+
const compositeParentIds = (0, import_react14.useMemo)(
|
|
9390
|
+
() => new Set(tasks.filter((task) => task.composite).map((task) => task.id)),
|
|
9391
|
+
[tasks]
|
|
9392
|
+
);
|
|
9393
|
+
const compositeParentsById = (0, import_react14.useMemo)(
|
|
9394
|
+
() => new Map(tasks.filter((task) => task.composite).map((task) => [task.id, task])),
|
|
9395
|
+
[tasks]
|
|
9396
|
+
);
|
|
9171
9397
|
const renderedVisibleRowIndices = (0, import_react14.useMemo)(
|
|
9172
9398
|
() => visibleRowIndices ?? visibleTasks.map((_, index) => index),
|
|
9173
9399
|
[visibleRowIndices, visibleTasks]
|
|
@@ -10159,7 +10385,7 @@ var TaskList = ({
|
|
|
10159
10385
|
renderedVisibleTasks.map(({ task, index }) => {
|
|
10160
10386
|
const previousVisibleTask = index > 0 ? visibleTasks[index - 1] : void 0;
|
|
10161
10387
|
const canDemoteTask = index === 0 || !task.parentId || previousVisibleTask?.id !== task.parentId;
|
|
10162
|
-
const topOffset = index * rowHeight + (hasVisiblePendingInsert && index > pendingInsertRowIndex ? rowHeight : 0);
|
|
10388
|
+
const topOffset = (rowTops?.[index] ?? index * rowHeight) + (hasVisiblePendingInsert && index > pendingInsertRowIndex ? rowHeight : 0);
|
|
10163
10389
|
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
10164
10390
|
"div",
|
|
10165
10391
|
{
|
|
@@ -10176,7 +10402,7 @@ var TaskList = ({
|
|
|
10176
10402
|
rowIndex: index,
|
|
10177
10403
|
taskNumber: originalTaskNumberMap[task.id] || "",
|
|
10178
10404
|
taskNumberMap: originalTaskNumberMap,
|
|
10179
|
-
rowHeight,
|
|
10405
|
+
rowHeight: rowHeights?.[index] ?? rowHeight,
|
|
10180
10406
|
onTasksChange,
|
|
10181
10407
|
onDurationChange,
|
|
10182
10408
|
selectedTaskId,
|
|
@@ -10233,7 +10459,8 @@ var TaskList = ({
|
|
|
10233
10459
|
onActiveCustomCellChange: setActiveCustomCell,
|
|
10234
10460
|
taskListMenuCommands,
|
|
10235
10461
|
hideTaskListRowActions,
|
|
10236
|
-
rowClassName: getTaskListRowClassName?.(task),
|
|
10462
|
+
rowClassName: [task.parentId && compositeParentIds.has(task.parentId) ? "gantt-tl-row-composite-detail" : "", getTaskListRowClassName?.(task)].filter(Boolean).join(" "),
|
|
10463
|
+
compositeParentColor: task.parentId ? compositeParentsById.get(task.parentId)?.color : void 0,
|
|
10237
10464
|
getTaskListNamePrefixIcon,
|
|
10238
10465
|
taskDateChangeMode,
|
|
10239
10466
|
onTaskDateChangeModeChange,
|
|
@@ -10249,7 +10476,7 @@ var TaskList = ({
|
|
|
10249
10476
|
{
|
|
10250
10477
|
style: {
|
|
10251
10478
|
position: "absolute",
|
|
10252
|
-
top: `${(pendingInsertRowIndex + 1) * rowHeight}px`,
|
|
10479
|
+
top: `${rowTops?.[pendingInsertRowIndex + 1] ?? (pendingInsertRowIndex + 1) * rowHeight}px`,
|
|
10253
10480
|
left: 0,
|
|
10254
10481
|
right: 0
|
|
10255
10482
|
},
|
|
@@ -10271,6 +10498,7 @@ var TaskList = ({
|
|
|
10271
10498
|
rowHeight,
|
|
10272
10499
|
variant: "task-list",
|
|
10273
10500
|
startIndex: visibleTasks.length,
|
|
10501
|
+
startTop: totalHeight - Math.max(0, Math.floor(skeletonRowCount)) * rowHeight,
|
|
10274
10502
|
taskListLayout: generationSkeletonTaskListLayout
|
|
10275
10503
|
}
|
|
10276
10504
|
)
|
|
@@ -14297,10 +14525,14 @@ function TaskGanttChartInner(props, ref) {
|
|
|
14297
14525
|
const rect = element.getBoundingClientRect();
|
|
14298
14526
|
const side = element.getAttribute("data-port-side");
|
|
14299
14527
|
return {
|
|
14300
|
-
//
|
|
14301
|
-
//
|
|
14302
|
-
|
|
14303
|
-
|
|
14528
|
+
// Anchor the preview at the port dot's center so the dragged polyline
|
|
14529
|
+
// ends exactly on the link handle. The dot core is 8px and sits 4px
|
|
14530
|
+
// inside the 24px zone from the bar side (see TaskRow.css), which puts
|
|
14531
|
+
// its center 8px off the button edge adjacent to the bar. No rounding:
|
|
14532
|
+
// the CSS ball centers at a fractional position, and a rounded SVG
|
|
14533
|
+
// coordinate landed ~1px off it.
|
|
14534
|
+
x: (side === "left" ? rect.right - 8 : rect.left + 8) - chartRect.left,
|
|
14535
|
+
y: rect.top + rect.height / 2 - chartRect.top
|
|
14304
14536
|
};
|
|
14305
14537
|
}, []);
|
|
14306
14538
|
const getVisualDependencyType = (0, import_react19.useCallback)((sourceSide, targetSide) => {
|
|
@@ -14451,7 +14683,7 @@ function TaskGanttChartInner(props, ref) {
|
|
|
14451
14683
|
}, [dependencyLineMenu, onTasksChange, tasks]);
|
|
14452
14684
|
const [activeTimelineTooltip, setActiveTimelineTooltip] = (0, import_react19.useState)(null);
|
|
14453
14685
|
const [internalCollapsedParentIds, setInternalCollapsedParentIds] = (0, import_react19.useState)(/* @__PURE__ */ new Set());
|
|
14454
|
-
const
|
|
14686
|
+
const [expandedCompositeIds, setExpandedCompositeIds] = (0, import_react19.useState)(/* @__PURE__ */ new Set());
|
|
14455
14687
|
const [editingTaskId, setEditingTaskId] = (0, import_react19.useState)(null);
|
|
14456
14688
|
const taskDateChangeMode = externalTaskDateChangeMode ?? internalTaskDateChangeMode;
|
|
14457
14689
|
const handleTaskDateChangeMode = externalOnTaskDateChangeModeChange ?? setInternalTaskDateChangeMode;
|
|
@@ -14461,7 +14693,36 @@ function TaskGanttChartInner(props, ref) {
|
|
|
14461
14693
|
() => Math.max(rowHeight, 10 + resolvedRowContentLines * 18),
|
|
14462
14694
|
[resolvedRowContentLines, rowHeight]
|
|
14463
14695
|
);
|
|
14464
|
-
const normalizedTasks = (0, import_react19.useMemo)(() =>
|
|
14696
|
+
const normalizedTasks = (0, import_react19.useMemo)(() => {
|
|
14697
|
+
const ordered = normalizeHierarchyTasks(tasks);
|
|
14698
|
+
const ranges = /* @__PURE__ */ new Map();
|
|
14699
|
+
for (const task of ordered) {
|
|
14700
|
+
if (!task.parentId) continue;
|
|
14701
|
+
const start = parseUTCDate(task.startDate).getTime();
|
|
14702
|
+
const end = parseUTCDate(task.endDate).getTime();
|
|
14703
|
+
const range = ranges.get(task.parentId);
|
|
14704
|
+
ranges.set(task.parentId, {
|
|
14705
|
+
start: Math.min(range?.start ?? start, start),
|
|
14706
|
+
end: Math.max(range?.end ?? end, end)
|
|
14707
|
+
});
|
|
14708
|
+
}
|
|
14709
|
+
return ordered.map((task) => {
|
|
14710
|
+
const range = task.composite ? ranges.get(task.id) : void 0;
|
|
14711
|
+
return range ? {
|
|
14712
|
+
...task,
|
|
14713
|
+
startDate: new Date(range.start).toISOString().slice(0, 10),
|
|
14714
|
+
endDate: new Date(range.end).toISOString().slice(0, 10)
|
|
14715
|
+
} : task;
|
|
14716
|
+
});
|
|
14717
|
+
}, [tasks]);
|
|
14718
|
+
const collapsedParentIds = (0, import_react19.useMemo)(() => {
|
|
14719
|
+
if (externalCollapsedParentIds) return externalCollapsedParentIds;
|
|
14720
|
+
const ids = new Set(internalCollapsedParentIds);
|
|
14721
|
+
for (const task of normalizedTasks) {
|
|
14722
|
+
if (task.composite && !expandedCompositeIds.has(task.id)) ids.add(task.id);
|
|
14723
|
+
}
|
|
14724
|
+
return ids;
|
|
14725
|
+
}, [externalCollapsedParentIds, internalCollapsedParentIds, normalizedTasks, expandedCompositeIds]);
|
|
14465
14726
|
const controlledScheduleIdentity = (0, import_react19.useMemo)(
|
|
14466
14727
|
() => buildControlledScheduleIdentity(normalizedTasks),
|
|
14467
14728
|
[normalizedTasks]
|
|
@@ -14541,6 +14802,23 @@ function TaskGanttChartInner(props, ref) {
|
|
|
14541
14802
|
}
|
|
14542
14803
|
return tasks2;
|
|
14543
14804
|
}, [normalizedTasks, collapsedParentIds, filterMode, taskFilter, criticalPathMode, criticalTaskIds]);
|
|
14805
|
+
const compositeRowLayout = (0, import_react19.useMemo)(() => {
|
|
14806
|
+
const compositeIds = new Set(normalizedTasks.filter((task) => task.composite).map((task) => task.id));
|
|
14807
|
+
const tops = [];
|
|
14808
|
+
const heights = [];
|
|
14809
|
+
let top = 0;
|
|
14810
|
+
for (const task of visibleTasks) {
|
|
14811
|
+
tops.push(top);
|
|
14812
|
+
const height = task.parentId && compositeIds.has(task.parentId) ? Math.min(effectiveRowHeight, 22) : effectiveRowHeight;
|
|
14813
|
+
heights.push(height);
|
|
14814
|
+
top += height;
|
|
14815
|
+
}
|
|
14816
|
+
return { tops, heights, totalHeight: top };
|
|
14817
|
+
}, [normalizedTasks, visibleTasks, effectiveRowHeight]);
|
|
14818
|
+
const compositeParentsById = (0, import_react19.useMemo)(
|
|
14819
|
+
() => new Map(normalizedTasks.filter((task) => task.composite).map((task) => [task.id, task])),
|
|
14820
|
+
[normalizedTasks]
|
|
14821
|
+
);
|
|
14544
14822
|
const matchedTaskIds = (0, import_react19.useMemo)(() => {
|
|
14545
14823
|
if (!taskFilter) return /* @__PURE__ */ new Set();
|
|
14546
14824
|
return new Set(visibleTasks.filter(taskFilter).map((task) => task.id));
|
|
@@ -14562,8 +14840,8 @@ function TaskGanttChartInner(props, ref) {
|
|
|
14562
14840
|
return mergedHighlightedTaskIds;
|
|
14563
14841
|
}, [filterMode, highlightedTaskIds, matchedTaskIds, criticalPathMode, criticalTaskIds]);
|
|
14564
14842
|
const totalGridHeight = (0, import_react19.useMemo)(
|
|
14565
|
-
() =>
|
|
14566
|
-
[effectiveRowHeight, skeletonRowCount
|
|
14843
|
+
() => compositeRowLayout.totalHeight + Math.max(0, Math.floor(skeletonRowCount)) * effectiveRowHeight,
|
|
14844
|
+
[compositeRowLayout.totalHeight, effectiveRowHeight, skeletonRowCount]
|
|
14567
14845
|
);
|
|
14568
14846
|
const timelineHeaderHeight = headerHeight + 1;
|
|
14569
14847
|
const tableBodyMinHeight = (0, import_react19.useMemo)(() => {
|
|
@@ -14690,7 +14968,7 @@ function TaskGanttChartInner(props, ref) {
|
|
|
14690
14968
|
const rowIndex = visibleTasks.findIndex((visibleTask) => visibleTask.id === taskId);
|
|
14691
14969
|
if (rowIndex === -1) return;
|
|
14692
14970
|
const paddedRowIndex = Math.max(0, rowIndex - SCROLL_TO_ROW_CONTEXT_ROWS);
|
|
14693
|
-
container2.scrollTo({ top: Math.max(0,
|
|
14971
|
+
container2.scrollTo({ top: Math.max(0, compositeRowLayout.tops[paddedRowIndex] ?? 0), behavior: "smooth" });
|
|
14694
14972
|
setSelectedTaskId(taskId);
|
|
14695
14973
|
return;
|
|
14696
14974
|
}
|
|
@@ -14709,7 +14987,7 @@ function TaskGanttChartInner(props, ref) {
|
|
|
14709
14987
|
const taskOffset = taskIndex * dayWidth;
|
|
14710
14988
|
const scrollLeft = Math.round(taskOffset - dayWidth * 2);
|
|
14711
14989
|
container.scrollTo({ left: Math.max(0, scrollLeft), behavior: "smooth" });
|
|
14712
|
-
}, [dateRange, dayWidth, effectiveRowHeight, isTableMatrixMode, tasks, visibleTasks]);
|
|
14990
|
+
}, [dateRange, dayWidth, effectiveRowHeight, compositeRowLayout, isTableMatrixMode, tasks, visibleTasks]);
|
|
14713
14991
|
const scrollToRow = (0, import_react19.useCallback)((taskId, options = {}) => {
|
|
14714
14992
|
const container = scrollContainerRef.current;
|
|
14715
14993
|
if (!container) return;
|
|
@@ -14718,7 +14996,7 @@ function TaskGanttChartInner(props, ref) {
|
|
|
14718
14996
|
const rowIndex = visibleTasks.findIndex((visibleTask) => visibleTask.id === task.id);
|
|
14719
14997
|
if (rowIndex === -1) return;
|
|
14720
14998
|
const paddedRowIndex = Math.max(0, rowIndex - SCROLL_TO_ROW_CONTEXT_ROWS);
|
|
14721
|
-
const scrollTop = Math.max(0,
|
|
14999
|
+
const scrollTop = Math.max(0, compositeRowLayout.tops[paddedRowIndex] ?? 0);
|
|
14722
15000
|
const {
|
|
14723
15001
|
select = true,
|
|
14724
15002
|
behavior = "smooth",
|
|
@@ -14738,7 +15016,7 @@ function TaskGanttChartInner(props, ref) {
|
|
|
14738
15016
|
}
|
|
14739
15017
|
}
|
|
14740
15018
|
container.scrollTo({ top: scrollTop, behavior });
|
|
14741
|
-
}, [effectiveRowHeight, tasks, visibleTasks]);
|
|
15019
|
+
}, [effectiveRowHeight, compositeRowLayout, tasks, visibleTasks]);
|
|
14742
15020
|
const [dragGuideLines, setDragGuideLines] = (0, import_react19.useState)(null);
|
|
14743
15021
|
const [draggedTaskOverride, setDraggedTaskOverride] = (0, import_react19.useState)(null);
|
|
14744
15022
|
(0, import_react19.useEffect)(() => {
|
|
@@ -14765,9 +15043,9 @@ function TaskGanttChartInner(props, ref) {
|
|
|
14765
15043
|
previewPositionStore.clear();
|
|
14766
15044
|
}, [previewPositionStore]);
|
|
14767
15045
|
const handleTaskChange = (0, import_react19.useCallback)((updatedTasks, durationEdit) => {
|
|
14768
|
-
|
|
15046
|
+
let updatedTask = updatedTasks[0];
|
|
14769
15047
|
if (!updatedTask) return;
|
|
14770
|
-
const originalTask =
|
|
15048
|
+
const originalTask = normalizedTasks.find((t) => t.id === updatedTask.id);
|
|
14771
15049
|
if (!originalTask) {
|
|
14772
15050
|
onTasksChange?.(updatedTasks);
|
|
14773
15051
|
if (editingTaskId === updatedTask.id) {
|
|
@@ -14780,6 +15058,8 @@ function TaskGanttChartInner(props, ref) {
|
|
|
14780
15058
|
const newStart = new Date(updatedTask.startDate);
|
|
14781
15059
|
const newEnd = new Date(updatedTask.endDate);
|
|
14782
15060
|
const datesChanged = origStart.getTime() !== newStart.getTime() || origEnd.getTime() !== newEnd.getTime();
|
|
15061
|
+
const isCompositeDetail = datesChanged && tasks.some((task) => task.id === updatedTask.parentId && task.composite);
|
|
15062
|
+
if (isCompositeDetail) updatedTask = { ...updatedTask, synced: false };
|
|
14783
15063
|
if (!datesChanged) {
|
|
14784
15064
|
if (updatedTasks.length > 1) {
|
|
14785
15065
|
onTasksChange?.(updatedTasks);
|
|
@@ -14841,7 +15121,7 @@ function TaskGanttChartInner(props, ref) {
|
|
|
14841
15121
|
}
|
|
14842
15122
|
return;
|
|
14843
15123
|
}
|
|
14844
|
-
const movedParentCascade = disableConstraints ? [updatedTask] : universalCascade(updatedTask, newStart, newEnd,
|
|
15124
|
+
const movedParentCascade = disableConstraints && !originalTask.composite ? [updatedTask] : universalCascade(updatedTask, newStart, newEnd, normalizedTasks, businessDays, isCustomWeekend);
|
|
14845
15125
|
if (onScheduleIntent) {
|
|
14846
15126
|
onScheduleIntent({
|
|
14847
15127
|
type: "move_task",
|
|
@@ -14865,7 +15145,8 @@ function TaskGanttChartInner(props, ref) {
|
|
|
14865
15145
|
taskId: updatedTask.id,
|
|
14866
15146
|
duration: durationEdit.duration,
|
|
14867
15147
|
anchor: durationEdit.anchor,
|
|
14868
|
-
taskType: updatedTask.type ?? "task"
|
|
15148
|
+
taskType: updatedTask.type ?? "task",
|
|
15149
|
+
...isCompositeDetail ? { localOverride: true } : {}
|
|
14869
15150
|
});
|
|
14870
15151
|
} else {
|
|
14871
15152
|
onTasksChange?.(cascadedTasks);
|
|
@@ -14877,7 +15158,8 @@ function TaskGanttChartInner(props, ref) {
|
|
|
14877
15158
|
onScheduleIntent({
|
|
14878
15159
|
type: "move_task",
|
|
14879
15160
|
taskId: updatedTask.id,
|
|
14880
|
-
startDate: newStart.toISOString().split("T")[0]
|
|
15161
|
+
startDate: newStart.toISOString().split("T")[0],
|
|
15162
|
+
...isCompositeDetail ? { localOverride: true } : {}
|
|
14881
15163
|
});
|
|
14882
15164
|
} else {
|
|
14883
15165
|
const anchor = startChanged ? "end" : "start";
|
|
@@ -14885,13 +15167,14 @@ function TaskGanttChartInner(props, ref) {
|
|
|
14885
15167
|
type: "resize_task",
|
|
14886
15168
|
taskId: updatedTask.id,
|
|
14887
15169
|
anchor,
|
|
14888
|
-
date: (startChanged ? newStart : newEnd).toISOString().split("T")[0]
|
|
15170
|
+
date: (startChanged ? newStart : newEnd).toISOString().split("T")[0],
|
|
15171
|
+
...isCompositeDetail ? { localOverride: true } : {}
|
|
14889
15172
|
});
|
|
14890
15173
|
}
|
|
14891
15174
|
} else {
|
|
14892
15175
|
onTasksChange?.(cascadedTasks);
|
|
14893
15176
|
}
|
|
14894
|
-
}, [tasks, onTasksChange, onScheduleIntent, disableConstraints, editingTaskId, businessDays, isCustomWeekend, onSubtreeScaleResult]);
|
|
15177
|
+
}, [tasks, normalizedTasks, onTasksChange, onScheduleIntent, disableConstraints, editingTaskId, businessDays, isCustomWeekend, onSubtreeScaleResult]);
|
|
14895
15178
|
const handleTaskDurationChange = (0, import_react19.useCallback)((task, duration) => {
|
|
14896
15179
|
const updatedTask = {
|
|
14897
15180
|
...task,
|
|
@@ -15005,12 +15288,25 @@ function TaskGanttChartInner(props, ref) {
|
|
|
15005
15288
|
if (scrollViewport.viewportHeight <= 0) {
|
|
15006
15289
|
return Array.from({ length: totalTasks }, (_, index) => index);
|
|
15007
15290
|
}
|
|
15008
|
-
|
|
15009
|
-
|
|
15010
|
-
|
|
15011
|
-
|
|
15012
|
-
|
|
15013
|
-
|
|
15291
|
+
let low = 0;
|
|
15292
|
+
let high = totalTasks;
|
|
15293
|
+
while (low < high) {
|
|
15294
|
+
const middle = low + high >>> 1;
|
|
15295
|
+
if (compositeRowLayout.tops[middle] + compositeRowLayout.heights[middle] < scrollViewport.scrollTop) low = middle + 1;
|
|
15296
|
+
else high = middle;
|
|
15297
|
+
}
|
|
15298
|
+
const first = Math.min(low, totalTasks - 1);
|
|
15299
|
+
const viewportBottom = scrollViewport.scrollTop + scrollViewport.viewportHeight;
|
|
15300
|
+
low = first;
|
|
15301
|
+
high = totalTasks;
|
|
15302
|
+
while (low < high) {
|
|
15303
|
+
const middle = low + high >>> 1;
|
|
15304
|
+
if (compositeRowLayout.tops[middle] < viewportBottom) low = middle + 1;
|
|
15305
|
+
else high = middle;
|
|
15306
|
+
}
|
|
15307
|
+
const last = Math.min(low, totalTasks - 1);
|
|
15308
|
+
const rangeStart = Math.max(0, first - TASK_ROW_OVERSCAN);
|
|
15309
|
+
const rangeEnd = Math.min(totalTasks - 1, last + TASK_ROW_OVERSCAN);
|
|
15014
15310
|
const indices = /* @__PURE__ */ new Set();
|
|
15015
15311
|
for (let index = rangeStart; index <= rangeEnd; index += 1) {
|
|
15016
15312
|
indices.add(index);
|
|
@@ -15022,7 +15318,7 @@ function TaskGanttChartInner(props, ref) {
|
|
|
15022
15318
|
}
|
|
15023
15319
|
}
|
|
15024
15320
|
return Array.from(indices).sort((left, right) => left - right);
|
|
15025
|
-
}, [
|
|
15321
|
+
}, [compositeRowLayout, forceFullRenderForPrint, forcedRenderedTaskIds, scrollViewport, visibleTaskIndexMap, visibleTasks.length]);
|
|
15026
15322
|
const visiblePlanFactDateIndices = (0, import_react19.useMemo)(() => {
|
|
15027
15323
|
if (forceFullRenderForPrint) {
|
|
15028
15324
|
return void 0;
|
|
@@ -15099,7 +15395,16 @@ function TaskGanttChartInner(props, ref) {
|
|
|
15099
15395
|
}
|
|
15100
15396
|
applyHoveredRows(taskId);
|
|
15101
15397
|
}, [applyHoveredRows]);
|
|
15102
|
-
const handleToggleCollapse = externalOnToggleCollapse ?? (
|
|
15398
|
+
const handleToggleCollapse = externalOnToggleCollapse ?? ((parentId) => {
|
|
15399
|
+
if (normalizedTasks.some((task) => task.id === parentId && task.composite)) {
|
|
15400
|
+
setExpandedCompositeIds((prev) => {
|
|
15401
|
+
const next = new Set(prev);
|
|
15402
|
+
if (next.has(parentId)) next.delete(parentId);
|
|
15403
|
+
else next.add(parentId);
|
|
15404
|
+
return next;
|
|
15405
|
+
});
|
|
15406
|
+
return;
|
|
15407
|
+
}
|
|
15103
15408
|
setInternalCollapsedParentIds((prev) => {
|
|
15104
15409
|
const next = new Set(prev);
|
|
15105
15410
|
if (next.has(parentId)) {
|
|
@@ -15109,7 +15414,14 @@ function TaskGanttChartInner(props, ref) {
|
|
|
15109
15414
|
}
|
|
15110
15415
|
return next;
|
|
15111
15416
|
});
|
|
15112
|
-
}
|
|
15417
|
+
});
|
|
15418
|
+
const lastCompositeBarToggleRef = (0, import_react19.useRef)(null);
|
|
15419
|
+
const handleCompositeBarToggle = (taskId, source) => {
|
|
15420
|
+
const now = Date.now();
|
|
15421
|
+
if (source === "click" && lastCompositeBarToggleRef.current?.source === "release" && lastCompositeBarToggleRef.current.id === taskId && now - lastCompositeBarToggleRef.current.time < 150) return;
|
|
15422
|
+
lastCompositeBarToggleRef.current = { id: taskId, time: now, source };
|
|
15423
|
+
handleToggleCollapse(taskId);
|
|
15424
|
+
};
|
|
15113
15425
|
const allParentIds = (0, import_react19.useMemo)(() => {
|
|
15114
15426
|
const taskIds = new Set(normalizedTasks.map((task) => task.id));
|
|
15115
15427
|
return new Set(normalizedTasks.map((task) => task.parentId).filter((parentId) => Boolean(parentId && taskIds.has(parentId))));
|
|
@@ -15117,11 +15429,13 @@ function TaskGanttChartInner(props, ref) {
|
|
|
15117
15429
|
const handleCollapseAll = (0, import_react19.useCallback)(() => {
|
|
15118
15430
|
if (externalCollapsedParentIds) return;
|
|
15119
15431
|
setInternalCollapsedParentIds(allParentIds);
|
|
15432
|
+
setExpandedCompositeIds(/* @__PURE__ */ new Set());
|
|
15120
15433
|
}, [allParentIds, externalCollapsedParentIds]);
|
|
15121
15434
|
const handleExpandAll = (0, import_react19.useCallback)(() => {
|
|
15122
15435
|
if (externalCollapsedParentIds) return;
|
|
15123
15436
|
setInternalCollapsedParentIds(/* @__PURE__ */ new Set());
|
|
15124
|
-
|
|
15437
|
+
setExpandedCompositeIds(new Set(normalizedTasks.filter((task) => task.composite).map((task) => task.id)));
|
|
15438
|
+
}, [externalCollapsedParentIds, normalizedTasks]);
|
|
15125
15439
|
const exportToPdf = (0, import_react19.useCallback)(async (options) => {
|
|
15126
15440
|
const sourceContainer = containerRef.current;
|
|
15127
15441
|
if (!sourceContainer || typeof window === "undefined" || typeof document === "undefined") {
|
|
@@ -15386,6 +15700,8 @@ function TaskGanttChartInner(props, ref) {
|
|
|
15386
15700
|
{
|
|
15387
15701
|
tasks: normalizedTasks,
|
|
15388
15702
|
rowHeight: effectiveRowHeight,
|
|
15703
|
+
rowTops: compositeRowLayout.tops,
|
|
15704
|
+
rowHeights: compositeRowLayout.heights,
|
|
15389
15705
|
headerHeight,
|
|
15390
15706
|
taskListWidth,
|
|
15391
15707
|
onTasksChange: handleTaskChange,
|
|
@@ -15580,6 +15896,8 @@ function TaskGanttChartInner(props, ref) {
|
|
|
15580
15896
|
gridWidth: renderGridWidth,
|
|
15581
15897
|
totalHeight: totalGridHeight,
|
|
15582
15898
|
rowIndexByTaskId: visibleTaskIndexMap,
|
|
15899
|
+
rowTops: compositeRowLayout.tops,
|
|
15900
|
+
rowHeights: compositeRowLayout.heights,
|
|
15583
15901
|
dragOverrides: dependencyOverrides,
|
|
15584
15902
|
selectedDep: selectedChip,
|
|
15585
15903
|
businessDays,
|
|
@@ -15666,10 +15984,10 @@ function TaskGanttChartInner(props, ref) {
|
|
|
15666
15984
|
{
|
|
15667
15985
|
style: {
|
|
15668
15986
|
position: "absolute",
|
|
15669
|
-
top: `${index
|
|
15987
|
+
top: `${compositeRowLayout.tops[index]}px`,
|
|
15670
15988
|
left: 0,
|
|
15671
15989
|
right: 0,
|
|
15672
|
-
height: `${
|
|
15990
|
+
height: `${compositeRowLayout.heights[index]}px`
|
|
15673
15991
|
},
|
|
15674
15992
|
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
15675
15993
|
TaskRow_default,
|
|
@@ -15677,7 +15995,9 @@ function TaskGanttChartInner(props, ref) {
|
|
|
15677
15995
|
task,
|
|
15678
15996
|
monthStart,
|
|
15679
15997
|
dayWidth,
|
|
15680
|
-
rowHeight:
|
|
15998
|
+
rowHeight: compositeRowLayout.heights[index],
|
|
15999
|
+
compactDetail: compositeRowLayout.heights[index] < effectiveRowHeight,
|
|
16000
|
+
compositeParentColor: task.parentId ? compositeParentsById.get(task.parentId)?.color : void 0,
|
|
15681
16001
|
onTasksChange: handleTaskChange,
|
|
15682
16002
|
onDragStateChange: (state) => {
|
|
15683
16003
|
if (state.isDragging) {
|
|
@@ -15714,7 +16034,9 @@ function TaskGanttChartInner(props, ref) {
|
|
|
15714
16034
|
isDependencyDragActive: dependencyCreationDrag !== null,
|
|
15715
16035
|
viewMode,
|
|
15716
16036
|
showTaskDateLabels,
|
|
15717
|
-
showTaskNames
|
|
16037
|
+
showTaskNames,
|
|
16038
|
+
onCompositeToggle: task.composite ? (source) => handleCompositeBarToggle(task.id, source) : void 0,
|
|
16039
|
+
compositeExpanded: task.composite ? !collapsedParentIds.has(task.id) : void 0
|
|
15718
16040
|
}
|
|
15719
16041
|
)
|
|
15720
16042
|
},
|
|
@@ -15727,6 +16049,7 @@ function TaskGanttChartInner(props, ref) {
|
|
|
15727
16049
|
rowHeight: effectiveRowHeight,
|
|
15728
16050
|
variant: "chart",
|
|
15729
16051
|
startIndex: visibleTasks.length,
|
|
16052
|
+
startTop: compositeRowLayout.totalHeight,
|
|
15730
16053
|
chartDayWidth: dayWidth,
|
|
15731
16054
|
chartStartDayOffset: todayInRange ? Math.max(0, todayIndex + Math.floor(Number.isFinite(skeletonStartOffsetDays) ? skeletonStartOffsetDays : 0)) : 0,
|
|
15732
16055
|
chartStartJitterDays: skeletonStartJitterDays
|
|
@@ -15810,6 +16133,8 @@ var nameContains = (substring, caseSensitive = false) => (task) => {
|
|
|
15810
16133
|
GenerationSkeletonRows,
|
|
15811
16134
|
GridBackground,
|
|
15812
16135
|
Input,
|
|
16136
|
+
MIN_EDGE_ZONE_PX,
|
|
16137
|
+
MIN_MOVE_ZONE_PX,
|
|
15813
16138
|
PlanFactMatrix,
|
|
15814
16139
|
Popover,
|
|
15815
16140
|
PopoverContent,
|