gantt-lib 0.135.9 → 0.136.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/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 +19 -2
- package/dist/index.d.ts +19 -2
- package/dist/index.js +469 -119
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +665 -315
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +228 -4
- 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 useMemo13, useCallback as useCallback10, useRef as
|
|
6
|
+
import { useMemo as useMemo13, useCallback as useCallback10, useRef as useRef13, useState as useState13, useEffect as useEffect11, useImperativeHandle, forwardRef } from "react";
|
|
7
7
|
|
|
8
8
|
// src/core/scheduling/dateMath.ts
|
|
9
9
|
var DAY_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -3155,7 +3155,8 @@ var TimeScaleHeader = ({
|
|
|
3155
3155
|
var TimeScaleHeader_default = TimeScaleHeader;
|
|
3156
3156
|
|
|
3157
3157
|
// src/components/TaskRow/TaskRow.tsx
|
|
3158
|
-
import React2, { useCallback as useCallback2, useMemo as useMemo2, useSyncExternalStore } from "react";
|
|
3158
|
+
import React2, { useCallback as useCallback2, useEffect as useEffect2, useMemo as useMemo2, useRef as useRef2, useState as useState2, useSyncExternalStore } from "react";
|
|
3159
|
+
import { createPortal } from "react-dom";
|
|
3159
3160
|
|
|
3160
3161
|
// src/utils/geometry.ts
|
|
3161
3162
|
var getUTCDayDifference = (date1, date2) => {
|
|
@@ -4263,12 +4264,36 @@ var useTaskDrag = (options) => {
|
|
|
4263
4264
|
|
|
4264
4265
|
// src/components/TaskRow/TaskRow.tsx
|
|
4265
4266
|
import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
4267
|
+
var COMPOSITE_SEGMENT_CUT_MIN_PX = 10;
|
|
4268
|
+
var formatCompositePreviewDate = (date) => {
|
|
4269
|
+
const month = new Intl.DateTimeFormat("ru-RU", { month: "short", timeZone: "UTC" }).format(date).replace(/\.$/, "");
|
|
4270
|
+
const yearSuffix = date.getUTCFullYear() === (/* @__PURE__ */ new Date()).getFullYear() ? "" : ` ${String(date.getUTCFullYear()).slice(-2)}`;
|
|
4271
|
+
return `${date.getUTCDate()} ${month}${yearSuffix}`;
|
|
4272
|
+
};
|
|
4266
4273
|
var arePropsEqual = (prevProps, nextProps) => {
|
|
4267
|
-
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;
|
|
4274
|
+
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 && prevProps.showCompositeSegments === nextProps.showCompositeSegments;
|
|
4268
4275
|
};
|
|
4269
4276
|
var TaskRow = React2.memo(
|
|
4270
|
-
({ 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 }) => {
|
|
4277
|
+
({ 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, showCompositeSegments: showCompositeSegmentsProp = true, onCompositeToggle, compactDetail = false, compositeParentColor, compositeExpanded = false }) => {
|
|
4271
4278
|
const defaultParentBarColor = "#782FC4";
|
|
4279
|
+
const [showCompositePreview, setShowCompositePreview] = useState2(false);
|
|
4280
|
+
const [compositePreviewPosition, setCompositePreviewPosition] = useState2(null);
|
|
4281
|
+
const pointerStart = useRef2(null);
|
|
4282
|
+
const suppressCompositeClick = useRef2(false);
|
|
4283
|
+
const compositeChildren = useMemo2(
|
|
4284
|
+
() => task.composite ? (allTasks ?? []).filter((child) => child.parentId === task.id) : [],
|
|
4285
|
+
[allTasks, task.composite, task.id]
|
|
4286
|
+
);
|
|
4287
|
+
useEffect2(() => {
|
|
4288
|
+
if (!showCompositePreview) return;
|
|
4289
|
+
const hide = () => setShowCompositePreview(false);
|
|
4290
|
+
window.addEventListener("scroll", hide, true);
|
|
4291
|
+
window.addEventListener("resize", hide);
|
|
4292
|
+
return () => {
|
|
4293
|
+
window.removeEventListener("scroll", hide, true);
|
|
4294
|
+
window.removeEventListener("resize", hide);
|
|
4295
|
+
};
|
|
4296
|
+
}, [showCompositePreview]);
|
|
4272
4297
|
const { divider: taskDivider } = task;
|
|
4273
4298
|
const normalizedTask = useMemo2(() => normalizeTaskDatesForType(task), [task]);
|
|
4274
4299
|
const milestone = useMemo2(() => isMilestoneTask(normalizedTask), [normalizedTask]);
|
|
@@ -4285,6 +4310,7 @@ var TaskRow = React2.memo(
|
|
|
4285
4310
|
const isParent = useMemo2(() => {
|
|
4286
4311
|
return allTasks ? isTaskParent(task.id, allTasks) : false;
|
|
4287
4312
|
}, [allTasks, task.id]);
|
|
4313
|
+
const isVisualParent = isParent && !task.composite;
|
|
4288
4314
|
const childCount = useMemo2(() => {
|
|
4289
4315
|
return allTasks ? getChildren(task.id, allTasks).length : 0;
|
|
4290
4316
|
}, [allTasks, task.id]);
|
|
@@ -4330,19 +4356,19 @@ var TaskRow = React2.memo(
|
|
|
4330
4356
|
if (isExpired) {
|
|
4331
4357
|
return "color-mix(in srgb, var(--gantt-expired-color) 40%, black)";
|
|
4332
4358
|
}
|
|
4333
|
-
const baseColor =
|
|
4359
|
+
const baseColor = isVisualParent ? task.color || defaultParentBarColor : task.color || "var(--gantt-task-bar-default-color)";
|
|
4334
4360
|
return `color-mix(in srgb, ${baseColor} 40%, black)`;
|
|
4335
|
-
}, [defaultParentBarColor, isCritical, isExpired,
|
|
4361
|
+
}, [defaultParentBarColor, isCritical, isExpired, isVisualParent, task.color]);
|
|
4336
4362
|
const barStyle = useMemo2(() => {
|
|
4337
4363
|
const parentBarColor = task.color || defaultParentBarColor;
|
|
4338
4364
|
if (isCritical && !isExpired) {
|
|
4339
4365
|
const c = criticalBarColor;
|
|
4340
|
-
if (
|
|
4366
|
+
if (isVisualParent) {
|
|
4341
4367
|
return { backgroundColor: c, "--gantt-parent-bar-color": c };
|
|
4342
4368
|
}
|
|
4343
4369
|
return { backgroundColor: c };
|
|
4344
4370
|
}
|
|
4345
|
-
if (
|
|
4371
|
+
if (isVisualParent) {
|
|
4346
4372
|
if (progressWidth >= 100) {
|
|
4347
4373
|
const c = isExpired ? "color-mix(in srgb, var(--gantt-expired-color) 40%, black)" : `color-mix(in srgb, ${parentBarColor} 40%, black)`;
|
|
4348
4374
|
return { backgroundColor: c, "--gantt-parent-bar-color": c };
|
|
@@ -4353,7 +4379,7 @@ var TaskRow = React2.memo(
|
|
|
4353
4379
|
return { backgroundColor: progressColor };
|
|
4354
4380
|
}
|
|
4355
4381
|
return { backgroundColor: barColor };
|
|
4356
|
-
}, [isCritical, defaultParentBarColor, isExpired,
|
|
4382
|
+
}, [isCritical, defaultParentBarColor, isExpired, isVisualParent, progressWidth, barColor, progressColor, task.color]);
|
|
4357
4383
|
const handleDragEnd = (result) => {
|
|
4358
4384
|
const updatedTask = {
|
|
4359
4385
|
...normalizedTask,
|
|
@@ -4427,6 +4453,35 @@ var TaskRow = React2.memo(
|
|
|
4427
4453
|
}, [displayLeft, dayWidth, milestoneGeometry.size]);
|
|
4428
4454
|
const visualLeft = milestone ? displayMilestoneGeometry.left : displayLeft;
|
|
4429
4455
|
const visualWidth = milestone ? displayMilestoneGeometry.size : displayWidth;
|
|
4456
|
+
const compositeSegments = useMemo2(() => {
|
|
4457
|
+
if (!task.composite || width <= 0) return [];
|
|
4458
|
+
const laneEnds = [];
|
|
4459
|
+
const segments2 = compositeChildren.map((child) => {
|
|
4460
|
+
const segment = calculateTaskBar(parseUTCDate(child.startDate), parseUTCDate(child.endDate), monthStart, dayWidth);
|
|
4461
|
+
let lane = Math.max(0, laneEnds.length - 1);
|
|
4462
|
+
if (laneEnds.length > 0 && segment.left < laneEnds[lane]) {
|
|
4463
|
+
lane = laneEnds.length;
|
|
4464
|
+
}
|
|
4465
|
+
laneEnds[lane] = segment.left + segment.width;
|
|
4466
|
+
return {
|
|
4467
|
+
id: child.id,
|
|
4468
|
+
name: child.name,
|
|
4469
|
+
left: (segment.left - left) / width * 100,
|
|
4470
|
+
width: segment.width / width * 100,
|
|
4471
|
+
lane,
|
|
4472
|
+
pxLeft: segment.left - left,
|
|
4473
|
+
cut: false
|
|
4474
|
+
};
|
|
4475
|
+
});
|
|
4476
|
+
const lastCutByLane = [];
|
|
4477
|
+
for (const segment of [...segments2].sort((a, b) => a.pxLeft - b.pxLeft)) {
|
|
4478
|
+
segment.cut = segment.pxLeft >= 1 && segment.pxLeft - (lastCutByLane[segment.lane] ?? 0) >= COMPOSITE_SEGMENT_CUT_MIN_PX;
|
|
4479
|
+
if (segment.cut) lastCutByLane[segment.lane] = segment.pxLeft;
|
|
4480
|
+
}
|
|
4481
|
+
return segments2;
|
|
4482
|
+
}, [task.composite, compositeChildren, monthStart, dayWidth, left, width, displayLeft]);
|
|
4483
|
+
const compositeLaneCount = Math.max(1, ...compositeSegments.map((segment) => segment.lane + 1));
|
|
4484
|
+
const shouldRenderCompositeSegments = showCompositeSegmentsProp && task.composite && compositeSegments.length > 0 && visualWidth / compositeSegments.length >= 22;
|
|
4430
4485
|
const shouldRenderBaseline = showBaseline && baselineGeometry !== null;
|
|
4431
4486
|
const hasPreviewPosition = isDragging || effectiveOverridePosition !== void 0;
|
|
4432
4487
|
const currentStartDate = hasPreviewPosition ? pixelsToDate(displayLeft, monthStart, dayWidth) : taskStartDate;
|
|
@@ -4444,17 +4499,20 @@ var TaskRow = React2.memo(
|
|
|
4444
4499
|
if (lastDigit >= 2 && lastDigit <= 4) return `${count} \u0440\u0430\u0431\u043E\u0442\u044B`;
|
|
4445
4500
|
return `${count} \u0440\u0430\u0431\u043E\u0442`;
|
|
4446
4501
|
};
|
|
4447
|
-
const estimatedTextWidth =
|
|
4448
|
-
const showProgressInside = !milestone && progressWidth > 0 && displayWidth > estimatedTextWidth;
|
|
4449
|
-
const MIN_DURATION_WIDTH =
|
|
4450
|
-
const showDurationInside = !milestone && durationDays >= 2 && displayWidth > MIN_DURATION_WIDTH;
|
|
4502
|
+
const estimatedTextWidth = isVisualParent ? 120 : durationDays >= 10 ? 76 : 62;
|
|
4503
|
+
const showProgressInside = !milestone && progressWidth > 0 && displayWidth > (compactDetail ? 28 : estimatedTextWidth);
|
|
4504
|
+
const MIN_DURATION_WIDTH = isVisualParent ? 80 : task.composite ? 92 : 50;
|
|
4505
|
+
const showDurationInside = !compactDetail && !milestone && durationDays >= 2 && displayWidth > MIN_DURATION_WIDTH;
|
|
4451
4506
|
return /* @__PURE__ */ jsxs2(
|
|
4452
4507
|
"div",
|
|
4453
4508
|
{
|
|
4454
4509
|
"data-filter-match": isFilterMatch ? "true" : "false",
|
|
4455
4510
|
"data-gantt-task-row-id": task.id,
|
|
4456
|
-
className: `gantt-tr-row ${isFilterMatch ? "gantt-tr-row-filter-match" : ""}`,
|
|
4457
|
-
style: {
|
|
4511
|
+
className: `gantt-tr-row ${compactDetail ? "gantt-tr-row-compositeDetail" : ""} ${isFilterMatch ? "gantt-tr-row-filter-match" : ""}`,
|
|
4512
|
+
style: {
|
|
4513
|
+
height: `${rowHeight}px`,
|
|
4514
|
+
"--gantt-tr-composite-detail-color": compositeParentColor ?? "var(--gantt-task-bar-default-color, #8b5cf6)"
|
|
4515
|
+
},
|
|
4458
4516
|
children: [
|
|
4459
4517
|
taskDivider === "top" && /* @__PURE__ */ jsx2("div", { className: "gantt-tr-divider gantt-tr-divider-top" }),
|
|
4460
4518
|
/* @__PURE__ */ jsxs2("div", { className: "gantt-tr-taskContainer", children: [
|
|
@@ -4472,7 +4530,11 @@ var TaskRow = React2.memo(
|
|
|
4472
4530
|
"div",
|
|
4473
4531
|
{
|
|
4474
4532
|
"data-taskbar": true,
|
|
4475
|
-
|
|
4533
|
+
role: task.composite ? "button" : void 0,
|
|
4534
|
+
tabIndex: task.composite ? 0 : void 0,
|
|
4535
|
+
"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,
|
|
4536
|
+
"aria-expanded": task.composite ? compositeExpanded : void 0,
|
|
4537
|
+
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" : ""}`,
|
|
4476
4538
|
style: {
|
|
4477
4539
|
left: `${visualLeft}px`,
|
|
4478
4540
|
...barStyle,
|
|
@@ -4482,14 +4544,57 @@ var TaskRow = React2.memo(
|
|
|
4482
4544
|
padding: 0
|
|
4483
4545
|
} : {
|
|
4484
4546
|
width: `${visualWidth}px`,
|
|
4485
|
-
height:
|
|
4547
|
+
height: compactDetail ? "18px" : isVisualParent ? "var(--gantt-parent-bar-height, 14px)" : "var(--gantt-task-bar-height)"
|
|
4486
4548
|
},
|
|
4487
4549
|
cursor: dragHandleProps.style.cursor,
|
|
4488
4550
|
userSelect: dragHandleProps.style.userSelect
|
|
4489
4551
|
},
|
|
4490
4552
|
onMouseDown: dragHandleProps.onMouseDown,
|
|
4491
4553
|
onMouseMove: dragHandleProps.onMouseMove,
|
|
4492
|
-
onMouseLeave:
|
|
4554
|
+
onMouseLeave: () => {
|
|
4555
|
+
dragHandleProps.onMouseLeave();
|
|
4556
|
+
setShowCompositePreview(false);
|
|
4557
|
+
},
|
|
4558
|
+
onMouseEnter: task.composite ? (event) => {
|
|
4559
|
+
const rect = event.currentTarget.getBoundingClientRect();
|
|
4560
|
+
const previewWidth = 220;
|
|
4561
|
+
const previewHeight = Math.min(340, 68 + Math.min(compositeChildren.length, 12) * 20);
|
|
4562
|
+
setCompositePreviewPosition({
|
|
4563
|
+
left: Math.max(8, Math.min(rect.left, window.innerWidth - previewWidth - 8)),
|
|
4564
|
+
top: rect.bottom + previewHeight + 8 < window.innerHeight ? rect.bottom + 6 : Math.max(8, rect.top - previewHeight - 6)
|
|
4565
|
+
});
|
|
4566
|
+
setShowCompositePreview(true);
|
|
4567
|
+
} : void 0,
|
|
4568
|
+
onMouseDownCapture: task.composite ? (event) => {
|
|
4569
|
+
suppressCompositeClick.current = Boolean(event.target.closest(".gantt-tr-resizeHandle"));
|
|
4570
|
+
pointerStart.current = { x: event.clientX, y: event.clientY };
|
|
4571
|
+
} : void 0,
|
|
4572
|
+
onMouseMoveCapture: task.composite ? (event) => {
|
|
4573
|
+
const start = pointerStart.current;
|
|
4574
|
+
if (start && Math.hypot(event.clientX - start.x, event.clientY - start.y) >= 4) {
|
|
4575
|
+
suppressCompositeClick.current = true;
|
|
4576
|
+
}
|
|
4577
|
+
} : void 0,
|
|
4578
|
+
onMouseUpCapture: task.composite ? (event) => {
|
|
4579
|
+
const start = pointerStart.current;
|
|
4580
|
+
if (start && Math.hypot(event.clientX - start.x, event.clientY - start.y) >= 4) {
|
|
4581
|
+
suppressCompositeClick.current = true;
|
|
4582
|
+
}
|
|
4583
|
+
pointerStart.current = null;
|
|
4584
|
+
} : void 0,
|
|
4585
|
+
onClick: task.composite ? () => {
|
|
4586
|
+
if (!isDragging && !suppressCompositeClick.current) {
|
|
4587
|
+
setShowCompositePreview(false);
|
|
4588
|
+
onCompositeToggle?.("click");
|
|
4589
|
+
}
|
|
4590
|
+
suppressCompositeClick.current = false;
|
|
4591
|
+
} : void 0,
|
|
4592
|
+
onKeyDown: task.composite ? (event) => {
|
|
4593
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
4594
|
+
event.preventDefault();
|
|
4595
|
+
onCompositeToggle?.("keyboard");
|
|
4596
|
+
}
|
|
4597
|
+
} : void 0,
|
|
4493
4598
|
children: [
|
|
4494
4599
|
!milestone && progressWidth > 0 && progressWidth < 100 && /* @__PURE__ */ jsx2(
|
|
4495
4600
|
"div",
|
|
@@ -4498,14 +4603,42 @@ var TaskRow = React2.memo(
|
|
|
4498
4603
|
style: {
|
|
4499
4604
|
width: `${progressWidth}%`,
|
|
4500
4605
|
backgroundColor: progressColor,
|
|
4501
|
-
...
|
|
4606
|
+
...isVisualParent && {
|
|
4502
4607
|
borderRadius: "var(--gantt-parent-bar-radius, 8px) 0 0 0"
|
|
4503
4608
|
}
|
|
4504
4609
|
}
|
|
4505
4610
|
}
|
|
4506
4611
|
),
|
|
4507
4612
|
!milestone && /* @__PURE__ */ jsx2("div", { className: "gantt-tr-resizeHandle gantt-tr-resizeHandleLeft" }),
|
|
4508
|
-
|
|
4613
|
+
shouldRenderCompositeSegments && /* @__PURE__ */ jsxs2("span", { className: "gantt-tr-compositeSegments", "aria-hidden": "true", children: [
|
|
4614
|
+
compositeSegments.map((segment) => /* @__PURE__ */ jsx2(
|
|
4615
|
+
"span",
|
|
4616
|
+
{
|
|
4617
|
+
className: "gantt-tr-compositeSegment",
|
|
4618
|
+
style: {
|
|
4619
|
+
left: `${segment.left}%`,
|
|
4620
|
+
width: `${segment.width}%`,
|
|
4621
|
+
top: `${segment.lane / compositeLaneCount * 100}%`,
|
|
4622
|
+
height: `${100 / compositeLaneCount}%`
|
|
4623
|
+
}
|
|
4624
|
+
},
|
|
4625
|
+
segment.id
|
|
4626
|
+
)),
|
|
4627
|
+
compositeSegments.map((segment) => segment.cut ? /* @__PURE__ */ jsx2(
|
|
4628
|
+
"span",
|
|
4629
|
+
{
|
|
4630
|
+
className: "gantt-tr-compositeSegmentCut",
|
|
4631
|
+
style: {
|
|
4632
|
+
left: `${segment.left}%`,
|
|
4633
|
+
top: `${segment.lane / compositeLaneCount * 100}%`,
|
|
4634
|
+
height: `${100 / compositeLaneCount}%`
|
|
4635
|
+
}
|
|
4636
|
+
},
|
|
4637
|
+
`${segment.id}-cut`
|
|
4638
|
+
) : null)
|
|
4639
|
+
] }),
|
|
4640
|
+
task.composite && /* @__PURE__ */ jsx2("span", { className: "gantt-tr-compositeHoverChevron", "aria-hidden": "true", children: /* @__PURE__ */ jsx2("svg", { className: `gantt-tr-compositeChevron${compositeExpanded ? " gantt-tr-compositeChevron-open" : ""}`, viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx2("path", { d: "m7 4 6 6-6 6", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }) }),
|
|
4641
|
+
showDurationInside && /* @__PURE__ */ jsx2("span", { className: "gantt-tr-taskDuration", children: isVisualParent ? getChildCountLabel(childCount) : `${durationDays} \u0434` }),
|
|
4509
4642
|
progressWidth > 0 && showProgressInside && /* @__PURE__ */ jsxs2("span", { className: "gantt-tr-progressText", children: [
|
|
4510
4643
|
progressWidth,
|
|
4511
4644
|
"%"
|
|
@@ -4514,6 +4647,41 @@ var TaskRow = React2.memo(
|
|
|
4514
4647
|
]
|
|
4515
4648
|
}
|
|
4516
4649
|
),
|
|
4650
|
+
task.composite && showCompositePreview && compositePreviewPosition && compositeChildren.length > 0 && !isDragging && typeof document !== "undefined" && createPortal(
|
|
4651
|
+
/* @__PURE__ */ jsxs2(
|
|
4652
|
+
"div",
|
|
4653
|
+
{
|
|
4654
|
+
className: "gantt-tr-compositePreview",
|
|
4655
|
+
style: { left: `${compositePreviewPosition.left}px`, top: `${compositePreviewPosition.top}px` },
|
|
4656
|
+
role: "tooltip",
|
|
4657
|
+
children: [
|
|
4658
|
+
/* @__PURE__ */ jsxs2("div", { className: "gantt-tr-compositePreviewAxis", children: [
|
|
4659
|
+
/* @__PURE__ */ jsx2("span", { children: formatCompositePreviewDate(currentStartDate) }),
|
|
4660
|
+
/* @__PURE__ */ jsx2("span", { children: formatCompositePreviewDate(currentEndDate) })
|
|
4661
|
+
] }),
|
|
4662
|
+
compositeChildren.slice(0, 12).map((child) => /* @__PURE__ */ jsxs2("div", { className: "gantt-tr-compositePreviewRow", children: [
|
|
4663
|
+
/* @__PURE__ */ jsx2("span", { children: child.name }),
|
|
4664
|
+
/* @__PURE__ */ jsx2("span", { className: "gantt-tr-compositePreviewTrack", children: /* @__PURE__ */ jsx2(
|
|
4665
|
+
"span",
|
|
4666
|
+
{
|
|
4667
|
+
className: "gantt-tr-compositePreviewBar",
|
|
4668
|
+
style: {
|
|
4669
|
+
left: `${Math.max(0, (parseUTCDate(child.startDate).getTime() - taskStartDate.getTime()) / (taskEndDate.getTime() - taskStartDate.getTime() + 864e5) * 100)}%`,
|
|
4670
|
+
width: `${Math.max(2, (parseUTCDate(child.endDate).getTime() - parseUTCDate(child.startDate).getTime() + 864e5) / (taskEndDate.getTime() - taskStartDate.getTime() + 864e5) * 100)}%`,
|
|
4671
|
+
backgroundColor: barColor
|
|
4672
|
+
}
|
|
4673
|
+
}
|
|
4674
|
+
) })
|
|
4675
|
+
] }, child.id)),
|
|
4676
|
+
compositeChildren.length > 12 && /* @__PURE__ */ jsxs2("div", { children: [
|
|
4677
|
+
"+",
|
|
4678
|
+
compositeChildren.length - 12
|
|
4679
|
+
] })
|
|
4680
|
+
]
|
|
4681
|
+
}
|
|
4682
|
+
),
|
|
4683
|
+
document.body
|
|
4684
|
+
),
|
|
4517
4685
|
!disableDependencyEditing && onDependencyPortPointerDown && /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
4518
4686
|
/* @__PURE__ */ jsx2(
|
|
4519
4687
|
"button",
|
|
@@ -4522,7 +4690,7 @@ var TaskRow = React2.memo(
|
|
|
4522
4690
|
"data-gantt-dependency-port": true,
|
|
4523
4691
|
"data-task-id": task.id,
|
|
4524
4692
|
"data-port-side": "left",
|
|
4525
|
-
className: `gantt-tr-dependencyPort gantt-tr-dependencyPortLeft ${milestone ? "gantt-tr-dependencyPortMilestone" : ""} ${
|
|
4693
|
+
className: `gantt-tr-dependencyPort gantt-tr-dependencyPortLeft ${milestone ? "gantt-tr-dependencyPortMilestone" : ""} ${isVisualParent ? "gantt-tr-dependencyPortParent" : ""} ${isDependencyDragActive ? "gantt-tr-dependencyPortDragActive" : ""}`,
|
|
4526
4694
|
style: { left: `${visualLeft - 24}px` },
|
|
4527
4695
|
"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}`,
|
|
4528
4696
|
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",
|
|
@@ -4536,7 +4704,7 @@ var TaskRow = React2.memo(
|
|
|
4536
4704
|
"data-gantt-dependency-port": true,
|
|
4537
4705
|
"data-task-id": task.id,
|
|
4538
4706
|
"data-port-side": "right",
|
|
4539
|
-
className: `gantt-tr-dependencyPort gantt-tr-dependencyPortRight ${milestone ? "gantt-tr-dependencyPortMilestone" : ""} ${
|
|
4707
|
+
className: `gantt-tr-dependencyPort gantt-tr-dependencyPortRight ${milestone ? "gantt-tr-dependencyPortMilestone" : ""} ${isVisualParent ? "gantt-tr-dependencyPortParent" : ""} ${isDependencyDragActive ? "gantt-tr-dependencyPortDragActive" : ""}`,
|
|
4540
4708
|
style: { left: `${visualLeft + visualWidth}px` },
|
|
4541
4709
|
"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}`,
|
|
4542
4710
|
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",
|
|
@@ -4575,6 +4743,14 @@ var TaskRow = React2.memo(
|
|
|
4575
4743
|
children: /* @__PURE__ */ jsx2("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" })
|
|
4576
4744
|
}
|
|
4577
4745
|
),
|
|
4746
|
+
!showDurationInside && !milestone && /* @__PURE__ */ jsx2(
|
|
4747
|
+
"span",
|
|
4748
|
+
{
|
|
4749
|
+
className: `gantt-tr-externalDuration gantt-tr-durationBeforeBar${compactDetail ? " gantt-tr-compositeDuration" : ""}`,
|
|
4750
|
+
style: { left: `${visualLeft - 46}px`, color: isParent ? task.color || defaultParentBarColor : barColor },
|
|
4751
|
+
children: isVisualParent ? getChildCountLabel(childCount) : `${durationDays} \u0434`
|
|
4752
|
+
}
|
|
4753
|
+
),
|
|
4578
4754
|
/* @__PURE__ */ jsxs2(
|
|
4579
4755
|
"div",
|
|
4580
4756
|
{
|
|
@@ -4584,7 +4760,6 @@ var TaskRow = React2.memo(
|
|
|
4584
4760
|
color: isParent ? task.color || defaultParentBarColor : barColor
|
|
4585
4761
|
},
|
|
4586
4762
|
children: [
|
|
4587
|
-
!showDurationInside && !milestone && /* @__PURE__ */ jsx2("span", { className: "gantt-tr-externalDuration", children: isParent ? getChildCountLabel(childCount) : `${durationDays} \u0434` }),
|
|
4588
4763
|
progressWidth > 0 && !showProgressInside && /* @__PURE__ */ jsxs2("span", { className: "gantt-tr-externalProgress", children: [
|
|
4589
4764
|
progressWidth,
|
|
4590
4765
|
"%"
|
|
@@ -4849,7 +5024,7 @@ var DragGuideLines = ({
|
|
|
4849
5024
|
var DragGuideLines_default = DragGuideLines;
|
|
4850
5025
|
|
|
4851
5026
|
// src/components/DependencyLines/DependencyLines.tsx
|
|
4852
|
-
import React6, { useMemo as useMemo6, useState as
|
|
5027
|
+
import React6, { useMemo as useMemo6, useState as useState3 } from "react";
|
|
4853
5028
|
import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
4854
5029
|
function isTaskHidden(taskId, collapsedParentIds, taskMap) {
|
|
4855
5030
|
const task = taskMap.get(taskId);
|
|
@@ -4888,6 +5063,8 @@ var DependencyLines = React6.memo(({
|
|
|
4888
5063
|
gridWidth,
|
|
4889
5064
|
totalHeight,
|
|
4890
5065
|
rowIndexByTaskId,
|
|
5066
|
+
rowTops,
|
|
5067
|
+
rowHeights,
|
|
4891
5068
|
dragOverrides,
|
|
4892
5069
|
selectedDep,
|
|
4893
5070
|
criticalTaskIds,
|
|
@@ -4895,7 +5072,7 @@ var DependencyLines = React6.memo(({
|
|
|
4895
5072
|
weekendPredicate,
|
|
4896
5073
|
onDependencyClick
|
|
4897
5074
|
}) => {
|
|
4898
|
-
const [hoveredLineId, setHoveredLineId] =
|
|
5075
|
+
const [hoveredLineId, setHoveredLineId] = useState3(null);
|
|
4899
5076
|
const tasksForPositions = allTasks ?? tasks;
|
|
4900
5077
|
const { taskPositions, taskIndices, hiddenTaskIds } = useMemo6(() => {
|
|
4901
5078
|
const positions = /* @__PURE__ */ new Map();
|
|
@@ -4911,7 +5088,8 @@ var DependencyLines = React6.memo(({
|
|
|
4911
5088
|
left: computed.left,
|
|
4912
5089
|
right: computed.right,
|
|
4913
5090
|
centerX: computed.centerX,
|
|
4914
|
-
rowTop: rowIndex * rowHeight,
|
|
5091
|
+
rowTop: rowTops?.[rowIndex] ?? rowIndex * rowHeight,
|
|
5092
|
+
rowHeight: rowHeights?.[rowIndex] ?? rowHeight,
|
|
4915
5093
|
isVirtual: false
|
|
4916
5094
|
});
|
|
4917
5095
|
});
|
|
@@ -4931,6 +5109,7 @@ var DependencyLines = React6.memo(({
|
|
|
4931
5109
|
right: computed.right,
|
|
4932
5110
|
centerX: computed.centerX,
|
|
4933
5111
|
rowTop: ancestorPosition.rowTop,
|
|
5112
|
+
rowHeight: ancestorPosition.rowHeight,
|
|
4934
5113
|
isVirtual: true
|
|
4935
5114
|
});
|
|
4936
5115
|
}
|
|
@@ -4944,18 +5123,19 @@ var DependencyLines = React6.memo(({
|
|
|
4944
5123
|
const override = dragOverrides?.get(task.id);
|
|
4945
5124
|
const computed = resolveTaskHorizontalGeometry(task, monthStart, dayWidth, override);
|
|
4946
5125
|
const rowIndex = rowIndexByTaskId?.get(task.id);
|
|
4947
|
-
const rowTop = rowIndex !== void 0 ? rowIndex * rowHeight : 0;
|
|
5126
|
+
const rowTop = rowIndex !== void 0 ? rowTops?.[rowIndex] ?? rowIndex * rowHeight : 0;
|
|
4948
5127
|
positions.set(task.id, {
|
|
4949
5128
|
left: computed.left,
|
|
4950
5129
|
right: computed.right,
|
|
4951
5130
|
centerX: computed.centerX,
|
|
4952
5131
|
rowTop,
|
|
5132
|
+
rowHeight: rowIndex !== void 0 ? rowHeights?.[rowIndex] ?? rowHeight : rowHeight,
|
|
4953
5133
|
isVirtual: false
|
|
4954
5134
|
});
|
|
4955
5135
|
}
|
|
4956
5136
|
}
|
|
4957
5137
|
return { taskPositions: positions, taskIndices: indices, hiddenTaskIds: hidden };
|
|
4958
|
-
}, [tasks, tasksForPositions, allTasks, collapsedParentIds, monthStart, dayWidth, rowHeight, dragOverrides, rowIndexByTaskId]);
|
|
5138
|
+
}, [tasks, tasksForPositions, allTasks, collapsedParentIds, monthStart, dayWidth, rowHeight, rowTops, rowHeights, dragOverrides, rowIndexByTaskId]);
|
|
4959
5139
|
const tasksForCycleDetection = allTasks ?? tasks;
|
|
4960
5140
|
const cycleInfo = useMemo6(() => {
|
|
4961
5141
|
const result = detectCycles(tasksForCycleDetection);
|
|
@@ -4997,7 +5177,9 @@ var DependencyLines = React6.memo(({
|
|
|
4997
5177
|
continue;
|
|
4998
5178
|
}
|
|
4999
5179
|
}
|
|
5000
|
-
|
|
5180
|
+
const predecessorVisibleId = predecessor.isVirtual ? findVisibleAncestor(taskMap.get(edge.predecessorId), collapsedParentIds, taskMap)?.id : edge.predecessorId;
|
|
5181
|
+
const successorVisibleId = successor.isVirtual ? findVisibleAncestor(taskMap.get(edge.successorId), collapsedParentIds, taskMap)?.id : edge.successorId;
|
|
5182
|
+
if (!renderedTaskIdSet.has(predecessorVisibleId ?? "") && !renderedTaskIdSet.has(successorVisibleId ?? "")) {
|
|
5001
5183
|
continue;
|
|
5002
5184
|
}
|
|
5003
5185
|
const isVirtual = predecessor.isVirtual || successor.isVirtual;
|
|
@@ -5011,9 +5193,9 @@ var DependencyLines = React6.memo(({
|
|
|
5011
5193
|
let toY;
|
|
5012
5194
|
if (reverseOrder) {
|
|
5013
5195
|
fromY = predecessor.rowTop + 10;
|
|
5014
|
-
toY = successor.rowTop + rowHeight - 6;
|
|
5196
|
+
toY = successor.rowTop + successor.rowHeight - 6;
|
|
5015
5197
|
} else {
|
|
5016
|
-
fromY = predecessor.rowTop + rowHeight - 10;
|
|
5198
|
+
fromY = predecessor.rowTop + predecessor.rowHeight - 10;
|
|
5017
5199
|
toY = successor.rowTop + 6;
|
|
5018
5200
|
}
|
|
5019
5201
|
let fromX = predecessorTask && isMilestoneTask(predecessorTask) ? predecessor.centerX : edge.type === "SS" || edge.type === "SF" ? predecessor.left : predecessor.right;
|
|
@@ -5289,7 +5471,7 @@ var DependencyCreationOverlay = ({ drag, width, height }) => {
|
|
|
5289
5471
|
};
|
|
5290
5472
|
|
|
5291
5473
|
// src/components/TaskList/TaskList.tsx
|
|
5292
|
-
import React13, { useMemo as useMemo9, useCallback as useCallback6, useState as
|
|
5474
|
+
import React13, { useMemo as useMemo9, useCallback as useCallback6, useState as useState8, useEffect as useEffect7, useRef as useRef8 } from "react";
|
|
5293
5475
|
|
|
5294
5476
|
// src/utils/taskListReorder.ts
|
|
5295
5477
|
function getDescendantIds(taskId, tasks) {
|
|
@@ -5494,9 +5676,9 @@ var PopoverContent = ({
|
|
|
5494
5676
|
|
|
5495
5677
|
// src/components/TaskList/TaskListRow.tsx
|
|
5496
5678
|
import React10, {
|
|
5497
|
-
useState as
|
|
5498
|
-
useRef as
|
|
5499
|
-
useEffect as
|
|
5679
|
+
useState as useState6,
|
|
5680
|
+
useRef as useRef5,
|
|
5681
|
+
useEffect as useEffect5,
|
|
5500
5682
|
useCallback as useCallback5,
|
|
5501
5683
|
useMemo as useMemo8
|
|
5502
5684
|
} from "react";
|
|
@@ -5519,14 +5701,14 @@ var Input = React7.forwardRef(
|
|
|
5519
5701
|
Input.displayName = "Input";
|
|
5520
5702
|
|
|
5521
5703
|
// src/components/ui/DatePicker.tsx
|
|
5522
|
-
import { useState as
|
|
5704
|
+
import { useState as useState5, useCallback as useCallback4, useEffect as useEffect4, useRef as useRef4 } from "react";
|
|
5523
5705
|
import { format as format3, isValid, parse, addDays, addMonths as addMonths2, addYears, subMonths as subMonths2, subYears, subDays } from "date-fns";
|
|
5524
5706
|
|
|
5525
5707
|
// src/components/ui/Calendar.tsx
|
|
5526
5708
|
import {
|
|
5527
|
-
useState as
|
|
5528
|
-
useRef as
|
|
5529
|
-
useEffect as
|
|
5709
|
+
useState as useState4,
|
|
5710
|
+
useRef as useRef3,
|
|
5711
|
+
useEffect as useEffect3,
|
|
5530
5712
|
useCallback as useCallback3,
|
|
5531
5713
|
useMemo as useMemo7
|
|
5532
5714
|
} from "react";
|
|
@@ -5561,13 +5743,13 @@ var Calendar = ({
|
|
|
5561
5743
|
disabled = false,
|
|
5562
5744
|
isWeekend: isWeekendProp
|
|
5563
5745
|
}) => {
|
|
5564
|
-
const scrollRef =
|
|
5746
|
+
const scrollRef = useRef3(null);
|
|
5565
5747
|
const initialMonth = useMemo7(
|
|
5566
5748
|
() => startOfMonth(initialDate ?? selected ?? /* @__PURE__ */ new Date()),
|
|
5567
5749
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
5568
5750
|
[]
|
|
5569
5751
|
);
|
|
5570
|
-
const [months, setMonths] =
|
|
5752
|
+
const [months, setMonths] = useState4(() => [
|
|
5571
5753
|
subMonths(initialMonth, 1),
|
|
5572
5754
|
initialMonth,
|
|
5573
5755
|
addMonths(initialMonth, 1)
|
|
@@ -5581,7 +5763,7 @@ var Calendar = ({
|
|
|
5581
5763
|
}
|
|
5582
5764
|
});
|
|
5583
5765
|
}, []);
|
|
5584
|
-
|
|
5766
|
+
useEffect3(() => {
|
|
5585
5767
|
const container = scrollRef.current;
|
|
5586
5768
|
if (!container) return;
|
|
5587
5769
|
const handleScroll = () => {
|
|
@@ -5599,7 +5781,7 @@ var Calendar = ({
|
|
|
5599
5781
|
container.addEventListener("scroll", handleScroll);
|
|
5600
5782
|
return () => container.removeEventListener("scroll", handleScroll);
|
|
5601
5783
|
}, [loadMoreMonths]);
|
|
5602
|
-
|
|
5784
|
+
useEffect3(() => {
|
|
5603
5785
|
if (!scrollRef.current) return;
|
|
5604
5786
|
const target = selected ?? initialDate ?? /* @__PURE__ */ new Date();
|
|
5605
5787
|
const monthKey = format2(startOfMonth(target), "yyyy-MM");
|
|
@@ -5704,12 +5886,12 @@ var DatePicker = ({
|
|
|
5704
5886
|
businessDays = true,
|
|
5705
5887
|
footer
|
|
5706
5888
|
}) => {
|
|
5707
|
-
const [open, setOpen] =
|
|
5708
|
-
const [inputValue, setInputValue] =
|
|
5709
|
-
const [draftDate, setDraftDate] =
|
|
5710
|
-
const dateInputRef =
|
|
5711
|
-
const segIdxRef =
|
|
5712
|
-
const charPosRef =
|
|
5889
|
+
const [open, setOpen] = useState5(false);
|
|
5890
|
+
const [inputValue, setInputValue] = useState5("");
|
|
5891
|
+
const [draftDate, setDraftDate] = useState5(void 0);
|
|
5892
|
+
const dateInputRef = useRef4(null);
|
|
5893
|
+
const segIdxRef = useRef4(0);
|
|
5894
|
+
const charPosRef = useRef4(0);
|
|
5713
5895
|
const selectedDate = (() => {
|
|
5714
5896
|
if (!value) return void 0;
|
|
5715
5897
|
const d = /* @__PURE__ */ new Date(value + "T00:00:00Z");
|
|
@@ -5717,7 +5899,7 @@ var DatePicker = ({
|
|
|
5717
5899
|
})();
|
|
5718
5900
|
const activeDate = draftDate ?? selectedDate;
|
|
5719
5901
|
const displayValue = selectedDate ? formatUTCDate(selectedDate, displayFormat) : placeholder;
|
|
5720
|
-
|
|
5902
|
+
useEffect4(() => {
|
|
5721
5903
|
if (value) {
|
|
5722
5904
|
const d = /* @__PURE__ */ new Date(value + "T00:00:00Z");
|
|
5723
5905
|
if (isValid(d)) {
|
|
@@ -5734,7 +5916,7 @@ var DatePicker = ({
|
|
|
5734
5916
|
const seg = segments[idx] ?? segments[0];
|
|
5735
5917
|
dateInputRef.current.setSelectionRange(seg.start, seg.end);
|
|
5736
5918
|
}, []);
|
|
5737
|
-
|
|
5919
|
+
useEffect4(() => {
|
|
5738
5920
|
if (open) {
|
|
5739
5921
|
setTimeout(() => {
|
|
5740
5922
|
if (dateInputRef.current) {
|
|
@@ -6333,10 +6515,10 @@ var DepChip = ({
|
|
|
6333
6515
|
businessDays = true,
|
|
6334
6516
|
weekendPredicate
|
|
6335
6517
|
}) => {
|
|
6336
|
-
const [popoverOpen, setPopoverOpen] =
|
|
6518
|
+
const [popoverOpen, setPopoverOpen] = useState6(false);
|
|
6337
6519
|
const lagAbs = Math.abs(lag ?? 0);
|
|
6338
|
-
const [inputAbs, setInputAbs] =
|
|
6339
|
-
|
|
6520
|
+
const [inputAbs, setInputAbs] = useState6(lagAbs === 0 ? "" : String(lagAbs));
|
|
6521
|
+
useEffect5(() => {
|
|
6340
6522
|
const abs = Math.abs(lag ?? 0);
|
|
6341
6523
|
setInputAbs(abs === 0 ? "" : String(abs));
|
|
6342
6524
|
}, [lag]);
|
|
@@ -6715,13 +6897,14 @@ var TaskListRow = React10.memo(
|
|
|
6715
6897
|
taskListMenuCommands = [],
|
|
6716
6898
|
hideTaskListRowActions = false,
|
|
6717
6899
|
rowClassName,
|
|
6900
|
+
compositeParentColor,
|
|
6718
6901
|
getTaskListNamePrefixIcon,
|
|
6719
6902
|
taskDateChangeMode = "preserve-duration",
|
|
6720
6903
|
onTaskDateChangeModeChange,
|
|
6721
6904
|
printDependencyLabels = false
|
|
6722
6905
|
}) => {
|
|
6723
|
-
const [editingColumnId, setEditingColumnId] =
|
|
6724
|
-
const [editingColumnStartValue, setEditingColumnStartValue] =
|
|
6906
|
+
const [editingColumnId, setEditingColumnId] = useState6(null);
|
|
6907
|
+
const [editingColumnStartValue, setEditingColumnStartValue] = useState6(void 0);
|
|
6725
6908
|
const editingName = editingColumnId === "name";
|
|
6726
6909
|
const editingDuration = editingColumnId === "duration";
|
|
6727
6910
|
const editingProgress = editingColumnId === "progress";
|
|
@@ -6752,27 +6935,27 @@ var TaskListRow = React10.memo(
|
|
|
6752
6935
|
}, [columnWidthStyleMap]);
|
|
6753
6936
|
const normalizedTask = useMemo8(() => normalizeTaskDatesForType(task), [task]);
|
|
6754
6937
|
const isMilestone = useMemo8(() => isMilestoneTask(normalizedTask), [normalizedTask]);
|
|
6755
|
-
const [nameValue, setNameValue] =
|
|
6756
|
-
const nameInputRef =
|
|
6757
|
-
const [durationValue, setDurationValue] =
|
|
6938
|
+
const [nameValue, setNameValue] = useState6("");
|
|
6939
|
+
const nameInputRef = useRef5(null);
|
|
6940
|
+
const [durationValue, setDurationValue] = useState6(
|
|
6758
6941
|
() => getInclusiveDurationDays(normalizedTask.startDate, normalizedTask.endDate)
|
|
6759
6942
|
);
|
|
6760
|
-
const durationInputRef =
|
|
6761
|
-
const dependencySearchInputRef =
|
|
6762
|
-
const dependencySearchListRef =
|
|
6763
|
-
const [progressValue, setProgressValue] =
|
|
6764
|
-
const progressInputRef =
|
|
6765
|
-
const [overflowOpen, setOverflowOpen] =
|
|
6766
|
-
const [contextMenuOpen, setContextMenuOpen] =
|
|
6767
|
-
const [colorMenuOpen, setColorMenuOpen] =
|
|
6768
|
-
const nameConfirmedRef =
|
|
6769
|
-
const durationConfirmedRef =
|
|
6770
|
-
const progressConfirmedRef =
|
|
6771
|
-
const autoEditedForRef =
|
|
6772
|
-
const editTriggerRef =
|
|
6943
|
+
const durationInputRef = useRef5(null);
|
|
6944
|
+
const dependencySearchInputRef = useRef5(null);
|
|
6945
|
+
const dependencySearchListRef = useRef5(null);
|
|
6946
|
+
const [progressValue, setProgressValue] = useState6(0);
|
|
6947
|
+
const progressInputRef = useRef5(null);
|
|
6948
|
+
const [overflowOpen, setOverflowOpen] = useState6(false);
|
|
6949
|
+
const [contextMenuOpen, setContextMenuOpen] = useState6(false);
|
|
6950
|
+
const [colorMenuOpen, setColorMenuOpen] = useState6(false);
|
|
6951
|
+
const nameConfirmedRef = useRef5(false);
|
|
6952
|
+
const durationConfirmedRef = useRef5(false);
|
|
6953
|
+
const progressConfirmedRef = useRef5(false);
|
|
6954
|
+
const autoEditedForRef = useRef5(null);
|
|
6955
|
+
const editTriggerRef = useRef5(
|
|
6773
6956
|
"doubleclick"
|
|
6774
6957
|
);
|
|
6775
|
-
const rowRef =
|
|
6958
|
+
const rowRef = useRef5(null);
|
|
6776
6959
|
const isSelected = selectedTaskId === task.id;
|
|
6777
6960
|
const isParent = useMemo8(
|
|
6778
6961
|
() => isTaskParent(task.id, allTasks),
|
|
@@ -6799,13 +6982,42 @@ var TaskListRow = React10.memo(
|
|
|
6799
6982
|
[businessDays, weekendPredicate]
|
|
6800
6983
|
);
|
|
6801
6984
|
const isCollapsed = collapsedParentIds.has(task.id);
|
|
6985
|
+
const [compositeIconMode, setCompositeIconMode] = useState6(
|
|
6986
|
+
() => isCollapsed ? "composite" : "down"
|
|
6987
|
+
);
|
|
6988
|
+
const compositeIconModeRef = useRef5(compositeIconMode);
|
|
6989
|
+
const [compositeIconAnimation, setCompositeIconAnimation] = useState6(null);
|
|
6990
|
+
const [compositeIconAnimationPhase, setCompositeIconAnimationPhase] = useState6(null);
|
|
6991
|
+
useEffect5(() => {
|
|
6992
|
+
const nextMode = isCollapsed ? "composite" : "down";
|
|
6993
|
+
if (nextMode === compositeIconModeRef.current) {
|
|
6994
|
+
setCompositeIconAnimation(null);
|
|
6995
|
+
setCompositeIconAnimationPhase(null);
|
|
6996
|
+
return;
|
|
6997
|
+
}
|
|
6998
|
+
setCompositeIconAnimation(isCollapsed ? "closing" : "opening");
|
|
6999
|
+
setCompositeIconAnimationPhase("outgoing");
|
|
7000
|
+
const swapTimeoutId = window.setTimeout(() => {
|
|
7001
|
+
compositeIconModeRef.current = nextMode;
|
|
7002
|
+
setCompositeIconMode(nextMode);
|
|
7003
|
+
setCompositeIconAnimationPhase("incoming");
|
|
7004
|
+
}, 120);
|
|
7005
|
+
const finishTimeoutId = window.setTimeout(() => {
|
|
7006
|
+
setCompositeIconAnimation(null);
|
|
7007
|
+
setCompositeIconAnimationPhase(null);
|
|
7008
|
+
}, 240);
|
|
7009
|
+
return () => {
|
|
7010
|
+
window.clearTimeout(swapTimeoutId);
|
|
7011
|
+
window.clearTimeout(finishTimeoutId);
|
|
7012
|
+
};
|
|
7013
|
+
}, [isCollapsed]);
|
|
6802
7014
|
const getHierarchyLineColor = useCallback5((columnDepth) => {
|
|
6803
7015
|
return columnDepth % 2 === 0 ? "#93c5fd" : "var(--gantt-hierarchy-line-color)";
|
|
6804
7016
|
}, []);
|
|
6805
7017
|
const isPicking = selectingPredecessorFor != null;
|
|
6806
7018
|
const isSourceRow = isPicking && selectingPredecessorFor === task.id;
|
|
6807
|
-
const [dependencySearchQuery, setDependencySearchQuery] =
|
|
6808
|
-
const [highlightedDependencyIndex, setHighlightedDependencyIndex] =
|
|
7019
|
+
const [dependencySearchQuery, setDependencySearchQuery] = useState6("");
|
|
7020
|
+
const [highlightedDependencyIndex, setHighlightedDependencyIndex] = useState6(0);
|
|
6809
7021
|
const chips = useMemo8(() => {
|
|
6810
7022
|
const taskById = new Map((allTasks ?? []).map((t) => [t.id, t]));
|
|
6811
7023
|
return (task.dependencies ?? []).map((dep) => {
|
|
@@ -6842,7 +7054,7 @@ var TaskListRow = React10.memo(
|
|
|
6842
7054
|
taskNumberMap,
|
|
6843
7055
|
task.dependencies
|
|
6844
7056
|
]);
|
|
6845
|
-
|
|
7057
|
+
useEffect5(() => {
|
|
6846
7058
|
if (editingName && nameInputRef.current) {
|
|
6847
7059
|
nameInputRef.current.focus();
|
|
6848
7060
|
if (editTriggerRef.current === "keypress") {
|
|
@@ -6853,15 +7065,15 @@ var TaskListRow = React10.memo(
|
|
|
6853
7065
|
}
|
|
6854
7066
|
}
|
|
6855
7067
|
}, [editingName]);
|
|
6856
|
-
|
|
7068
|
+
useEffect5(() => {
|
|
6857
7069
|
if (!isSourceRow && dependencySearchQuery !== "") {
|
|
6858
7070
|
setDependencySearchQuery("");
|
|
6859
7071
|
}
|
|
6860
7072
|
}, [isSourceRow, dependencySearchQuery]);
|
|
6861
|
-
|
|
7073
|
+
useEffect5(() => {
|
|
6862
7074
|
setHighlightedDependencyIndex(0);
|
|
6863
7075
|
}, [dependencySearchQuery, isSourceRow, dependencyPickMode]);
|
|
6864
|
-
|
|
7076
|
+
useEffect5(() => {
|
|
6865
7077
|
if (dependencySearchCandidates.length === 0) {
|
|
6866
7078
|
setHighlightedDependencyIndex(0);
|
|
6867
7079
|
return;
|
|
@@ -6870,13 +7082,13 @@ var TaskListRow = React10.memo(
|
|
|
6870
7082
|
setHighlightedDependencyIndex(dependencySearchCandidates.length - 1);
|
|
6871
7083
|
}
|
|
6872
7084
|
}, [dependencySearchCandidates, highlightedDependencyIndex]);
|
|
6873
|
-
|
|
7085
|
+
useEffect5(() => {
|
|
6874
7086
|
if (isSourceRow && dependencySearchInputRef.current) {
|
|
6875
7087
|
dependencySearchInputRef.current.focus();
|
|
6876
7088
|
dependencySearchInputRef.current.select();
|
|
6877
7089
|
}
|
|
6878
7090
|
}, [isSourceRow, dependencyPickMode, activeLinkType]);
|
|
6879
|
-
|
|
7091
|
+
useEffect5(() => {
|
|
6880
7092
|
if (!isSourceRow || dependencySearchCandidates.length === 0) {
|
|
6881
7093
|
return;
|
|
6882
7094
|
}
|
|
@@ -6888,7 +7100,7 @@ var TaskListRow = React10.memo(
|
|
|
6888
7100
|
block: "nearest"
|
|
6889
7101
|
});
|
|
6890
7102
|
}, [isSourceRow, highlightedDependencyIndex, dependencySearchCandidates]);
|
|
6891
|
-
|
|
7103
|
+
useEffect5(() => {
|
|
6892
7104
|
if (editingTaskId === task.id && !disableTaskNameEditing && autoEditedForRef.current !== editingTaskId) {
|
|
6893
7105
|
autoEditedForRef.current = editingTaskId;
|
|
6894
7106
|
nameConfirmedRef.current = false;
|
|
@@ -6907,6 +7119,7 @@ var TaskListRow = React10.memo(
|
|
|
6907
7119
|
);
|
|
6908
7120
|
const handleNameDoubleClick = useCallback5(
|
|
6909
7121
|
(e) => {
|
|
7122
|
+
if (task.composite) return;
|
|
6910
7123
|
if (disableTaskNameEditing) return;
|
|
6911
7124
|
e.stopPropagation();
|
|
6912
7125
|
nameConfirmedRef.current = false;
|
|
@@ -6914,7 +7127,7 @@ var TaskListRow = React10.memo(
|
|
|
6914
7127
|
setNameValue(task.name);
|
|
6915
7128
|
setEditingColumnId("name");
|
|
6916
7129
|
},
|
|
6917
|
-
[task.name, disableTaskNameEditing]
|
|
7130
|
+
[task.name, task.composite, disableTaskNameEditing]
|
|
6918
7131
|
);
|
|
6919
7132
|
const handleRowKeyDown = useCallback5(
|
|
6920
7133
|
(e) => {
|
|
@@ -7069,16 +7282,16 @@ var TaskListRow = React10.memo(
|
|
|
7069
7282
|
},
|
|
7070
7283
|
[progressValue, task, onTasksChange, handleProgressCancel, allTasks]
|
|
7071
7284
|
);
|
|
7072
|
-
|
|
7285
|
+
useEffect5(() => {
|
|
7073
7286
|
if (editingProgress && progressInputRef.current) {
|
|
7074
7287
|
progressInputRef.current.focus();
|
|
7075
7288
|
progressInputRef.current.select();
|
|
7076
7289
|
}
|
|
7077
7290
|
}, [editingProgress]);
|
|
7078
|
-
|
|
7291
|
+
useEffect5(() => {
|
|
7079
7292
|
setDurationValue(getDuration(normalizedTask.startDate, normalizedTask.endDate));
|
|
7080
7293
|
}, [normalizedTask.startDate, normalizedTask.endDate, getDuration]);
|
|
7081
|
-
|
|
7294
|
+
useEffect5(() => {
|
|
7082
7295
|
if (editingDuration && durationInputRef.current) {
|
|
7083
7296
|
durationInputRef.current.focus();
|
|
7084
7297
|
durationInputRef.current.select();
|
|
@@ -7563,7 +7776,7 @@ var TaskListRow = React10.memo(
|
|
|
7563
7776
|
]
|
|
7564
7777
|
}
|
|
7565
7778
|
);
|
|
7566
|
-
const nameTriggerPaddingLeft = isParent ? `${nestingDepth * 20 + 28}px` : nestingDepth > 0 ? `${nestingDepth * 20 + 8}px` : void 0;
|
|
7779
|
+
const nameTriggerPaddingLeft = isParent && !task.composite ? `${nestingDepth * 20 + 28}px` : nestingDepth > 0 ? `${nestingDepth * 20 + 8}px` : void 0;
|
|
7567
7780
|
const nameInputPaddingLeft = nestingDepth > 0 ? `${nestingDepth * 20 + 8}px` : void 0;
|
|
7568
7781
|
const nestedDropIndicatorLeft = (() => {
|
|
7569
7782
|
const numberColumnWidth = resolvedColumns?.find((col) => col.id === "number")?.width ?? 40;
|
|
@@ -7661,36 +7874,35 @@ var TaskListRow = React10.memo(
|
|
|
7661
7874
|
}
|
|
7662
7875
|
)
|
|
7663
7876
|
] }),
|
|
7664
|
-
|
|
7665
|
-
|
|
7666
|
-
|
|
7667
|
-
|
|
7668
|
-
|
|
7669
|
-
|
|
7670
|
-
|
|
7671
|
-
|
|
7672
|
-
|
|
7673
|
-
|
|
7674
|
-
|
|
7675
|
-
|
|
7676
|
-
|
|
7677
|
-
}
|
|
7678
|
-
}
|
|
7679
|
-
),
|
|
7680
|
-
/* @__PURE__ */ jsx14(
|
|
7681
|
-
"button",
|
|
7682
|
-
{
|
|
7683
|
-
type: "button",
|
|
7684
|
-
className: `gantt-tl-collapse-btn ${isCollapsed ? "gantt-tl-collapse-btn-collapsed" : ""}`,
|
|
7685
|
-
onClick: handleToggleCollapse,
|
|
7686
|
-
style: { left: `${nestingDepth * 20 + 1}px` },
|
|
7687
|
-
"aria-label": isCollapsed ? "Expand children" : "Collapse children",
|
|
7688
|
-
children: /* @__PURE__ */ jsx14(ChevronRightIcon, {})
|
|
7877
|
+
task.composite && !isFilterHideMode && !isCollapsed && !editingName && /* @__PURE__ */ jsx14(
|
|
7878
|
+
"span",
|
|
7879
|
+
{
|
|
7880
|
+
"data-testid": "gantt-tl-parent-connector-tail",
|
|
7881
|
+
style: {
|
|
7882
|
+
position: "absolute",
|
|
7883
|
+
left: `${nestingDepth * 20 + 9}px`,
|
|
7884
|
+
top: `${rowHeight / 2 + 7}px`,
|
|
7885
|
+
height: `${rowHeight / 2 - 7}px`,
|
|
7886
|
+
width: "1.5px",
|
|
7887
|
+
background: getHierarchyLineColor(nestingDepth),
|
|
7888
|
+
borderRadius: "1px",
|
|
7889
|
+
pointerEvents: "none"
|
|
7689
7890
|
}
|
|
7690
|
-
|
|
7691
|
-
|
|
7891
|
+
}
|
|
7892
|
+
),
|
|
7893
|
+
isParent && !task.composite && !editingName && /* @__PURE__ */ jsx14(Fragment3, { children: /* @__PURE__ */ jsx14(
|
|
7894
|
+
"button",
|
|
7895
|
+
{
|
|
7896
|
+
type: "button",
|
|
7897
|
+
className: `gantt-tl-collapse-btn ${isCollapsed ? "gantt-tl-collapse-btn-collapsed" : ""}`,
|
|
7898
|
+
onClick: handleToggleCollapse,
|
|
7899
|
+
style: { left: `${nestingDepth * 20 - 2}px` },
|
|
7900
|
+
"aria-label": isCollapsed ? "Expand children" : "Collapse children",
|
|
7901
|
+
children: /* @__PURE__ */ jsx14(ChevronRightIcon, {})
|
|
7902
|
+
}
|
|
7903
|
+
) })
|
|
7692
7904
|
] }),
|
|
7693
|
-
!isChild && isParent && !editingName && /* @__PURE__ */ jsxs10(Fragment3, { children: [
|
|
7905
|
+
!isChild && isParent && !task.composite && !editingName && /* @__PURE__ */ jsxs10(Fragment3, { children: [
|
|
7694
7906
|
!isFilterHideMode && !isCollapsed && /* @__PURE__ */ jsx14(
|
|
7695
7907
|
"span",
|
|
7696
7908
|
{
|
|
@@ -7713,7 +7925,7 @@ var TaskListRow = React10.memo(
|
|
|
7713
7925
|
type: "button",
|
|
7714
7926
|
className: `gantt-tl-collapse-btn ${isCollapsed ? "gantt-tl-collapse-btn-collapsed" : ""}`,
|
|
7715
7927
|
onClick: handleToggleCollapse,
|
|
7716
|
-
style: { left: `${nestingDepth * 20
|
|
7928
|
+
style: { left: `${nestingDepth * 20 - 2}px` },
|
|
7717
7929
|
"aria-label": isCollapsed ? "Expand children" : "Collapse children",
|
|
7718
7930
|
children: /* @__PURE__ */ jsx14(ChevronRightIcon, {})
|
|
7719
7931
|
}
|
|
@@ -7732,27 +7944,57 @@ var TaskListRow = React10.memo(
|
|
|
7732
7944
|
style: { paddingLeft: nameInputPaddingLeft },
|
|
7733
7945
|
onClick: (e) => e.stopPropagation()
|
|
7734
7946
|
}
|
|
7735
|
-
) : /* @__PURE__ */ jsxs10(
|
|
7736
|
-
|
|
7737
|
-
|
|
7738
|
-
|
|
7739
|
-
|
|
7740
|
-
"gantt-tl-
|
|
7741
|
-
|
|
7742
|
-
|
|
7743
|
-
|
|
7744
|
-
|
|
7745
|
-
|
|
7746
|
-
|
|
7747
|
-
|
|
7748
|
-
|
|
7749
|
-
|
|
7750
|
-
|
|
7751
|
-
|
|
7752
|
-
|
|
7753
|
-
|
|
7754
|
-
|
|
7755
|
-
|
|
7947
|
+
) : /* @__PURE__ */ jsxs10(Fragment3, { children: [
|
|
7948
|
+
task.composite && /* @__PURE__ */ jsx14(
|
|
7949
|
+
"button",
|
|
7950
|
+
{
|
|
7951
|
+
type: "button",
|
|
7952
|
+
className: "gantt-tl-compositeToggle",
|
|
7953
|
+
onClick: handleToggleCollapse,
|
|
7954
|
+
style: { left: `${nestingDepth * 20 - 3}px` },
|
|
7955
|
+
"aria-label": isCollapsed ? `\u0420\u0430\u0441\u043A\u0440\u044B\u0442\u044C ${task.name}` : `\u0421\u0432\u0435\u0440\u043D\u0443\u0442\u044C ${task.name}`,
|
|
7956
|
+
"aria-expanded": !isCollapsed,
|
|
7957
|
+
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",
|
|
7958
|
+
children: /* @__PURE__ */ jsx14(
|
|
7959
|
+
"svg",
|
|
7960
|
+
{
|
|
7961
|
+
className: compositeIconAnimation && compositeIconAnimationPhase ? `gantt-tl-compositeGlyph-${compositeIconMode}-${compositeIconAnimation}-${compositeIconAnimationPhase}` : void 0,
|
|
7962
|
+
viewBox: "0 0 24 24",
|
|
7963
|
+
fill: "none",
|
|
7964
|
+
stroke: "currentColor",
|
|
7965
|
+
strokeWidth: "2",
|
|
7966
|
+
strokeLinecap: "round",
|
|
7967
|
+
strokeLinejoin: "round",
|
|
7968
|
+
"aria-hidden": "true",
|
|
7969
|
+
children: compositeIconMode === "composite" ? /* @__PURE__ */ jsxs10(Fragment3, { children: [
|
|
7970
|
+
/* @__PURE__ */ jsx14("path", { d: "M21 5H11" }),
|
|
7971
|
+
/* @__PURE__ */ jsx14("path", { d: "M21 12H11" }),
|
|
7972
|
+
/* @__PURE__ */ jsx14("path", { d: "M21 19H11" }),
|
|
7973
|
+
/* @__PURE__ */ jsx14("path", { d: "m3 8 4 4-4 4" })
|
|
7974
|
+
] }) : /* @__PURE__ */ jsx14("path", { d: "m6 9 6 6 6-6" })
|
|
7975
|
+
}
|
|
7976
|
+
)
|
|
7977
|
+
}
|
|
7978
|
+
),
|
|
7979
|
+
/* @__PURE__ */ jsxs10(
|
|
7980
|
+
"button",
|
|
7981
|
+
{
|
|
7982
|
+
type: "button",
|
|
7983
|
+
className: `gantt-tl-name-trigger${disableTaskNameEditing ? " gantt-tl-name-locked" : ""}`,
|
|
7984
|
+
title: task.name,
|
|
7985
|
+
onClick: handleNameClick,
|
|
7986
|
+
onDoubleClick: handleNameDoubleClick,
|
|
7987
|
+
style: {
|
|
7988
|
+
paddingLeft: task.composite ? `${nestingDepth * 20 + 30}px` : nameTriggerPaddingLeft,
|
|
7989
|
+
paddingRight: task.color ? "20px" : void 0
|
|
7990
|
+
},
|
|
7991
|
+
children: [
|
|
7992
|
+
taskListNamePrefixIcon ? /* @__PURE__ */ jsx14("span", { className: "gantt-tl-name-trigger-icon", "aria-hidden": "true", children: taskListNamePrefixIcon }) : null,
|
|
7993
|
+
/* @__PURE__ */ jsx14("span", { className: "gantt-tl-name-trigger-text", children: task.name })
|
|
7994
|
+
]
|
|
7995
|
+
}
|
|
7996
|
+
)
|
|
7997
|
+
] }),
|
|
7756
7998
|
!editingName && task.color && /* @__PURE__ */ jsx14(
|
|
7757
7999
|
"span",
|
|
7758
8000
|
{
|
|
@@ -8369,8 +8611,9 @@ var TaskListRow = React10.memo(
|
|
|
8369
8611
|
isDragOver && isNestedDropTarget ? "gantt-tl-row-drag-over-nested" : "",
|
|
8370
8612
|
isDragOver && isDirectChildDropTarget ? "gantt-tl-row-drag-over-direct-child" : "",
|
|
8371
8613
|
isChild ? "gantt-tl-row-child" : "",
|
|
8372
|
-
isParent ? "gantt-tl-row-parent" : "",
|
|
8373
|
-
|
|
8614
|
+
isParent && !task.composite ? "gantt-tl-row-parent" : "",
|
|
8615
|
+
task.composite ? "gantt-tl-row-composite" : "",
|
|
8616
|
+
isParent && !task.composite && fillParentRow ? "gantt-tl-row-parent-filled" : "",
|
|
8374
8617
|
`gantt-tl-row-level-${rowFillLevel}`,
|
|
8375
8618
|
isTotalRow ? "gantt-tl-row-total" : "",
|
|
8376
8619
|
rowClassName ?? ""
|
|
@@ -8378,6 +8621,7 @@ var TaskListRow = React10.memo(
|
|
|
8378
8621
|
style: {
|
|
8379
8622
|
height: `${rowHeight}px`,
|
|
8380
8623
|
position: "relative",
|
|
8624
|
+
"--gantt-tl-composite-detail-color": compositeParentColor ?? "var(--gantt-task-bar-default-color, #8b5cf6)",
|
|
8381
8625
|
"--gantt-tl-nested-drop-left": nestedDropIndicatorLeft,
|
|
8382
8626
|
"--gantt-tl-nested-inside-drop-left": nestedInsideDropIndicatorLeft
|
|
8383
8627
|
},
|
|
@@ -8519,7 +8763,7 @@ var TaskListRow = React10.memo(
|
|
|
8519
8763
|
TaskListRow.displayName = "TaskListRow";
|
|
8520
8764
|
|
|
8521
8765
|
// src/components/TaskList/NewTaskRow.tsx
|
|
8522
|
-
import { useState as
|
|
8766
|
+
import { useState as useState7, useRef as useRef6, useEffect as useEffect6 } from "react";
|
|
8523
8767
|
import { jsx as jsx15, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
8524
8768
|
var NewTaskRow = ({
|
|
8525
8769
|
rowHeight,
|
|
@@ -8527,12 +8771,12 @@ var NewTaskRow = ({
|
|
|
8527
8771
|
onCancel,
|
|
8528
8772
|
nestingDepth = 0
|
|
8529
8773
|
}) => {
|
|
8530
|
-
const [nameValue, setNameValue] =
|
|
8531
|
-
const inputRef =
|
|
8532
|
-
const confirmedRef =
|
|
8774
|
+
const [nameValue, setNameValue] = useState7("");
|
|
8775
|
+
const inputRef = useRef6(null);
|
|
8776
|
+
const confirmedRef = useRef6(false);
|
|
8533
8777
|
const inputInnerPadding = 4;
|
|
8534
8778
|
const levelOffset = nestingDepth > 0 ? nestingDepth * 20 + 8 : 0;
|
|
8535
|
-
|
|
8779
|
+
useEffect6(() => {
|
|
8536
8780
|
if (inputRef.current) {
|
|
8537
8781
|
inputRef.current.focus();
|
|
8538
8782
|
inputRef.current.select();
|
|
@@ -8585,7 +8829,7 @@ var NewTaskRow = ({
|
|
|
8585
8829
|
};
|
|
8586
8830
|
|
|
8587
8831
|
// src/components/GenerationSkeleton/GenerationSkeleton.tsx
|
|
8588
|
-
import { useRef as
|
|
8832
|
+
import { useRef as useRef7 } from "react";
|
|
8589
8833
|
import { Fragment as Fragment4, jsx as jsx16 } from "react/jsx-runtime";
|
|
8590
8834
|
var MAX_SKELETON_ROWS = 200;
|
|
8591
8835
|
var SHIMMER_DURATION_MS = 1450;
|
|
@@ -8603,14 +8847,15 @@ var GenerationSkeletonRows = ({
|
|
|
8603
8847
|
rowHeight,
|
|
8604
8848
|
variant,
|
|
8605
8849
|
startIndex = 0,
|
|
8850
|
+
startTop,
|
|
8606
8851
|
taskListLayout,
|
|
8607
8852
|
chartDayWidth = 40,
|
|
8608
8853
|
chartStartDayOffset = 0,
|
|
8609
8854
|
chartStartJitterDays = 0
|
|
8610
8855
|
}) => {
|
|
8611
8856
|
const safeCount = clampCount(count);
|
|
8612
|
-
const previousCountRef =
|
|
8613
|
-
const shimmerDelayRef =
|
|
8857
|
+
const previousCountRef = useRef7(null);
|
|
8858
|
+
const shimmerDelayRef = useRef7("0ms");
|
|
8614
8859
|
if (previousCountRef.current !== safeCount) {
|
|
8615
8860
|
previousCountRef.current = safeCount;
|
|
8616
8861
|
shimmerDelayRef.current = `-${Date.now() % SHIMMER_DURATION_MS}ms`;
|
|
@@ -8643,7 +8888,7 @@ var GenerationSkeletonRows = ({
|
|
|
8643
8888
|
"div",
|
|
8644
8889
|
{
|
|
8645
8890
|
className: "gantt-generation-skeleton-row",
|
|
8646
|
-
style: { top: `${
|
|
8891
|
+
style: { top: `${(startTop ?? startIndex * rowHeight) + index * rowHeight}px`, height: `${rowHeight}px` },
|
|
8647
8892
|
children: variant === "task-list" ? /* @__PURE__ */ jsx16(Fragment4, { children: /* @__PURE__ */ jsx16("span", { className: `gantt-generation-skeleton-label ${shortShape ? "gantt-generation-skeleton-label-short" : ""} ${mediumShape ? "gantt-generation-skeleton-label-medium" : ""}` }) }) : /* @__PURE__ */ jsx16("span", { className: `gantt-generation-skeleton-bar ${parentShape ? "gantt-generation-skeleton-bar-parent" : ""} ${shortShape ? "gantt-generation-skeleton-bar-short" : ""}`, style: chartBarStyle })
|
|
8648
8893
|
},
|
|
8649
8894
|
rowIndex
|
|
@@ -8881,8 +9126,8 @@ var SelectAllCheckbox = ({
|
|
|
8881
9126
|
indeterminate,
|
|
8882
9127
|
onChange
|
|
8883
9128
|
}) => {
|
|
8884
|
-
const ref =
|
|
8885
|
-
|
|
9129
|
+
const ref = useRef8(null);
|
|
9130
|
+
useEffect7(() => {
|
|
8886
9131
|
if (ref.current) {
|
|
8887
9132
|
ref.current.indeterminate = indeterminate;
|
|
8888
9133
|
}
|
|
@@ -8903,6 +9148,8 @@ var SelectAllCheckbox = ({
|
|
|
8903
9148
|
var TaskList = ({
|
|
8904
9149
|
tasks,
|
|
8905
9150
|
rowHeight,
|
|
9151
|
+
rowTops,
|
|
9152
|
+
rowHeights,
|
|
8906
9153
|
headerHeight,
|
|
8907
9154
|
taskListWidth,
|
|
8908
9155
|
onTasksChange,
|
|
@@ -8961,14 +9208,14 @@ var TaskList = ({
|
|
|
8961
9208
|
skeletonRowCount = 0
|
|
8962
9209
|
}) => {
|
|
8963
9210
|
const reorderDisabled = disableTaskListReorder || disableTaskDrag;
|
|
8964
|
-
const [internalSelectedTaskIds, setInternalSelectedTaskIds] =
|
|
8965
|
-
const [activeCustomCell, setActiveCustomCell] =
|
|
8966
|
-
const [columnWidthOverrides, setColumnWidthOverrides] =
|
|
8967
|
-
const [isColumnResizeMode, setIsColumnResizeMode] =
|
|
8968
|
-
const columnResizeHeaderRef =
|
|
8969
|
-
const resizeStateRef =
|
|
9211
|
+
const [internalSelectedTaskIds, setInternalSelectedTaskIds] = useState8(/* @__PURE__ */ new Set());
|
|
9212
|
+
const [activeCustomCell, setActiveCustomCell] = useState8(null);
|
|
9213
|
+
const [columnWidthOverrides, setColumnWidthOverrides] = useState8(() => normalizeColumnWidthMap(taskListColumnWidths));
|
|
9214
|
+
const [isColumnResizeMode, setIsColumnResizeMode] = useState8(false);
|
|
9215
|
+
const columnResizeHeaderRef = useRef8(null);
|
|
9216
|
+
const resizeStateRef = useRef8(null);
|
|
8970
9217
|
const effectiveSelectedTaskIds = selectedTaskIds ?? internalSelectedTaskIds;
|
|
8971
|
-
|
|
9218
|
+
useEffect7(() => {
|
|
8972
9219
|
if (!isColumnResizeMode) {
|
|
8973
9220
|
return;
|
|
8974
9221
|
}
|
|
@@ -8990,7 +9237,7 @@ var TaskList = ({
|
|
|
8990
9237
|
}
|
|
8991
9238
|
onSelectedTaskIdsChange?.(nextSelectedTaskIds);
|
|
8992
9239
|
}, [onSelectedTaskIdsChange, selectedTaskIds]);
|
|
8993
|
-
const [internalCollapsedParentIds, setInternalCollapsedParentIds] =
|
|
9240
|
+
const [internalCollapsedParentIds, setInternalCollapsedParentIds] = useState8(/* @__PURE__ */ new Set());
|
|
8994
9241
|
const collapsedParentIds = externalCollapsedParentIds ?? internalCollapsedParentIds;
|
|
8995
9242
|
const handleToggleCollapse = externalOnToggleCollapse ?? useCallback6((parentId) => {
|
|
8996
9243
|
setInternalCollapsedParentIds((prev) => {
|
|
@@ -9030,14 +9277,22 @@ var TaskList = ({
|
|
|
9030
9277
|
return tasks2;
|
|
9031
9278
|
}, [orderedTasks, collapsedParentIds, filterMode, filteredTaskIds, isFilterActive, criticalPathMode, criticalTaskIds]);
|
|
9032
9279
|
const totalHeight = useMemo9(
|
|
9033
|
-
() => (visibleTasks.length + Math.max(0, Math.floor(skeletonRowCount))
|
|
9034
|
-
[rowHeight, skeletonRowCount, visibleTasks.length]
|
|
9280
|
+
() => (rowTops && rowHeights && visibleTasks.length > 0 ? rowTops[visibleTasks.length - 1] + rowHeights[visibleTasks.length - 1] : visibleTasks.length * rowHeight) + Math.max(0, Math.floor(skeletonRowCount)) * rowHeight,
|
|
9281
|
+
[rowHeight, rowTops, rowHeights, skeletonRowCount, visibleTasks.length]
|
|
9035
9282
|
);
|
|
9036
9283
|
const visibleTaskNumberMap = useMemo9(
|
|
9037
9284
|
() => Object.fromEntries(buildTaskNumberMap(visibleTasks)),
|
|
9038
9285
|
[visibleTasks]
|
|
9039
9286
|
);
|
|
9040
9287
|
const visibleTaskIds = useMemo9(() => visibleTasks.map((task) => task.id), [visibleTasks]);
|
|
9288
|
+
const compositeParentIds = useMemo9(
|
|
9289
|
+
() => new Set(tasks.filter((task) => task.composite).map((task) => task.id)),
|
|
9290
|
+
[tasks]
|
|
9291
|
+
);
|
|
9292
|
+
const compositeParentsById = useMemo9(
|
|
9293
|
+
() => new Map(tasks.filter((task) => task.composite).map((task) => [task.id, task])),
|
|
9294
|
+
[tasks]
|
|
9295
|
+
);
|
|
9041
9296
|
const renderedVisibleRowIndices = useMemo9(
|
|
9042
9297
|
() => visibleRowIndices ?? visibleTasks.map((_, index) => index),
|
|
9043
9298
|
[visibleRowIndices, visibleTasks]
|
|
@@ -9148,14 +9403,14 @@ var TaskList = ({
|
|
|
9148
9403
|
const handleRowClick = useCallback6((taskId) => {
|
|
9149
9404
|
onTaskSelect?.(taskId);
|
|
9150
9405
|
}, [onTaskSelect]);
|
|
9151
|
-
const [activeLinkType, setActiveLinkType] =
|
|
9152
|
-
const [selectingPredecessorFor, setSelectingPredecessorFor] =
|
|
9153
|
-
const [dependencyPickMode, setDependencyPickMode] =
|
|
9154
|
-
const [typeMenuOpen, setTypeMenuOpen] =
|
|
9155
|
-
const [dependencyError, setDependencyError] =
|
|
9156
|
-
const overlayRef =
|
|
9157
|
-
const [selectedChip, setSelectedChip] =
|
|
9158
|
-
|
|
9406
|
+
const [activeLinkType, setActiveLinkType] = useState8("FS");
|
|
9407
|
+
const [selectingPredecessorFor, setSelectingPredecessorFor] = useState8(null);
|
|
9408
|
+
const [dependencyPickMode, setDependencyPickMode] = useState8("successor");
|
|
9409
|
+
const [typeMenuOpen, setTypeMenuOpen] = useState8(false);
|
|
9410
|
+
const [dependencyError, setDependencyError] = useState8(null);
|
|
9411
|
+
const overlayRef = useRef8(null);
|
|
9412
|
+
const [selectedChip, setSelectedChip] = useState8(controlledSelectedChip ? { ...controlledSelectedChip, linkType: controlledSelectedChip.linkType } : null);
|
|
9413
|
+
useEffect7(() => {
|
|
9159
9414
|
if (controlledSelectedChip !== void 0) {
|
|
9160
9415
|
setSelectedChip(controlledSelectedChip ? { ...controlledSelectedChip, linkType: controlledSelectedChip.linkType } : null);
|
|
9161
9416
|
}
|
|
@@ -9164,7 +9419,7 @@ var TaskList = ({
|
|
|
9164
9419
|
setSelectedChip(chip);
|
|
9165
9420
|
onSelectedChipChange?.(chip);
|
|
9166
9421
|
}, [onSelectedChipChange]);
|
|
9167
|
-
|
|
9422
|
+
useEffect7(() => {
|
|
9168
9423
|
if (!selectingPredecessorFor && !selectedChip && !selectedTaskId && !activeCustomCell) return;
|
|
9169
9424
|
const pendingCanvasMouseDownRef = {
|
|
9170
9425
|
container: null,
|
|
@@ -9346,13 +9601,13 @@ var TaskList = ({
|
|
|
9346
9601
|
);
|
|
9347
9602
|
onTasksChange?.([{ ...task, dependencies: updatedDeps }]);
|
|
9348
9603
|
}, [tasks, onTasksChange]);
|
|
9349
|
-
const [isCreating, setIsCreating] =
|
|
9350
|
-
const [pendingInsert, setPendingInsert] =
|
|
9351
|
-
const [draggingIndex, setDraggingIndex] =
|
|
9352
|
-
const [dragOverTarget, setDragOverTarget] =
|
|
9353
|
-
const [isBeforeFirstDropZoneActive, setIsBeforeFirstDropZoneActive] =
|
|
9354
|
-
const dragOriginIndexRef =
|
|
9355
|
-
const dragTaskIdRef =
|
|
9604
|
+
const [isCreating, setIsCreating] = useState8(false);
|
|
9605
|
+
const [pendingInsert, setPendingInsert] = useState8(null);
|
|
9606
|
+
const [draggingIndex, setDraggingIndex] = useState8(null);
|
|
9607
|
+
const [dragOverTarget, setDragOverTarget] = useState8(null);
|
|
9608
|
+
const [isBeforeFirstDropZoneActive, setIsBeforeFirstDropZoneActive] = useState8(false);
|
|
9609
|
+
const dragOriginIndexRef = useRef8(null);
|
|
9610
|
+
const dragTaskIdRef = useRef8(null);
|
|
9356
9611
|
const clearDragState = useCallback6(() => {
|
|
9357
9612
|
setDraggingIndex(null);
|
|
9358
9613
|
setDragOverTarget(null);
|
|
@@ -9688,7 +9943,7 @@ var TaskList = ({
|
|
|
9688
9943
|
() => createBuiltInColumns({ businessDays, enableTaskMultiSelect }),
|
|
9689
9944
|
[businessDays, enableTaskMultiSelect]
|
|
9690
9945
|
);
|
|
9691
|
-
|
|
9946
|
+
useEffect7(() => {
|
|
9692
9947
|
setColumnWidthOverrides(normalizeColumnWidthMap(taskListColumnWidths));
|
|
9693
9948
|
}, [taskListColumnWidths]);
|
|
9694
9949
|
const resolvedColumns = useMemo9(
|
|
@@ -9740,7 +9995,7 @@ var TaskList = ({
|
|
|
9740
9995
|
return next;
|
|
9741
9996
|
});
|
|
9742
9997
|
}, [onTaskListColumnWidthsChange]);
|
|
9743
|
-
|
|
9998
|
+
useEffect7(() => {
|
|
9744
9999
|
const updateResizedColumn = (clientX) => {
|
|
9745
10000
|
const resizeState = resizeStateRef.current;
|
|
9746
10001
|
if (!resizeState) {
|
|
@@ -10029,7 +10284,7 @@ var TaskList = ({
|
|
|
10029
10284
|
renderedVisibleTasks.map(({ task, index }) => {
|
|
10030
10285
|
const previousVisibleTask = index > 0 ? visibleTasks[index - 1] : void 0;
|
|
10031
10286
|
const canDemoteTask = index === 0 || !task.parentId || previousVisibleTask?.id !== task.parentId;
|
|
10032
|
-
const topOffset = index * rowHeight + (hasVisiblePendingInsert && index > pendingInsertRowIndex ? rowHeight : 0);
|
|
10287
|
+
const topOffset = (rowTops?.[index] ?? index * rowHeight) + (hasVisiblePendingInsert && index > pendingInsertRowIndex ? rowHeight : 0);
|
|
10033
10288
|
return /* @__PURE__ */ jsx17(
|
|
10034
10289
|
"div",
|
|
10035
10290
|
{
|
|
@@ -10046,7 +10301,7 @@ var TaskList = ({
|
|
|
10046
10301
|
rowIndex: index,
|
|
10047
10302
|
taskNumber: originalTaskNumberMap[task.id] || "",
|
|
10048
10303
|
taskNumberMap: originalTaskNumberMap,
|
|
10049
|
-
rowHeight,
|
|
10304
|
+
rowHeight: rowHeights?.[index] ?? rowHeight,
|
|
10050
10305
|
onTasksChange,
|
|
10051
10306
|
onDurationChange,
|
|
10052
10307
|
selectedTaskId,
|
|
@@ -10103,7 +10358,8 @@ var TaskList = ({
|
|
|
10103
10358
|
onActiveCustomCellChange: setActiveCustomCell,
|
|
10104
10359
|
taskListMenuCommands,
|
|
10105
10360
|
hideTaskListRowActions,
|
|
10106
|
-
rowClassName: getTaskListRowClassName?.(task),
|
|
10361
|
+
rowClassName: [task.parentId && compositeParentIds.has(task.parentId) ? "gantt-tl-row-composite-detail" : "", getTaskListRowClassName?.(task)].filter(Boolean).join(" "),
|
|
10362
|
+
compositeParentColor: task.parentId ? compositeParentsById.get(task.parentId)?.color : void 0,
|
|
10107
10363
|
getTaskListNamePrefixIcon,
|
|
10108
10364
|
taskDateChangeMode,
|
|
10109
10365
|
onTaskDateChangeModeChange,
|
|
@@ -10119,7 +10375,7 @@ var TaskList = ({
|
|
|
10119
10375
|
{
|
|
10120
10376
|
style: {
|
|
10121
10377
|
position: "absolute",
|
|
10122
|
-
top: `${(pendingInsertRowIndex + 1) * rowHeight}px`,
|
|
10378
|
+
top: `${rowTops?.[pendingInsertRowIndex + 1] ?? (pendingInsertRowIndex + 1) * rowHeight}px`,
|
|
10123
10379
|
left: 0,
|
|
10124
10380
|
right: 0
|
|
10125
10381
|
},
|
|
@@ -10141,6 +10397,7 @@ var TaskList = ({
|
|
|
10141
10397
|
rowHeight,
|
|
10142
10398
|
variant: "task-list",
|
|
10143
10399
|
startIndex: visibleTasks.length,
|
|
10400
|
+
startTop: totalHeight - Math.max(0, Math.floor(skeletonRowCount)) * rowHeight,
|
|
10144
10401
|
taskListLayout: generationSkeletonTaskListLayout
|
|
10145
10402
|
}
|
|
10146
10403
|
)
|
|
@@ -10194,7 +10451,7 @@ var TaskList = ({
|
|
|
10194
10451
|
};
|
|
10195
10452
|
|
|
10196
10453
|
// src/components/ResourceTimelineChart/ResourceTimelineChart.tsx
|
|
10197
|
-
import React14, { useCallback as useCallback8, useEffect as
|
|
10454
|
+
import React14, { useCallback as useCallback8, useEffect as useEffect9, useMemo as useMemo10, useRef as useRef10, useState as useState10 } from "react";
|
|
10198
10455
|
|
|
10199
10456
|
// src/utils/resourceTimelineLayout.ts
|
|
10200
10457
|
var isInvalidDate = (date) => Number.isNaN(date.getTime());
|
|
@@ -10396,7 +10653,7 @@ var layoutResourceTimelineItems = (resources, options) => {
|
|
|
10396
10653
|
};
|
|
10397
10654
|
|
|
10398
10655
|
// src/hooks/useResourceItemDrag.ts
|
|
10399
|
-
import { useCallback as useCallback7, useEffect as
|
|
10656
|
+
import { useCallback as useCallback7, useEffect as useEffect8, useRef as useRef9, useState as useState9 } from "react";
|
|
10400
10657
|
var RESOURCE_CURSOR_STYLE_ID = "gantt-resource-global-drag-cursor-style";
|
|
10401
10658
|
function ensureResourceGlobalCursorStyle() {
|
|
10402
10659
|
if (typeof document === "undefined") return;
|
|
@@ -10508,15 +10765,15 @@ var useResourceItemDrag = ({
|
|
|
10508
10765
|
weekendPredicate,
|
|
10509
10766
|
onResourceItemMove
|
|
10510
10767
|
}) => {
|
|
10511
|
-
const activeDragRef =
|
|
10512
|
-
const rowsRef =
|
|
10513
|
-
const onResourceItemMoveRef =
|
|
10514
|
-
const rafRef =
|
|
10515
|
-
const [preview, setPreview] =
|
|
10516
|
-
|
|
10768
|
+
const activeDragRef = useRef9(null);
|
|
10769
|
+
const rowsRef = useRef9(rows);
|
|
10770
|
+
const onResourceItemMoveRef = useRef9(onResourceItemMove);
|
|
10771
|
+
const rafRef = useRef9(null);
|
|
10772
|
+
const [preview, setPreview] = useState9(null);
|
|
10773
|
+
useEffect8(() => {
|
|
10517
10774
|
rowsRef.current = rows;
|
|
10518
10775
|
}, [rows]);
|
|
10519
|
-
|
|
10776
|
+
useEffect8(() => {
|
|
10520
10777
|
onResourceItemMoveRef.current = onResourceItemMove;
|
|
10521
10778
|
}, [onResourceItemMove]);
|
|
10522
10779
|
const clearRaf = useCallback7(() => {
|
|
@@ -10531,7 +10788,7 @@ var useResourceItemDrag = ({
|
|
|
10531
10788
|
activeDragRef.current = null;
|
|
10532
10789
|
setPreview(null);
|
|
10533
10790
|
}, [clearRaf]);
|
|
10534
|
-
|
|
10791
|
+
useEffect8(() => {
|
|
10535
10792
|
const handleMouseMove = (event) => {
|
|
10536
10793
|
const activeDrag = activeDragRef.current;
|
|
10537
10794
|
if (!activeDrag || rafRef.current !== null) {
|
|
@@ -10864,13 +11121,13 @@ var ResourceHeader = ({
|
|
|
10864
11121
|
onConflictBadgeClick,
|
|
10865
11122
|
columnTemplate
|
|
10866
11123
|
}) => {
|
|
10867
|
-
const [menuOpen, setMenuOpen] =
|
|
10868
|
-
const [typeMenuOpen, setTypeMenuOpen] =
|
|
10869
|
-
const [scopeMenuOpen, setScopeMenuOpen] =
|
|
10870
|
-
const [editingName, setEditingName] =
|
|
10871
|
-
const [nameValue, setNameValue] =
|
|
10872
|
-
const nameInputRef =
|
|
10873
|
-
const nameConfirmedRef =
|
|
11124
|
+
const [menuOpen, setMenuOpen] = useState10(false);
|
|
11125
|
+
const [typeMenuOpen, setTypeMenuOpen] = useState10(false);
|
|
11126
|
+
const [scopeMenuOpen, setScopeMenuOpen] = useState10(false);
|
|
11127
|
+
const [editingName, setEditingName] = useState10(false);
|
|
11128
|
+
const [nameValue, setNameValue] = useState10(resource.name);
|
|
11129
|
+
const nameInputRef = useRef10(null);
|
|
11130
|
+
const nameConfirmedRef = useRef10(false);
|
|
10874
11131
|
const visibleCommands = useMemo10(
|
|
10875
11132
|
() => menuCommands.filter((command) => command.isVisible?.(resource) ?? true),
|
|
10876
11133
|
[menuCommands, resource]
|
|
@@ -10883,12 +11140,12 @@ var ResourceHeader = ({
|
|
|
10883
11140
|
const applyResourcePatch = useCallback8((patch) => {
|
|
10884
11141
|
onResourceChange?.({ ...resource, ...patch });
|
|
10885
11142
|
}, [onResourceChange, resource]);
|
|
10886
|
-
|
|
11143
|
+
useEffect9(() => {
|
|
10887
11144
|
if (!editingName) {
|
|
10888
11145
|
setNameValue(resource.name);
|
|
10889
11146
|
}
|
|
10890
11147
|
}, [editingName, resource.name]);
|
|
10891
|
-
|
|
11148
|
+
useEffect9(() => {
|
|
10892
11149
|
if (editingName && nameInputRef.current) {
|
|
10893
11150
|
nameInputRef.current.focus();
|
|
10894
11151
|
nameInputRef.current.select();
|
|
@@ -11129,10 +11386,10 @@ var ResourceHeader = ({
|
|
|
11129
11386
|
);
|
|
11130
11387
|
};
|
|
11131
11388
|
var NewResourceRow = ({ height, onConfirm, onCancel, columnTemplate }) => {
|
|
11132
|
-
const [nameValue, setNameValue] =
|
|
11133
|
-
const inputRef =
|
|
11134
|
-
const confirmedRef =
|
|
11135
|
-
|
|
11389
|
+
const [nameValue, setNameValue] = useState10("");
|
|
11390
|
+
const inputRef = useRef10(null);
|
|
11391
|
+
const confirmedRef = useRef10(false);
|
|
11392
|
+
useEffect9(() => {
|
|
11136
11393
|
inputRef.current?.focus();
|
|
11137
11394
|
inputRef.current?.select();
|
|
11138
11395
|
}, []);
|
|
@@ -11217,18 +11474,18 @@ function ResourceTimelineChart({
|
|
|
11217
11474
|
resourceTableColumnWidths,
|
|
11218
11475
|
onResourceTableColumnWidthsChange
|
|
11219
11476
|
}) {
|
|
11220
|
-
const scrollContainerRef =
|
|
11221
|
-
const gridRef =
|
|
11222
|
-
const panStateRef =
|
|
11223
|
-
const resourceColumnResizeRef =
|
|
11224
|
-
const conflictNavigationIndexRef =
|
|
11225
|
-
const resourceNavigationIndexRef =
|
|
11226
|
-
const conflictHighlightTimeoutRef =
|
|
11227
|
-
const [isCreatingResource, setIsCreatingResource] =
|
|
11228
|
-
const [creatingResourceGroupType, setCreatingResourceGroupType] =
|
|
11229
|
-
const [activeConflictItemId, setActiveConflictItemId] =
|
|
11230
|
-
const [resourceColumnHasRightShadow, setResourceColumnHasRightShadow] =
|
|
11231
|
-
const [resourceColumnWidthOverrides, setResourceColumnWidthOverrides] =
|
|
11477
|
+
const scrollContainerRef = useRef10(null);
|
|
11478
|
+
const gridRef = useRef10(null);
|
|
11479
|
+
const panStateRef = useRef10(null);
|
|
11480
|
+
const resourceColumnResizeRef = useRef10(null);
|
|
11481
|
+
const conflictNavigationIndexRef = useRef10(/* @__PURE__ */ new Map());
|
|
11482
|
+
const resourceNavigationIndexRef = useRef10(/* @__PURE__ */ new Map());
|
|
11483
|
+
const conflictHighlightTimeoutRef = useRef10(null);
|
|
11484
|
+
const [isCreatingResource, setIsCreatingResource] = useState10(false);
|
|
11485
|
+
const [creatingResourceGroupType, setCreatingResourceGroupType] = useState10(null);
|
|
11486
|
+
const [activeConflictItemId, setActiveConflictItemId] = useState10(null);
|
|
11487
|
+
const [resourceColumnHasRightShadow, setResourceColumnHasRightShadow] = useState10(false);
|
|
11488
|
+
const [resourceColumnWidthOverrides, setResourceColumnWidthOverrides] = useState10(() => normalizeResourceColumnWidthMap(resourceTableColumnWidths));
|
|
11232
11489
|
const validItems = useMemo10(() => collectValidItems(resources), [resources]);
|
|
11233
11490
|
const dateRange = useMemo10(() => getMultiMonthDays(validItems), [validItems]);
|
|
11234
11491
|
const monthStart = useMemo10(() => {
|
|
@@ -11240,7 +11497,7 @@ function ResourceTimelineChart({
|
|
|
11240
11497
|
[customDays, isWeekend3]
|
|
11241
11498
|
);
|
|
11242
11499
|
const gridWidth = useMemo10(() => Math.round(dateRange.length * dayWidth), [dateRange.length, dayWidth]);
|
|
11243
|
-
|
|
11500
|
+
useEffect9(() => {
|
|
11244
11501
|
setResourceColumnWidthOverrides(normalizeResourceColumnWidthMap(resourceTableColumnWidths));
|
|
11245
11502
|
}, [resourceTableColumnWidths]);
|
|
11246
11503
|
const resolvedResourceColumnWidths = useMemo10(
|
|
@@ -11296,7 +11553,7 @@ function ResourceTimelineChart({
|
|
|
11296
11553
|
);
|
|
11297
11554
|
const canAddResource = enableAddResource && Boolean(onAddResource);
|
|
11298
11555
|
const resourceAddRowHeight = laneHeight + DEFAULT_RESOURCE_ROW_GAP;
|
|
11299
|
-
const [collapsedResourceGroups, setCollapsedResourceGroups] =
|
|
11556
|
+
const [collapsedResourceGroups, setCollapsedResourceGroups] = useState10(/* @__PURE__ */ new Set());
|
|
11300
11557
|
const updateResourceColumnWidth = useCallback8((columnId, width) => {
|
|
11301
11558
|
setResourceColumnWidthOverrides((prev) => {
|
|
11302
11559
|
if (prev[columnId] === width) {
|
|
@@ -11307,7 +11564,7 @@ function ResourceTimelineChart({
|
|
|
11307
11564
|
return next;
|
|
11308
11565
|
});
|
|
11309
11566
|
}, [onResourceTableColumnWidthsChange]);
|
|
11310
|
-
|
|
11567
|
+
useEffect9(() => {
|
|
11311
11568
|
const handleMouseMove = (event) => {
|
|
11312
11569
|
const resizeState = resourceColumnResizeRef.current;
|
|
11313
11570
|
if (!resizeState) {
|
|
@@ -11576,7 +11833,7 @@ function ResourceTimelineChart({
|
|
|
11576
11833
|
weekendPredicate,
|
|
11577
11834
|
onResourceItemMove
|
|
11578
11835
|
});
|
|
11579
|
-
|
|
11836
|
+
useEffect9(() => {
|
|
11580
11837
|
const container = scrollContainerRef.current;
|
|
11581
11838
|
if (!container) return;
|
|
11582
11839
|
const updateShadow = () => {
|
|
@@ -11616,7 +11873,7 @@ function ResourceTimelineChart({
|
|
|
11616
11873
|
container.style.cursor = "grabbing";
|
|
11617
11874
|
event.preventDefault();
|
|
11618
11875
|
}, []);
|
|
11619
|
-
|
|
11876
|
+
useEffect9(() => {
|
|
11620
11877
|
const handlePanMove = (event) => {
|
|
11621
11878
|
const pan = panStateRef.current;
|
|
11622
11879
|
const container = scrollContainerRef.current;
|
|
@@ -11645,7 +11902,7 @@ function ResourceTimelineChart({
|
|
|
11645
11902
|
window.removeEventListener("mouseup", handlePanEnd);
|
|
11646
11903
|
};
|
|
11647
11904
|
}, [allowVerticalPan]);
|
|
11648
|
-
|
|
11905
|
+
useEffect9(() => {
|
|
11649
11906
|
const nextNavigation = /* @__PURE__ */ new Map();
|
|
11650
11907
|
for (const [resourceId, resourceItems] of itemsByResourceId.entries()) {
|
|
11651
11908
|
if (resourceItems.length === 0) {
|
|
@@ -11655,7 +11912,7 @@ function ResourceTimelineChart({
|
|
|
11655
11912
|
}
|
|
11656
11913
|
resourceNavigationIndexRef.current = nextNavigation;
|
|
11657
11914
|
}, [itemsByResourceId]);
|
|
11658
|
-
|
|
11915
|
+
useEffect9(() => {
|
|
11659
11916
|
return () => {
|
|
11660
11917
|
if (conflictHighlightTimeoutRef.current) {
|
|
11661
11918
|
window.clearTimeout(conflictHighlightTimeoutRef.current);
|
|
@@ -12075,7 +12332,7 @@ function ResourceTimelineChart({
|
|
|
12075
12332
|
}
|
|
12076
12333
|
|
|
12077
12334
|
// src/components/TableMatrix/TableMatrix.tsx
|
|
12078
|
-
import { useLayoutEffect, useMemo as useMemo11, useRef as
|
|
12335
|
+
import { useLayoutEffect, useMemo as useMemo11, useRef as useRef11, useState as useState11 } from "react";
|
|
12079
12336
|
import { jsx as jsx19, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
12080
12337
|
var AUTO_COLUMN_MIN_WIDTH = 72;
|
|
12081
12338
|
var AUTO_COLUMN_MAX_WIDTH = 180;
|
|
@@ -12142,8 +12399,8 @@ function TableMatrix({
|
|
|
12142
12399
|
filterMode = "highlight",
|
|
12143
12400
|
visibleRowIndices
|
|
12144
12401
|
}) {
|
|
12145
|
-
const measureRef =
|
|
12146
|
-
const [measuredAutoWidths, setMeasuredAutoWidths] =
|
|
12402
|
+
const measureRef = useRef11(null);
|
|
12403
|
+
const [measuredAutoWidths, setMeasuredAutoWidths] = useState11([]);
|
|
12147
12404
|
const hasAutoWidthColumns = useMemo11(
|
|
12148
12405
|
() => columns.some((column) => typeof column.width !== "number"),
|
|
12149
12406
|
[columns]
|
|
@@ -12443,7 +12700,7 @@ function TableMatrix({
|
|
|
12443
12700
|
}
|
|
12444
12701
|
|
|
12445
12702
|
// src/components/PlanFactMatrix/PlanFactMatrix.tsx
|
|
12446
|
-
import React16, { useCallback as useCallback9, useEffect as
|
|
12703
|
+
import React16, { useCallback as useCallback9, useEffect as useEffect10, useMemo as useMemo12, useRef as useRef12, useState as useState12 } from "react";
|
|
12447
12704
|
import { jsx as jsx20, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
12448
12705
|
var DAY_MS5 = 24 * 60 * 60 * 1e3;
|
|
12449
12706
|
function joinClasses2(...values) {
|
|
@@ -12535,9 +12792,9 @@ function PlanFactCellEditor({
|
|
|
12535
12792
|
onCommitRange,
|
|
12536
12793
|
onCancel
|
|
12537
12794
|
}) {
|
|
12538
|
-
const [draft, setDraft] =
|
|
12539
|
-
const inputRef =
|
|
12540
|
-
|
|
12795
|
+
const [draft, setDraft] = useState12(startValue ?? (value === void 0 ? "" : String(value)));
|
|
12796
|
+
const inputRef = useRef12(null);
|
|
12797
|
+
useEffect10(() => {
|
|
12541
12798
|
inputRef.current?.focus();
|
|
12542
12799
|
if (startValue === void 0) {
|
|
12543
12800
|
inputRef.current?.select();
|
|
@@ -12890,18 +13147,18 @@ function PlanFactMatrix({
|
|
|
12890
13147
|
todayDateIndex,
|
|
12891
13148
|
isCustomWeekend
|
|
12892
13149
|
}) {
|
|
12893
|
-
const [activeCell, setActiveCell] =
|
|
12894
|
-
const [editingCell, setEditingCell] =
|
|
12895
|
-
const [selectedRange, setSelectedRange] =
|
|
12896
|
-
const [fillRange, setFillRange] =
|
|
12897
|
-
const [overflowTooltip, setOverflowTooltip] =
|
|
12898
|
-
const isSelectingRef =
|
|
12899
|
-
const isFillDraggingRef =
|
|
12900
|
-
const didDragSelectRef =
|
|
12901
|
-
const pendingHoverCellRef =
|
|
12902
|
-
const hoverFrameRef =
|
|
12903
|
-
const rootRef =
|
|
12904
|
-
const bodyRef =
|
|
13150
|
+
const [activeCell, setActiveCell] = useState12(null);
|
|
13151
|
+
const [editingCell, setEditingCell] = useState12(null);
|
|
13152
|
+
const [selectedRange, setSelectedRange] = useState12(null);
|
|
13153
|
+
const [fillRange, setFillRange] = useState12(null);
|
|
13154
|
+
const [overflowTooltip, setOverflowTooltip] = useState12(null);
|
|
13155
|
+
const isSelectingRef = useRef12(false);
|
|
13156
|
+
const isFillDraggingRef = useRef12(false);
|
|
13157
|
+
const didDragSelectRef = useRef12(false);
|
|
13158
|
+
const pendingHoverCellRef = useRef12(null);
|
|
13159
|
+
const hoverFrameRef = useRef12(null);
|
|
13160
|
+
const rootRef = useRef12(null);
|
|
13161
|
+
const bodyRef = useRef12(null);
|
|
12905
13162
|
const totalWidth = dateRange.length * dayWidth;
|
|
12906
13163
|
const subrowHeight = rowHeight / 2;
|
|
12907
13164
|
const renderedRowIndices = useMemo12(
|
|
@@ -13307,7 +13564,7 @@ function PlanFactMatrix({
|
|
|
13307
13564
|
onTaskSelect?.(nextCell.taskId);
|
|
13308
13565
|
focusCell(selectedRange?.anchor ?? cell);
|
|
13309
13566
|
}, [dateRange.length, focusCell, onTaskSelect, parentTaskIds, selectedRange, tasks]);
|
|
13310
|
-
|
|
13567
|
+
useEffect10(() => {
|
|
13311
13568
|
const endSelection = () => {
|
|
13312
13569
|
let pendingFillRange = null;
|
|
13313
13570
|
if (hoverFrameRef.current !== null) {
|
|
@@ -13330,12 +13587,12 @@ function PlanFactMatrix({
|
|
|
13330
13587
|
window.removeEventListener("mouseup", endSelection);
|
|
13331
13588
|
};
|
|
13332
13589
|
}, [applyFillRange, flushPendingHoverCell]);
|
|
13333
|
-
|
|
13590
|
+
useEffect10(() => () => {
|
|
13334
13591
|
if (hoverFrameRef.current !== null) {
|
|
13335
13592
|
window.cancelAnimationFrame(hoverFrameRef.current);
|
|
13336
13593
|
}
|
|
13337
13594
|
}, []);
|
|
13338
|
-
|
|
13595
|
+
useEffect10(() => {
|
|
13339
13596
|
const handleKeyDown = (event) => {
|
|
13340
13597
|
if (event.key !== "Escape") return;
|
|
13341
13598
|
clearSelection();
|
|
@@ -14111,6 +14368,7 @@ function TaskGanttChartInner(props, ref) {
|
|
|
14111
14368
|
skeletonStartJitterDays = 0,
|
|
14112
14369
|
showTaskDateLabels = true,
|
|
14113
14370
|
showTaskNames = true,
|
|
14371
|
+
showCompositeSegments = true,
|
|
14114
14372
|
timelineMarkers,
|
|
14115
14373
|
additionalColumns,
|
|
14116
14374
|
hiddenTaskListColumns,
|
|
@@ -14138,31 +14396,31 @@ function TaskGanttChartInner(props, ref) {
|
|
|
14138
14396
|
const onMatrixCellClick = isTableMatrixMode ? props.onMatrixCellClick : void 0;
|
|
14139
14397
|
const matrixDateOverlay = isTableMatrixMode ? props.matrixDateOverlay : void 0;
|
|
14140
14398
|
const onPlanFactCellCommit = isPlanFactMode ? props.onPlanFactCellCommit : void 0;
|
|
14141
|
-
const containerRef =
|
|
14142
|
-
const scrollContainerRef =
|
|
14143
|
-
const scrollContentRef =
|
|
14144
|
-
const clearSelectedTaskTimeoutRef =
|
|
14145
|
-
const hasAutoScrolledToTodayRef =
|
|
14146
|
-
const previewPositionStoreRef =
|
|
14147
|
-
const renderedTaskIdsRef =
|
|
14399
|
+
const containerRef = useRef13(null);
|
|
14400
|
+
const scrollContainerRef = useRef13(null);
|
|
14401
|
+
const scrollContentRef = useRef13(null);
|
|
14402
|
+
const clearSelectedTaskTimeoutRef = useRef13(null);
|
|
14403
|
+
const hasAutoScrolledToTodayRef = useRef13(false);
|
|
14404
|
+
const previewPositionStoreRef = useRef13(null);
|
|
14405
|
+
const renderedTaskIdsRef = useRef13(/* @__PURE__ */ new Set());
|
|
14148
14406
|
if (previewPositionStoreRef.current === null) {
|
|
14149
14407
|
previewPositionStoreRef.current = createTaskPreviewPositionStore();
|
|
14150
14408
|
}
|
|
14151
14409
|
const previewPositionStore = previewPositionStoreRef.current;
|
|
14152
|
-
const [selectedTaskId, setSelectedTaskId] =
|
|
14153
|
-
const [taskListHasRightShadow, setTaskListHasRightShadow] =
|
|
14154
|
-
const [internalTaskDateChangeMode, setInternalTaskDateChangeMode] =
|
|
14155
|
-
const [scrollViewport, setScrollViewport] =
|
|
14410
|
+
const [selectedTaskId, setSelectedTaskId] = useState13(null);
|
|
14411
|
+
const [taskListHasRightShadow, setTaskListHasRightShadow] = useState13(false);
|
|
14412
|
+
const [internalTaskDateChangeMode, setInternalTaskDateChangeMode] = useState13("preserve-duration");
|
|
14413
|
+
const [scrollViewport, setScrollViewport] = useState13(() => ({
|
|
14156
14414
|
scrollTop: 0,
|
|
14157
14415
|
viewportHeight: getInitialScrollViewportHeight(containerHeight, headerHeight + 1)
|
|
14158
14416
|
}));
|
|
14159
|
-
const [forceFullRenderForPrint, setForceFullRenderForPrint] =
|
|
14160
|
-
const [planFactDateWindow, setPlanFactDateWindow] =
|
|
14161
|
-
const [selectedChip, setSelectedChip] =
|
|
14162
|
-
const [dependencyCreationDrag, setDependencyCreationDrag] =
|
|
14163
|
-
const dependencyCreationRef =
|
|
14164
|
-
const [dependencyCreationError, setDependencyCreationError] =
|
|
14165
|
-
const [dependencyLineMenu, setDependencyLineMenu] =
|
|
14417
|
+
const [forceFullRenderForPrint, setForceFullRenderForPrint] = useState13(false);
|
|
14418
|
+
const [planFactDateWindow, setPlanFactDateWindow] = useState13({ start: 0, end: 0 });
|
|
14419
|
+
const [selectedChip, setSelectedChip] = useState13(null);
|
|
14420
|
+
const [dependencyCreationDrag, setDependencyCreationDrag] = useState13(null);
|
|
14421
|
+
const dependencyCreationRef = useRef13(null);
|
|
14422
|
+
const [dependencyCreationError, setDependencyCreationError] = useState13(null);
|
|
14423
|
+
const [dependencyLineMenu, setDependencyLineMenu] = useState13(null);
|
|
14166
14424
|
const getDependencyPortPoint = useCallback10((element, chartRect) => {
|
|
14167
14425
|
const rect = element.getBoundingClientRect();
|
|
14168
14426
|
const side = element.getAttribute("data-port-side");
|
|
@@ -14196,7 +14454,7 @@ function TaskGanttChartInner(props, ref) {
|
|
|
14196
14454
|
dependencyCreationRef.current = nextDrag;
|
|
14197
14455
|
setDependencyCreationDrag(nextDrag);
|
|
14198
14456
|
}, [disableDependencyEditing, getDependencyPortPoint]);
|
|
14199
|
-
|
|
14457
|
+
useEffect11(() => {
|
|
14200
14458
|
if (!dependencyCreationDrag) return;
|
|
14201
14459
|
const handlePointerMove = (event) => {
|
|
14202
14460
|
const activeDrag = dependencyCreationRef.current;
|
|
@@ -14280,12 +14538,12 @@ function TaskGanttChartInner(props, ref) {
|
|
|
14280
14538
|
document.removeEventListener("keydown", handleKeyDown);
|
|
14281
14539
|
};
|
|
14282
14540
|
}, [businessDays, customDays, dependencyCreationDrag !== null, getDependencyPortPoint, getVisualDependencyType, isWeekend3, onTasksChange, tasks]);
|
|
14283
|
-
|
|
14541
|
+
useEffect11(() => {
|
|
14284
14542
|
if (!dependencyCreationError) return;
|
|
14285
14543
|
const timeout = window.setTimeout(() => setDependencyCreationError(null), 3e3);
|
|
14286
14544
|
return () => window.clearTimeout(timeout);
|
|
14287
14545
|
}, [dependencyCreationError]);
|
|
14288
|
-
|
|
14546
|
+
useEffect11(() => {
|
|
14289
14547
|
if (!dependencyLineMenu) return;
|
|
14290
14548
|
const closeMenu = (event) => {
|
|
14291
14549
|
const target = event.target;
|
|
@@ -14323,26 +14581,55 @@ function TaskGanttChartInner(props, ref) {
|
|
|
14323
14581
|
setSelectedChip(null);
|
|
14324
14582
|
setDependencyLineMenu(null);
|
|
14325
14583
|
}, [dependencyLineMenu, onTasksChange, tasks]);
|
|
14326
|
-
const [activeTimelineTooltip, setActiveTimelineTooltip] =
|
|
14327
|
-
const [internalCollapsedParentIds, setInternalCollapsedParentIds] =
|
|
14328
|
-
const
|
|
14329
|
-
const [editingTaskId, setEditingTaskId] =
|
|
14584
|
+
const [activeTimelineTooltip, setActiveTimelineTooltip] = useState13(null);
|
|
14585
|
+
const [internalCollapsedParentIds, setInternalCollapsedParentIds] = useState13(/* @__PURE__ */ new Set());
|
|
14586
|
+
const [expandedCompositeIds, setExpandedCompositeIds] = useState13(/* @__PURE__ */ new Set());
|
|
14587
|
+
const [editingTaskId, setEditingTaskId] = useState13(null);
|
|
14330
14588
|
const taskDateChangeMode = externalTaskDateChangeMode ?? internalTaskDateChangeMode;
|
|
14331
14589
|
const handleTaskDateChangeMode = externalOnTaskDateChangeModeChange ?? setInternalTaskDateChangeMode;
|
|
14332
14590
|
const resolvedRowContentLines = isPlanFactMode ? Math.max(2, Math.floor(rowContentLines)) : Math.max(1, Math.floor(rowContentLines));
|
|
14333
14591
|
const shouldFillParentRowsInTaskList = fillParentRowsInTaskList ?? isPlanFactMode;
|
|
14334
14592
|
const effectiveRowHeight = useMemo13(
|
|
14335
|
-
() => Math.max(rowHeight, 10 + resolvedRowContentLines * 18),
|
|
14336
|
-
[resolvedRowContentLines, rowHeight]
|
|
14593
|
+
() => rowContentLines === 0 && !isPlanFactMode ? rowHeight : Math.max(rowHeight, 10 + resolvedRowContentLines * 18),
|
|
14594
|
+
[isPlanFactMode, resolvedRowContentLines, rowContentLines, rowHeight]
|
|
14337
14595
|
);
|
|
14338
|
-
const normalizedTasks = useMemo13(() =>
|
|
14596
|
+
const normalizedTasks = useMemo13(() => {
|
|
14597
|
+
const ordered = normalizeHierarchyTasks(tasks);
|
|
14598
|
+
const ranges = /* @__PURE__ */ new Map();
|
|
14599
|
+
for (const task of ordered) {
|
|
14600
|
+
if (!task.parentId) continue;
|
|
14601
|
+
const start = parseUTCDate(task.startDate).getTime();
|
|
14602
|
+
const end = parseUTCDate(task.endDate).getTime();
|
|
14603
|
+
const range = ranges.get(task.parentId);
|
|
14604
|
+
ranges.set(task.parentId, {
|
|
14605
|
+
start: Math.min(range?.start ?? start, start),
|
|
14606
|
+
end: Math.max(range?.end ?? end, end)
|
|
14607
|
+
});
|
|
14608
|
+
}
|
|
14609
|
+
return ordered.map((task) => {
|
|
14610
|
+
const range = task.composite ? ranges.get(task.id) : void 0;
|
|
14611
|
+
return range ? {
|
|
14612
|
+
...task,
|
|
14613
|
+
startDate: new Date(range.start).toISOString().slice(0, 10),
|
|
14614
|
+
endDate: new Date(range.end).toISOString().slice(0, 10)
|
|
14615
|
+
} : task;
|
|
14616
|
+
});
|
|
14617
|
+
}, [tasks]);
|
|
14618
|
+
const collapsedParentIds = useMemo13(() => {
|
|
14619
|
+
if (externalCollapsedParentIds) return externalCollapsedParentIds;
|
|
14620
|
+
const ids = new Set(internalCollapsedParentIds);
|
|
14621
|
+
for (const task of normalizedTasks) {
|
|
14622
|
+
if (task.composite && !expandedCompositeIds.has(task.id)) ids.add(task.id);
|
|
14623
|
+
}
|
|
14624
|
+
return ids;
|
|
14625
|
+
}, [externalCollapsedParentIds, internalCollapsedParentIds, normalizedTasks, expandedCompositeIds]);
|
|
14339
14626
|
const controlledScheduleIdentity = useMemo13(
|
|
14340
14627
|
() => buildControlledScheduleIdentity(normalizedTasks),
|
|
14341
14628
|
[normalizedTasks]
|
|
14342
14629
|
);
|
|
14343
|
-
const previousControlledScheduleIdentityRef =
|
|
14630
|
+
const previousControlledScheduleIdentityRef = useRef13(null);
|
|
14344
14631
|
const controlledScheduleChanged = previousControlledScheduleIdentityRef.current !== null && previousControlledScheduleIdentityRef.current !== controlledScheduleIdentity;
|
|
14345
|
-
const [previewTasksById, setPreviewTasksById] =
|
|
14632
|
+
const [previewTasksById, setPreviewTasksById] = useState13(/* @__PURE__ */ new Map());
|
|
14346
14633
|
const previewNormalizedTasks = useMemo13(() => {
|
|
14347
14634
|
if (controlledScheduleChanged || previewTasksById.size === 0) return normalizedTasks;
|
|
14348
14635
|
return normalizedTasks.map((task) => previewTasksById.get(task.id) ?? task);
|
|
@@ -14382,8 +14669,8 @@ function TaskGanttChartInner(props, ref) {
|
|
|
14382
14669
|
},
|
|
14383
14670
|
[dateRangeTasks, explicitDateRange, isPlanFactMode]
|
|
14384
14671
|
);
|
|
14385
|
-
const [validationResult, setValidationResult] =
|
|
14386
|
-
const [cascadeOverrides, setCascadeOverrides] =
|
|
14672
|
+
const [validationResult, setValidationResult] = useState13(null);
|
|
14673
|
+
const [cascadeOverrides, setCascadeOverrides] = useState13(/* @__PURE__ */ new Map());
|
|
14387
14674
|
const gridWidth = useMemo13(
|
|
14388
14675
|
() => Math.round(dateRange.length * dayWidth),
|
|
14389
14676
|
[dateRange.length, dayWidth]
|
|
@@ -14415,6 +14702,23 @@ function TaskGanttChartInner(props, ref) {
|
|
|
14415
14702
|
}
|
|
14416
14703
|
return tasks2;
|
|
14417
14704
|
}, [normalizedTasks, collapsedParentIds, filterMode, taskFilter, criticalPathMode, criticalTaskIds]);
|
|
14705
|
+
const compositeRowLayout = useMemo13(() => {
|
|
14706
|
+
const compositeIds = new Set(normalizedTasks.filter((task) => task.composite).map((task) => task.id));
|
|
14707
|
+
const tops = [];
|
|
14708
|
+
const heights = [];
|
|
14709
|
+
let top = 0;
|
|
14710
|
+
for (const task of visibleTasks) {
|
|
14711
|
+
tops.push(top);
|
|
14712
|
+
const height = task.parentId && compositeIds.has(task.parentId) ? Math.min(effectiveRowHeight, 22) : effectiveRowHeight;
|
|
14713
|
+
heights.push(height);
|
|
14714
|
+
top += height;
|
|
14715
|
+
}
|
|
14716
|
+
return { tops, heights, totalHeight: top };
|
|
14717
|
+
}, [normalizedTasks, visibleTasks, effectiveRowHeight]);
|
|
14718
|
+
const compositeParentsById = useMemo13(
|
|
14719
|
+
() => new Map(normalizedTasks.filter((task) => task.composite).map((task) => [task.id, task])),
|
|
14720
|
+
[normalizedTasks]
|
|
14721
|
+
);
|
|
14418
14722
|
const matchedTaskIds = useMemo13(() => {
|
|
14419
14723
|
if (!taskFilter) return /* @__PURE__ */ new Set();
|
|
14420
14724
|
return new Set(visibleTasks.filter(taskFilter).map((task) => task.id));
|
|
@@ -14436,8 +14740,8 @@ function TaskGanttChartInner(props, ref) {
|
|
|
14436
14740
|
return mergedHighlightedTaskIds;
|
|
14437
14741
|
}, [filterMode, highlightedTaskIds, matchedTaskIds, criticalPathMode, criticalTaskIds]);
|
|
14438
14742
|
const totalGridHeight = useMemo13(
|
|
14439
|
-
() =>
|
|
14440
|
-
[effectiveRowHeight, skeletonRowCount
|
|
14743
|
+
() => compositeRowLayout.totalHeight + Math.max(0, Math.floor(skeletonRowCount)) * effectiveRowHeight,
|
|
14744
|
+
[compositeRowLayout.totalHeight, effectiveRowHeight, skeletonRowCount]
|
|
14441
14745
|
);
|
|
14442
14746
|
const timelineHeaderHeight = headerHeight + 1;
|
|
14443
14747
|
const tableBodyMinHeight = useMemo13(() => {
|
|
@@ -14475,7 +14779,7 @@ function TaskGanttChartInner(props, ref) {
|
|
|
14475
14779
|
return markerDate >= rangeStartMs && markerDate <= rangeEndMs;
|
|
14476
14780
|
});
|
|
14477
14781
|
}, [dateRange, isTableMatrixMode, timelineMarkers]);
|
|
14478
|
-
|
|
14782
|
+
useEffect11(() => {
|
|
14479
14783
|
if (isTableMatrixMode) return;
|
|
14480
14784
|
if (hasAutoScrolledToTodayRef.current) return;
|
|
14481
14785
|
const container = scrollContainerRef.current;
|
|
@@ -14489,7 +14793,7 @@ function TaskGanttChartInner(props, ref) {
|
|
|
14489
14793
|
container.scrollLeft = Math.max(0, scrollLeft);
|
|
14490
14794
|
hasAutoScrolledToTodayRef.current = true;
|
|
14491
14795
|
}, [dateRange, dayWidth, isTableMatrixMode]);
|
|
14492
|
-
|
|
14796
|
+
useEffect11(() => {
|
|
14493
14797
|
const container = scrollContainerRef.current;
|
|
14494
14798
|
if (!container) return;
|
|
14495
14799
|
let frameId = null;
|
|
@@ -14564,7 +14868,7 @@ function TaskGanttChartInner(props, ref) {
|
|
|
14564
14868
|
const rowIndex = visibleTasks.findIndex((visibleTask) => visibleTask.id === taskId);
|
|
14565
14869
|
if (rowIndex === -1) return;
|
|
14566
14870
|
const paddedRowIndex = Math.max(0, rowIndex - SCROLL_TO_ROW_CONTEXT_ROWS);
|
|
14567
|
-
container2.scrollTo({ top: Math.max(0,
|
|
14871
|
+
container2.scrollTo({ top: Math.max(0, compositeRowLayout.tops[paddedRowIndex] ?? 0), behavior: "smooth" });
|
|
14568
14872
|
setSelectedTaskId(taskId);
|
|
14569
14873
|
return;
|
|
14570
14874
|
}
|
|
@@ -14583,7 +14887,7 @@ function TaskGanttChartInner(props, ref) {
|
|
|
14583
14887
|
const taskOffset = taskIndex * dayWidth;
|
|
14584
14888
|
const scrollLeft = Math.round(taskOffset - dayWidth * 2);
|
|
14585
14889
|
container.scrollTo({ left: Math.max(0, scrollLeft), behavior: "smooth" });
|
|
14586
|
-
}, [dateRange, dayWidth, effectiveRowHeight, isTableMatrixMode, tasks, visibleTasks]);
|
|
14890
|
+
}, [dateRange, dayWidth, effectiveRowHeight, compositeRowLayout, isTableMatrixMode, tasks, visibleTasks]);
|
|
14587
14891
|
const scrollToRow = useCallback10((taskId, options = {}) => {
|
|
14588
14892
|
const container = scrollContainerRef.current;
|
|
14589
14893
|
if (!container) return;
|
|
@@ -14592,7 +14896,7 @@ function TaskGanttChartInner(props, ref) {
|
|
|
14592
14896
|
const rowIndex = visibleTasks.findIndex((visibleTask) => visibleTask.id === task.id);
|
|
14593
14897
|
if (rowIndex === -1) return;
|
|
14594
14898
|
const paddedRowIndex = Math.max(0, rowIndex - SCROLL_TO_ROW_CONTEXT_ROWS);
|
|
14595
|
-
const scrollTop = Math.max(0,
|
|
14899
|
+
const scrollTop = Math.max(0, compositeRowLayout.tops[paddedRowIndex] ?? 0);
|
|
14596
14900
|
const {
|
|
14597
14901
|
select = true,
|
|
14598
14902
|
behavior = "smooth",
|
|
@@ -14612,10 +14916,10 @@ function TaskGanttChartInner(props, ref) {
|
|
|
14612
14916
|
}
|
|
14613
14917
|
}
|
|
14614
14918
|
container.scrollTo({ top: scrollTop, behavior });
|
|
14615
|
-
}, [effectiveRowHeight, tasks, visibleTasks]);
|
|
14616
|
-
const [dragGuideLines, setDragGuideLines] =
|
|
14617
|
-
const [draggedTaskOverride, setDraggedTaskOverride] =
|
|
14618
|
-
|
|
14919
|
+
}, [effectiveRowHeight, compositeRowLayout, tasks, visibleTasks]);
|
|
14920
|
+
const [dragGuideLines, setDragGuideLines] = useState13(null);
|
|
14921
|
+
const [draggedTaskOverride, setDraggedTaskOverride] = useState13(null);
|
|
14922
|
+
useEffect11(() => {
|
|
14619
14923
|
const previousIdentity = previousControlledScheduleIdentityRef.current;
|
|
14620
14924
|
previousControlledScheduleIdentityRef.current = controlledScheduleIdentity;
|
|
14621
14925
|
if (previousIdentity === null || previousIdentity === controlledScheduleIdentity) {
|
|
@@ -14627,21 +14931,21 @@ function TaskGanttChartInner(props, ref) {
|
|
|
14627
14931
|
setDraggedTaskOverride((current) => current === null ? current : null);
|
|
14628
14932
|
setDragGuideLines((current) => current === null ? current : null);
|
|
14629
14933
|
}, [controlledScheduleIdentity, previewPositionStore]);
|
|
14630
|
-
|
|
14934
|
+
useEffect11(() => {
|
|
14631
14935
|
const result = validateDependencies(tasks);
|
|
14632
14936
|
setValidationResult(result);
|
|
14633
14937
|
onValidateDependencies?.(result);
|
|
14634
14938
|
}, [tasks, onValidateDependencies]);
|
|
14635
|
-
|
|
14939
|
+
useEffect11(() => () => {
|
|
14636
14940
|
if (clearSelectedTaskTimeoutRef.current !== null) {
|
|
14637
14941
|
window.clearTimeout(clearSelectedTaskTimeoutRef.current);
|
|
14638
14942
|
}
|
|
14639
14943
|
previewPositionStore.clear();
|
|
14640
14944
|
}, [previewPositionStore]);
|
|
14641
14945
|
const handleTaskChange = useCallback10((updatedTasks, durationEdit) => {
|
|
14642
|
-
|
|
14946
|
+
let updatedTask = updatedTasks[0];
|
|
14643
14947
|
if (!updatedTask) return;
|
|
14644
|
-
const originalTask =
|
|
14948
|
+
const originalTask = normalizedTasks.find((t) => t.id === updatedTask.id);
|
|
14645
14949
|
if (!originalTask) {
|
|
14646
14950
|
onTasksChange?.(updatedTasks);
|
|
14647
14951
|
if (editingTaskId === updatedTask.id) {
|
|
@@ -14654,6 +14958,8 @@ function TaskGanttChartInner(props, ref) {
|
|
|
14654
14958
|
const newStart = new Date(updatedTask.startDate);
|
|
14655
14959
|
const newEnd = new Date(updatedTask.endDate);
|
|
14656
14960
|
const datesChanged = origStart.getTime() !== newStart.getTime() || origEnd.getTime() !== newEnd.getTime();
|
|
14961
|
+
const isCompositeDetail = datesChanged && tasks.some((task) => task.id === updatedTask.parentId && task.composite);
|
|
14962
|
+
if (isCompositeDetail) updatedTask = { ...updatedTask, synced: false };
|
|
14657
14963
|
if (!datesChanged) {
|
|
14658
14964
|
if (updatedTasks.length > 1) {
|
|
14659
14965
|
onTasksChange?.(updatedTasks);
|
|
@@ -14715,7 +15021,7 @@ function TaskGanttChartInner(props, ref) {
|
|
|
14715
15021
|
}
|
|
14716
15022
|
return;
|
|
14717
15023
|
}
|
|
14718
|
-
const movedParentCascade = disableConstraints ? [updatedTask] : universalCascade(updatedTask, newStart, newEnd,
|
|
15024
|
+
const movedParentCascade = disableConstraints && !originalTask.composite ? [updatedTask] : universalCascade(updatedTask, newStart, newEnd, normalizedTasks, businessDays, isCustomWeekend);
|
|
14719
15025
|
if (onScheduleIntent) {
|
|
14720
15026
|
onScheduleIntent({
|
|
14721
15027
|
type: "move_task",
|
|
@@ -14739,7 +15045,8 @@ function TaskGanttChartInner(props, ref) {
|
|
|
14739
15045
|
taskId: updatedTask.id,
|
|
14740
15046
|
duration: durationEdit.duration,
|
|
14741
15047
|
anchor: durationEdit.anchor,
|
|
14742
|
-
taskType: updatedTask.type ?? "task"
|
|
15048
|
+
taskType: updatedTask.type ?? "task",
|
|
15049
|
+
...isCompositeDetail ? { localOverride: true } : {}
|
|
14743
15050
|
});
|
|
14744
15051
|
} else {
|
|
14745
15052
|
onTasksChange?.(cascadedTasks);
|
|
@@ -14751,7 +15058,8 @@ function TaskGanttChartInner(props, ref) {
|
|
|
14751
15058
|
onScheduleIntent({
|
|
14752
15059
|
type: "move_task",
|
|
14753
15060
|
taskId: updatedTask.id,
|
|
14754
|
-
startDate: newStart.toISOString().split("T")[0]
|
|
15061
|
+
startDate: newStart.toISOString().split("T")[0],
|
|
15062
|
+
...isCompositeDetail ? { localOverride: true } : {}
|
|
14755
15063
|
});
|
|
14756
15064
|
} else {
|
|
14757
15065
|
const anchor = startChanged ? "end" : "start";
|
|
@@ -14759,13 +15067,14 @@ function TaskGanttChartInner(props, ref) {
|
|
|
14759
15067
|
type: "resize_task",
|
|
14760
15068
|
taskId: updatedTask.id,
|
|
14761
15069
|
anchor,
|
|
14762
|
-
date: (startChanged ? newStart : newEnd).toISOString().split("T")[0]
|
|
15070
|
+
date: (startChanged ? newStart : newEnd).toISOString().split("T")[0],
|
|
15071
|
+
...isCompositeDetail ? { localOverride: true } : {}
|
|
14763
15072
|
});
|
|
14764
15073
|
}
|
|
14765
15074
|
} else {
|
|
14766
15075
|
onTasksChange?.(cascadedTasks);
|
|
14767
15076
|
}
|
|
14768
|
-
}, [tasks, onTasksChange, onScheduleIntent, disableConstraints, editingTaskId, businessDays, isCustomWeekend, onSubtreeScaleResult]);
|
|
15077
|
+
}, [tasks, normalizedTasks, onTasksChange, onScheduleIntent, disableConstraints, editingTaskId, businessDays, isCustomWeekend, onSubtreeScaleResult]);
|
|
14769
15078
|
const handleTaskDurationChange = useCallback10((task, duration) => {
|
|
14770
15079
|
const updatedTask = {
|
|
14771
15080
|
...task,
|
|
@@ -14879,12 +15188,25 @@ function TaskGanttChartInner(props, ref) {
|
|
|
14879
15188
|
if (scrollViewport.viewportHeight <= 0) {
|
|
14880
15189
|
return Array.from({ length: totalTasks }, (_, index) => index);
|
|
14881
15190
|
}
|
|
14882
|
-
|
|
14883
|
-
|
|
14884
|
-
|
|
14885
|
-
|
|
14886
|
-
|
|
14887
|
-
|
|
15191
|
+
let low = 0;
|
|
15192
|
+
let high = totalTasks;
|
|
15193
|
+
while (low < high) {
|
|
15194
|
+
const middle = low + high >>> 1;
|
|
15195
|
+
if (compositeRowLayout.tops[middle] + compositeRowLayout.heights[middle] < scrollViewport.scrollTop) low = middle + 1;
|
|
15196
|
+
else high = middle;
|
|
15197
|
+
}
|
|
15198
|
+
const first = Math.min(low, totalTasks - 1);
|
|
15199
|
+
const viewportBottom = scrollViewport.scrollTop + scrollViewport.viewportHeight;
|
|
15200
|
+
low = first;
|
|
15201
|
+
high = totalTasks;
|
|
15202
|
+
while (low < high) {
|
|
15203
|
+
const middle = low + high >>> 1;
|
|
15204
|
+
if (compositeRowLayout.tops[middle] < viewportBottom) low = middle + 1;
|
|
15205
|
+
else high = middle;
|
|
15206
|
+
}
|
|
15207
|
+
const last = Math.min(low, totalTasks - 1);
|
|
15208
|
+
const rangeStart = Math.max(0, first - TASK_ROW_OVERSCAN);
|
|
15209
|
+
const rangeEnd = Math.min(totalTasks - 1, last + TASK_ROW_OVERSCAN);
|
|
14888
15210
|
const indices = /* @__PURE__ */ new Set();
|
|
14889
15211
|
for (let index = rangeStart; index <= rangeEnd; index += 1) {
|
|
14890
15212
|
indices.add(index);
|
|
@@ -14896,7 +15218,7 @@ function TaskGanttChartInner(props, ref) {
|
|
|
14896
15218
|
}
|
|
14897
15219
|
}
|
|
14898
15220
|
return Array.from(indices).sort((left, right) => left - right);
|
|
14899
|
-
}, [
|
|
15221
|
+
}, [compositeRowLayout, forceFullRenderForPrint, forcedRenderedTaskIds, scrollViewport, visibleTaskIndexMap, visibleTasks.length]);
|
|
14900
15222
|
const visiblePlanFactDateIndices = useMemo13(() => {
|
|
14901
15223
|
if (forceFullRenderForPrint) {
|
|
14902
15224
|
return void 0;
|
|
@@ -14933,7 +15255,7 @@ function TaskGanttChartInner(props, ref) {
|
|
|
14933
15255
|
const handleTaskSelect = useCallback10((taskId) => {
|
|
14934
15256
|
setSelectedTaskId(taskId);
|
|
14935
15257
|
}, []);
|
|
14936
|
-
const hoveredRowElementsRef =
|
|
15258
|
+
const hoveredRowElementsRef = useRef13([]);
|
|
14937
15259
|
const clearHoveredRows = useCallback10(() => {
|
|
14938
15260
|
for (const element of hoveredRowElementsRef.current) {
|
|
14939
15261
|
element.classList.remove("gantt-tl-row-hovered", "gantt-tr-row-hovered", "gantt-mx-row-hovered", "gantt-pf-row-hovered");
|
|
@@ -14973,7 +15295,16 @@ function TaskGanttChartInner(props, ref) {
|
|
|
14973
15295
|
}
|
|
14974
15296
|
applyHoveredRows(taskId);
|
|
14975
15297
|
}, [applyHoveredRows]);
|
|
14976
|
-
const handleToggleCollapse = externalOnToggleCollapse ??
|
|
15298
|
+
const handleToggleCollapse = externalOnToggleCollapse ?? ((parentId) => {
|
|
15299
|
+
if (normalizedTasks.some((task) => task.id === parentId && task.composite)) {
|
|
15300
|
+
setExpandedCompositeIds((prev) => {
|
|
15301
|
+
const next = new Set(prev);
|
|
15302
|
+
if (next.has(parentId)) next.delete(parentId);
|
|
15303
|
+
else next.add(parentId);
|
|
15304
|
+
return next;
|
|
15305
|
+
});
|
|
15306
|
+
return;
|
|
15307
|
+
}
|
|
14977
15308
|
setInternalCollapsedParentIds((prev) => {
|
|
14978
15309
|
const next = new Set(prev);
|
|
14979
15310
|
if (next.has(parentId)) {
|
|
@@ -14983,7 +15314,14 @@ function TaskGanttChartInner(props, ref) {
|
|
|
14983
15314
|
}
|
|
14984
15315
|
return next;
|
|
14985
15316
|
});
|
|
14986
|
-
}
|
|
15317
|
+
});
|
|
15318
|
+
const lastCompositeBarToggleRef = useRef13(null);
|
|
15319
|
+
const handleCompositeBarToggle = (taskId, source) => {
|
|
15320
|
+
const now = Date.now();
|
|
15321
|
+
if (source === "click" && lastCompositeBarToggleRef.current?.source === "release" && lastCompositeBarToggleRef.current.id === taskId && now - lastCompositeBarToggleRef.current.time < 150) return;
|
|
15322
|
+
lastCompositeBarToggleRef.current = { id: taskId, time: now, source };
|
|
15323
|
+
handleToggleCollapse(taskId);
|
|
15324
|
+
};
|
|
14987
15325
|
const allParentIds = useMemo13(() => {
|
|
14988
15326
|
const taskIds = new Set(normalizedTasks.map((task) => task.id));
|
|
14989
15327
|
return new Set(normalizedTasks.map((task) => task.parentId).filter((parentId) => Boolean(parentId && taskIds.has(parentId))));
|
|
@@ -14991,11 +15329,13 @@ function TaskGanttChartInner(props, ref) {
|
|
|
14991
15329
|
const handleCollapseAll = useCallback10(() => {
|
|
14992
15330
|
if (externalCollapsedParentIds) return;
|
|
14993
15331
|
setInternalCollapsedParentIds(allParentIds);
|
|
15332
|
+
setExpandedCompositeIds(/* @__PURE__ */ new Set());
|
|
14994
15333
|
}, [allParentIds, externalCollapsedParentIds]);
|
|
14995
15334
|
const handleExpandAll = useCallback10(() => {
|
|
14996
15335
|
if (externalCollapsedParentIds) return;
|
|
14997
15336
|
setInternalCollapsedParentIds(/* @__PURE__ */ new Set());
|
|
14998
|
-
|
|
15337
|
+
setExpandedCompositeIds(new Set(normalizedTasks.filter((task) => task.composite).map((task) => task.id)));
|
|
15338
|
+
}, [externalCollapsedParentIds, normalizedTasks]);
|
|
14999
15339
|
const exportToPdf = useCallback10(async (options) => {
|
|
15000
15340
|
const sourceContainer = containerRef.current;
|
|
15001
15341
|
if (!sourceContainer || typeof window === "undefined" || typeof document === "undefined") {
|
|
@@ -15167,7 +15507,7 @@ function TaskGanttChartInner(props, ref) {
|
|
|
15167
15507
|
onTasksChange?.(changedTasks);
|
|
15168
15508
|
}
|
|
15169
15509
|
}, [tasks, onTasksChange, onUngroupTask]);
|
|
15170
|
-
const panStateRef =
|
|
15510
|
+
const panStateRef = useRef13(null);
|
|
15171
15511
|
const handlePanStart = useCallback10((e) => {
|
|
15172
15512
|
if (e.button !== 0) return;
|
|
15173
15513
|
const target = e.target;
|
|
@@ -15192,7 +15532,7 @@ function TaskGanttChartInner(props, ref) {
|
|
|
15192
15532
|
container.style.cursor = "grabbing";
|
|
15193
15533
|
e.preventDefault();
|
|
15194
15534
|
}, []);
|
|
15195
|
-
|
|
15535
|
+
useEffect11(() => {
|
|
15196
15536
|
const flushPanMove = () => {
|
|
15197
15537
|
const pan = panStateRef.current;
|
|
15198
15538
|
if (!pan?.active) return;
|
|
@@ -15260,6 +15600,8 @@ function TaskGanttChartInner(props, ref) {
|
|
|
15260
15600
|
{
|
|
15261
15601
|
tasks: normalizedTasks,
|
|
15262
15602
|
rowHeight: effectiveRowHeight,
|
|
15603
|
+
rowTops: compositeRowLayout.tops,
|
|
15604
|
+
rowHeights: compositeRowLayout.heights,
|
|
15263
15605
|
headerHeight,
|
|
15264
15606
|
taskListWidth,
|
|
15265
15607
|
onTasksChange: handleTaskChange,
|
|
@@ -15454,6 +15796,8 @@ function TaskGanttChartInner(props, ref) {
|
|
|
15454
15796
|
gridWidth: renderGridWidth,
|
|
15455
15797
|
totalHeight: totalGridHeight,
|
|
15456
15798
|
rowIndexByTaskId: visibleTaskIndexMap,
|
|
15799
|
+
rowTops: compositeRowLayout.tops,
|
|
15800
|
+
rowHeights: compositeRowLayout.heights,
|
|
15457
15801
|
dragOverrides: dependencyOverrides,
|
|
15458
15802
|
selectedDep: selectedChip,
|
|
15459
15803
|
businessDays,
|
|
@@ -15540,10 +15884,10 @@ function TaskGanttChartInner(props, ref) {
|
|
|
15540
15884
|
{
|
|
15541
15885
|
style: {
|
|
15542
15886
|
position: "absolute",
|
|
15543
|
-
top: `${index
|
|
15887
|
+
top: `${compositeRowLayout.tops[index]}px`,
|
|
15544
15888
|
left: 0,
|
|
15545
15889
|
right: 0,
|
|
15546
|
-
height: `${
|
|
15890
|
+
height: `${compositeRowLayout.heights[index]}px`
|
|
15547
15891
|
},
|
|
15548
15892
|
children: /* @__PURE__ */ jsx21(
|
|
15549
15893
|
TaskRow_default,
|
|
@@ -15551,7 +15895,9 @@ function TaskGanttChartInner(props, ref) {
|
|
|
15551
15895
|
task,
|
|
15552
15896
|
monthStart,
|
|
15553
15897
|
dayWidth,
|
|
15554
|
-
rowHeight:
|
|
15898
|
+
rowHeight: compositeRowLayout.heights[index],
|
|
15899
|
+
compactDetail: compositeRowLayout.heights[index] < effectiveRowHeight,
|
|
15900
|
+
compositeParentColor: task.parentId ? compositeParentsById.get(task.parentId)?.color : void 0,
|
|
15555
15901
|
onTasksChange: handleTaskChange,
|
|
15556
15902
|
onDragStateChange: (state) => {
|
|
15557
15903
|
if (state.isDragging) {
|
|
@@ -15588,7 +15934,10 @@ function TaskGanttChartInner(props, ref) {
|
|
|
15588
15934
|
isDependencyDragActive: dependencyCreationDrag !== null,
|
|
15589
15935
|
viewMode,
|
|
15590
15936
|
showTaskDateLabels,
|
|
15591
|
-
showTaskNames
|
|
15937
|
+
showTaskNames,
|
|
15938
|
+
showCompositeSegments,
|
|
15939
|
+
onCompositeToggle: task.composite ? (source) => handleCompositeBarToggle(task.id, source) : void 0,
|
|
15940
|
+
compositeExpanded: task.composite ? !collapsedParentIds.has(task.id) : void 0
|
|
15592
15941
|
}
|
|
15593
15942
|
)
|
|
15594
15943
|
},
|
|
@@ -15601,6 +15950,7 @@ function TaskGanttChartInner(props, ref) {
|
|
|
15601
15950
|
rowHeight: effectiveRowHeight,
|
|
15602
15951
|
variant: "chart",
|
|
15603
15952
|
startIndex: visibleTasks.length,
|
|
15953
|
+
startTop: compositeRowLayout.totalHeight,
|
|
15604
15954
|
chartDayWidth: dayWidth,
|
|
15605
15955
|
chartStartDayOffset: todayInRange ? Math.max(0, todayIndex + Math.floor(Number.isFinite(skeletonStartOffsetDays) ? skeletonStartOffsetDays : 0)) : 0,
|
|
15606
15956
|
chartStartJitterDays: skeletonStartJitterDays
|