gantt-lib 0.142.2 → 0.143.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -3,7 +3,7 @@
3
3
  "use client";
4
4
 
5
5
  // src/components/GanttChart/GanttChart.tsx
6
- import { useMemo as useMemo14, useCallback as useCallback10, useRef as useRef13, useState as useState13, useEffect as useEffect12, useImperativeHandle, forwardRef } from "react";
6
+ import { useMemo as useMemo14, useCallback as useCallback11, useRef as useRef14, useState as useState13, useEffect as useEffect12, useImperativeHandle, forwardRef } from "react";
7
7
 
8
8
  // src/core/scheduling/dateMath.ts
9
9
  var DAY_MS = 24 * 60 * 60 * 1e3;
@@ -4610,6 +4610,7 @@ function createTaskPreviewPositionStore() {
4610
4610
  }
4611
4611
  function createActivityPreviewStore() {
4612
4612
  let overridesByTask = /* @__PURE__ */ new Map();
4613
+ let draggedRange;
4613
4614
  const listenersByTaskId = /* @__PURE__ */ new Map();
4614
4615
  function notify(taskIds) {
4615
4616
  for (const taskId of taskIds) {
@@ -4630,6 +4631,16 @@ function createActivityPreviewStore() {
4630
4631
  }
4631
4632
  };
4632
4633
  },
4634
+ getActivityRange(taskId, activityId) {
4635
+ return draggedRange?.taskId === taskId && draggedRange.activityId === activityId ? draggedRange : void 0;
4636
+ },
4637
+ setActivityRange(taskId, activityId, range) {
4638
+ if (draggedRange?.taskId === taskId && draggedRange.activityId === activityId && draggedRange.startDate.getTime() === range.startDate.getTime() && draggedRange.endDate.getTime() === range.endDate.getTime()) return;
4639
+ const changed = /* @__PURE__ */ new Set([taskId]);
4640
+ if (draggedRange) changed.add(draggedRange.taskId);
4641
+ draggedRange = { taskId, activityId, ...range };
4642
+ notify(changed);
4643
+ },
4633
4644
  getTaskOverrides(taskId) {
4634
4645
  return overridesByTask.get(taskId);
4635
4646
  },
@@ -4650,10 +4661,10 @@ function createActivityPreviewStore() {
4650
4661
  notify(changedTaskIds);
4651
4662
  },
4652
4663
  clear() {
4653
- if (overridesByTask.size === 0) {
4654
- return;
4655
- }
4664
+ if (overridesByTask.size === 0 && !draggedRange) return;
4656
4665
  const changedTaskIds = new Set(overridesByTask.keys());
4666
+ if (draggedRange) changedTaskIds.add(draggedRange.taskId);
4667
+ draggedRange = void 0;
4657
4668
  overridesByTask = /* @__PURE__ */ new Map();
4658
4669
  notify(changedTaskIds);
4659
4670
  }
@@ -4999,13 +5010,6 @@ var TaskRow = React2.memo(
4999
5010
  const activityDragStart = useRef2(null);
5000
5011
  const activityConstraintRef = useRef2(null);
5001
5012
  const [activityBlockedBy, setActivityBlockedBy] = useState2(null);
5002
- const visibleActivitySegments = useMemo2(() => {
5003
- if (!activityLayout) return [];
5004
- const window2 = horizontalWindow;
5005
- if (!window2) return activityLayout.segments;
5006
- const draggedId = activityDrag?.id;
5007
- return activityLayout.segments.filter((segment) => segment.id === draggedId || segment.left <= window2.endPx && segment.left + segment.width >= window2.startPx);
5008
- }, [activityLayout, horizontalWindow, activityDrag?.id]);
5009
5013
  const subscribeActivityOverrides = useCallback2(
5010
5014
  (listener) => activityPreviewStore?.subscribeTask(task.id, listener) ?? (() => {
5011
5015
  }),
@@ -5020,6 +5024,15 @@ var TaskRow = React2.memo(
5020
5024
  getActivityOverridesSnapshot,
5021
5025
  () => void 0
5022
5026
  );
5027
+ const visibleActivitySegments = useMemo2(() => {
5028
+ if (!activityLayout) return [];
5029
+ if (!horizontalWindow) return activityLayout.segments;
5030
+ return activityLayout.segments.filter((segment) => {
5031
+ if (segment.id === activityDrag?.id) return true;
5032
+ const left2 = segment.left + (activityOverrides?.get(segment.id) ?? 0) * dayWidth;
5033
+ return left2 <= horizontalWindow.endPx && left2 + segment.width >= horizontalWindow.startPx;
5034
+ });
5035
+ }, [activityLayout, horizontalWindow, activityDrag?.id, activityOverrides, dayWidth]);
5023
5036
  const subscribeActivityBlock = useCallback2(
5024
5037
  (listener) => activityBlockStore?.subscribeTask(task.id, listener) ?? (() => {
5025
5038
  }),
@@ -5145,6 +5158,11 @@ var TaskRow = React2.memo(
5145
5158
  });
5146
5159
  }
5147
5160
  publishChainPreview(activityDrag.id, activityDrag.mode, clamped);
5161
+ const sourceActivity = task.activities?.find((activity) => activity.id === activityDrag.id);
5162
+ if (sourceActivity) activityPreviewStore?.setActivityRange?.(task.id, activityDrag.id, {
5163
+ startDate: shiftActivityDay(sourceActivity.startDate, activityDrag.mode === "resize-right" ? 0 : clamped),
5164
+ endDate: shiftActivityDay(sourceActivity.endDate, activityDrag.mode === "resize-left" ? 0 : clamped)
5165
+ });
5148
5166
  };
5149
5167
  const onUp = () => {
5150
5168
  activityPreviewStore?.clear();
@@ -5250,6 +5268,53 @@ var TaskRow = React2.memo(
5250
5268
  }
5251
5269
  return { left: segment.left, width: segment.width + activityDrag.dayDelta * dayWidth };
5252
5270
  };
5271
+ const activityLinks = useMemo2(() => {
5272
+ const gaps = [];
5273
+ const elbows = [];
5274
+ if (!showActivityLinks || !renderActivities || !activityLayout) return { gaps, elbows };
5275
+ const activities = task.activities ?? [];
5276
+ const segmentById = new Map(activityLayout.segments.map((segment) => [segment.id, segment]));
5277
+ const visibleIds = new Set(visibleActivitySegments.map((segment) => segment.id));
5278
+ const laneTopY = (lane) => activityTopOffset + lane * ACTIVITY_LANE_STEP + (ACTIVITY_LANE_STEP - ACTIVITY_LANE_BAR_HEIGHT) / 2;
5279
+ const liveRect = (segment) => {
5280
+ const geometry = liveActivityGeometry(segment);
5281
+ const chainDelta = activityOverrides?.get(segment.id) ?? 0;
5282
+ const left2 = geometry.left + (chainDelta !== 0 ? chainDelta * dayWidth : 0);
5283
+ return { left: left2, right: left2 + geometry.width };
5284
+ };
5285
+ for (let index = 0; index < activities.length - 1; index += 1) {
5286
+ const predecessor = segmentById.get(activities[index].id);
5287
+ const successor = segmentById.get(activities[index + 1].id);
5288
+ if (!predecessor || !successor) continue;
5289
+ if (!visibleIds.has(predecessor.id) || !visibleIds.has(successor.id)) continue;
5290
+ const lag = activities[index + 1].lag ?? 0;
5291
+ const predRect = liveRect(predecessor);
5292
+ const succRect = liveRect(successor);
5293
+ if (predecessor.lane === successor.lane && succRect.left >= predRect.right) {
5294
+ const width2 = succRect.left - predRect.right;
5295
+ if (width2 >= 1) {
5296
+ gaps.push({ key: `${predecessor.id}->${successor.id}`, left: predRect.right, width: width2, lane: predecessor.lane, lag });
5297
+ }
5298
+ continue;
5299
+ }
5300
+ const predecessorLaneTop = laneTopY(predecessor.lane);
5301
+ const successorLaneTop = laneTopY(successor.lane);
5302
+ const sameLane = predecessor.lane === successor.lane;
5303
+ const reverseOrder = !sameLane && successorLaneTop < predecessorLaneTop;
5304
+ const fromY = reverseOrder ? predecessorLaneTop + 6 : predecessorLaneTop + ACTIVITY_LANE_BAR_HEIGHT - 6;
5305
+ const toY = reverseOrder ? successorLaneTop + ACTIVITY_LANE_BAR_HEIGHT - 6 : successorLaneTop + (sameLane ? ACTIVITY_LANE_STEP : 0) + 6;
5306
+ const fromX = predRect.right;
5307
+ const toX = succRect.left;
5308
+ elbows.push({
5309
+ key: `${predecessor.id}->${successor.id}`,
5310
+ d: calculateDependencyPath({ x: fromX, y: fromY }, { x: toX, y: toY }, false),
5311
+ lagX: toX - 14,
5312
+ lagY: reverseOrder ? fromY - 4 : fromY + 12,
5313
+ lag
5314
+ });
5315
+ }
5316
+ return { gaps, elbows };
5317
+ }, [showActivityLinks, renderActivities, activityLayout, visibleActivitySegments, activityTopOffset, activityOverrides, activityDrag, dayWidth, task.activities]);
5253
5318
  const activityTipData = useMemo2(() => {
5254
5319
  if (!activityTipId || !task.activities) return null;
5255
5320
  const activity = task.activities.find((item) => item.id === activityTipId);
@@ -5321,72 +5386,121 @@ var TaskRow = React2.memo(
5321
5386
  }
5322
5387
  }
5323
5388
  ),
5324
- renderActivities && activityLayout && /* @__PURE__ */ jsx2("div", { className: "gantt-tr-activityLanes", children: visibleActivitySegments.map((segment) => {
5325
- const live = liveActivityGeometry(segment);
5326
- const chainDelta = activityOverrides?.get(segment.id) ?? 0;
5327
- const activityProgress = segment.progress === void 0 ? 0 : Math.min(100, Math.max(0, Math.round(segment.progress)));
5328
- const liveLeft = live.left + (chainDelta !== 0 ? chainDelta * dayWidth : 0);
5329
- const isDraggingActivity = activityDrag?.id === segment.id;
5330
- const isBlockingActivity = blockedActivityIds?.has(segment.id) ?? false;
5331
- const isAtLimit = isDraggingActivity && activityBlockedBy !== null;
5332
- const isActiveActivity = activationVisualEnabled && activeActivityKey === activityOwnerKey(task.id, segment.id);
5333
- const isSameWorkType = activeWork !== null && (segment.id === activeWork.id || activeWork.name !== null && segment.name === activeWork.name);
5334
- const isDimmed = dimOthers && activeWork !== null && !isSameWorkType;
5335
- const isChainHighlighted = highlightChain && activeWork !== null && isSameWorkType;
5336
- return /* @__PURE__ */ jsxs2(
5337
- "div",
5338
- {
5339
- "data-activity-id": segment.id,
5340
- className: `gantt-tr-activityBar${isDraggingActivity ? " gantt-tr-activityBar-dragging" : ""}${isBlockingActivity ? " gantt-tr-activityBar-blocking" : ""}${isAtLimit ? " gantt-tr-activityBar-atLimit" : ""}${isActiveActivity ? " gantt-tr-activityBar-active" : ""}${isDimmed ? " gantt-tr-activityBar-dimmed" : ""}${isChainHighlighted ? " gantt-tr-activityBar-chain" : ""}${activityDragEnabled ? "" : " gantt-tr-activityBar-locked"}`,
5341
- style: {
5342
- left: `${liveLeft}px`,
5343
- width: `${live.width}px`,
5344
- top: `${activityTopOffset + segment.lane * ACTIVITY_LANE_STEP + (ACTIVITY_LANE_STEP - ACTIVITY_LANE_BAR_HEIGHT) / 2}px`,
5345
- height: `${ACTIVITY_LANE_BAR_HEIGHT}px`,
5346
- backgroundColor: segment.color || "var(--gantt-task-bar-default-color)"
5347
- },
5348
- onMouseDown: (event) => {
5349
- if (!activityDragEnabled) return;
5350
- const activationKey = activityOwnerKey(task.id, segment.id);
5351
- const isActive = activityActivationStore?.getActiveKey() === activationKey;
5352
- if (activationVisualEnabled && !isActive) {
5353
- activityActivationStore?.setActiveKey(activationKey);
5389
+ renderActivities && activityLayout && /* @__PURE__ */ jsxs2("div", { className: "gantt-tr-activityLanes", children: [
5390
+ activityLinks.elbows.length > 0 && /* @__PURE__ */ jsxs2("svg", { className: "gantt-tr-activityLinksSvg", width: "100%", height: "100%", "aria-hidden": "true", children: [
5391
+ /* @__PURE__ */ jsx2("defs", { children: /* @__PURE__ */ jsx2("marker", { id: "arrowhead", markerWidth: "8", markerHeight: "6", markerUnits: "userSpaceOnUse", refX: "7", refY: "3", orient: "auto", children: /* @__PURE__ */ jsx2("polygon", { points: "0 0, 8 3, 0 6", fill: "var(--gantt-dependency-line-color, #666666)" }) }) }),
5392
+ activityLinks.elbows.map((link) => /* @__PURE__ */ jsxs2("g", { children: [
5393
+ /* @__PURE__ */ jsx2("path", { className: "gantt-dependency-path", d: link.d, markerEnd: "url(#arrowhead)" }),
5394
+ showActivityLag && link.lag !== 0 && /* @__PURE__ */ jsx2(
5395
+ "text",
5396
+ {
5397
+ className: "gantt-dependency-lag-label",
5398
+ x: link.lagX,
5399
+ y: link.lagY,
5400
+ textAnchor: "middle",
5401
+ fontSize: "10",
5402
+ fill: "var(--gantt-dependency-line-color, #666666)",
5403
+ children: link.lag > 0 ? `+${link.lag}` : `${link.lag}`
5354
5404
  }
5355
- if (activityClickToDrag && !isActive) return;
5356
- const target = event.target;
5357
- const mode = target.closest(".gantt-tr-resizeHandleLeft") ? "resize-left" : target.closest(".gantt-tr-resizeHandleRight") ? "resize-right" : "move";
5358
- handleActivityPointerDown(segment, mode)(event);
5359
- },
5360
- onMouseEnter: (event) => {
5361
- if (activityDrag || activityDragOwner?.get()) return;
5362
- setActivityTipPosition(anchorActivityTip(event.currentTarget.getBoundingClientRect()));
5363
- setActivityTipId(segment.id);
5405
+ )
5406
+ ] }, link.key))
5407
+ ] }),
5408
+ visibleActivitySegments.map((segment) => {
5409
+ const live = liveActivityGeometry(segment);
5410
+ const chainDelta = activityOverrides?.get(segment.id) ?? 0;
5411
+ const activityProgress = segment.progress === void 0 ? 0 : Math.min(100, Math.max(0, Math.round(segment.progress)));
5412
+ const liveLeft = live.left + (chainDelta !== 0 ? chainDelta * dayWidth : 0);
5413
+ const isDraggingActivity = activityDrag?.id === segment.id;
5414
+ const isBlockingActivity = blockedActivityIds?.has(segment.id) ?? false;
5415
+ const isAtLimit = isDraggingActivity && activityBlockedBy !== null;
5416
+ const isActiveActivity = activationVisualEnabled && activeActivityKey === activityOwnerKey(task.id, segment.id);
5417
+ const isSameWorkType = activeWork !== null && (segment.id === activeWork.id || activeWork.name !== null && segment.name === activeWork.name);
5418
+ const isDimmed = dimOthers && activeWork !== null && !isSameWorkType;
5419
+ const isChainHighlighted = highlightChain && activeWork !== null && isSameWorkType;
5420
+ return /* @__PURE__ */ jsxs2(
5421
+ "div",
5422
+ {
5423
+ "data-activity-id": segment.id,
5424
+ className: `gantt-tr-activityBar${isDraggingActivity ? " gantt-tr-activityBar-dragging" : ""}${isBlockingActivity ? " gantt-tr-activityBar-blocking" : ""}${isAtLimit ? " gantt-tr-activityBar-atLimit" : ""}${isActiveActivity ? " gantt-tr-activityBar-active" : ""}${isDimmed ? " gantt-tr-activityBar-dimmed" : ""}${isChainHighlighted ? " gantt-tr-activityBar-chain" : ""}${activityDragEnabled ? "" : " gantt-tr-activityBar-locked"}`,
5425
+ style: {
5426
+ left: `${liveLeft}px`,
5427
+ width: `${live.width}px`,
5428
+ top: `${activityTopOffset + segment.lane * ACTIVITY_LANE_STEP + (ACTIVITY_LANE_STEP - ACTIVITY_LANE_BAR_HEIGHT) / 2}px`,
5429
+ height: `${ACTIVITY_LANE_BAR_HEIGHT}px`,
5430
+ backgroundColor: segment.color || "var(--gantt-task-bar-default-color)"
5431
+ },
5432
+ onMouseDown: (event) => {
5433
+ if (!activityDragEnabled) return;
5434
+ const activationKey = activityOwnerKey(task.id, segment.id);
5435
+ const isActive = activityActivationStore?.getActiveKey() === activationKey;
5436
+ if (activationVisualEnabled && !isActive) {
5437
+ activityActivationStore?.setActiveKey(activationKey);
5438
+ }
5439
+ if (activityClickToDrag && !isActive) return;
5440
+ const target = event.target;
5441
+ const mode = target.closest(".gantt-tr-resizeHandleLeft") ? "resize-left" : target.closest(".gantt-tr-resizeHandleRight") ? "resize-right" : "move";
5442
+ handleActivityPointerDown(segment, mode)(event);
5443
+ },
5444
+ onMouseEnter: (event) => {
5445
+ if (activityDrag || activityDragOwner?.get()) return;
5446
+ setActivityTipPosition(anchorActivityTip(event.currentTarget.getBoundingClientRect()));
5447
+ setActivityTipId(segment.id);
5448
+ },
5449
+ onMouseLeave: () => {
5450
+ if (!activityDrag) {
5451
+ setActivityTipId((current) => current === segment.id ? null : current);
5452
+ activityTipAnchor.current = null;
5453
+ setActivityTipPosition(null);
5454
+ }
5455
+ },
5456
+ children: [
5457
+ activityProgress > 0 && /* @__PURE__ */ jsx2(
5458
+ "span",
5459
+ {
5460
+ className: "gantt-tr-activityProgress",
5461
+ style: { width: `${activityProgress}%` }
5462
+ }
5463
+ ),
5464
+ /* @__PURE__ */ jsx2("span", { className: "gantt-tr-activityName", style: { color: activityTextColor(segment.color) }, children: segment.name }),
5465
+ activityDragEnabled && /* @__PURE__ */ jsxs2(Fragment, { children: [
5466
+ /* @__PURE__ */ jsx2("div", { className: "gantt-tr-resizeHandle gantt-tr-resizeHandleLeft" }),
5467
+ /* @__PURE__ */ jsx2("div", { className: "gantt-tr-resizeHandle gantt-tr-resizeHandleRight" })
5468
+ ] })
5469
+ ]
5364
5470
  },
5365
- onMouseLeave: () => {
5366
- if (!activityDrag) {
5367
- setActivityTipId((current) => current === segment.id ? null : current);
5368
- activityTipAnchor.current = null;
5369
- setActivityTipPosition(null);
5471
+ segment.id
5472
+ );
5473
+ }),
5474
+ activityLinks.gaps.map((gap) => /* @__PURE__ */ jsxs2(React2.Fragment, { children: [
5475
+ /* @__PURE__ */ jsx2(
5476
+ "span",
5477
+ {
5478
+ className: "gantt-tr-activityLink",
5479
+ "aria-hidden": "true",
5480
+ style: {
5481
+ left: `${gap.left}px`,
5482
+ width: `${gap.width}px`,
5483
+ top: `${activityTopOffset + gap.lane * ACTIVITY_LANE_STEP + ACTIVITY_LANE_STEP / 2}px`
5370
5484
  }
5371
- },
5372
- children: [
5373
- activityProgress > 0 && /* @__PURE__ */ jsx2(
5374
- "span",
5375
- {
5376
- className: "gantt-tr-activityProgress",
5377
- style: { width: `${activityProgress}%` }
5378
- }
5379
- ),
5380
- /* @__PURE__ */ jsx2("span", { className: "gantt-tr-activityName", style: { color: activityTextColor(segment.color) }, children: segment.name }),
5381
- activityDragEnabled && /* @__PURE__ */ jsxs2(Fragment, { children: [
5382
- /* @__PURE__ */ jsx2("div", { className: "gantt-tr-resizeHandle gantt-tr-resizeHandleLeft" }),
5383
- /* @__PURE__ */ jsx2("div", { className: "gantt-tr-resizeHandle gantt-tr-resizeHandleRight" })
5384
- ] })
5385
- ]
5386
- },
5387
- segment.id
5388
- );
5389
- }) }),
5485
+ }
5486
+ ),
5487
+ showActivityLag && gap.lag > 0 && /* @__PURE__ */ jsxs2(
5488
+ "span",
5489
+ {
5490
+ className: "gantt-tr-activityLag",
5491
+ title: `\u0417\u0430\u0437\u043E\u0440 ${gap.lag} \u0434`,
5492
+ style: {
5493
+ left: `${gap.left + gap.width - 14}px`,
5494
+ top: `${activityTopOffset + gap.lane * ACTIVITY_LANE_STEP + ACTIVITY_LANE_STEP / 2}px`
5495
+ },
5496
+ children: [
5497
+ "+",
5498
+ gap.lag
5499
+ ]
5500
+ }
5501
+ )
5502
+ ] }, gap.key))
5503
+ ] }),
5390
5504
  !renderActivities && /* @__PURE__ */ jsxs2(
5391
5505
  "div",
5392
5506
  {
@@ -5929,7 +6043,7 @@ var DragGuideLines = ({
5929
6043
  var DragGuideLines_default = DragGuideLines;
5930
6044
 
5931
6045
  // src/components/DependencyLines/DependencyLines.tsx
5932
- import React6, { useId, useMemo as useMemo6, useState as useState3 } from "react";
6046
+ import React6, { useCallback as useCallback3, useId, useMemo as useMemo6, useState as useState3 } from "react";
5933
6047
  import { Fragment as Fragment3, jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
5934
6048
  function isTaskHidden(taskId, collapsedParentIds, taskMap) {
5935
6049
  const task = taskMap.get(taskId);
@@ -5959,6 +6073,74 @@ function areBothHiddenInSameParent(predecessorId, successorId, collapsedParentId
5959
6073
  return predVisibleAncestor.id === succVisibleAncestor.id;
5960
6074
  }
5961
6075
  var EMPTY_COLLAPSED_PARENT_IDS = /* @__PURE__ */ new Set();
6076
+ var DependencyLineView = React6.memo(function DependencyLineView2({
6077
+ line,
6078
+ hovered,
6079
+ selected,
6080
+ showLag,
6081
+ markerPrefix,
6082
+ onLineHover,
6083
+ onLineLeave,
6084
+ onDependencyClick
6085
+ }) {
6086
+ const { id, predecessorId, successorId, linkType, path, hasCycle, lag, toX, fromY, reverseOrder, isVirtual, isCoupling } = line;
6087
+ const interactive = !isCoupling && onDependencyClick !== void 0;
6088
+ let pathClassName = "gantt-dependency-path";
6089
+ if (selected) pathClassName += " gantt-dependency-selected";
6090
+ else if (hasCycle) pathClassName += " gantt-dependency-cycle";
6091
+ else if (line.isCritical) pathClassName += " gantt-dependency-critical";
6092
+ if (isVirtual && !selected) pathClassName += " gantt-dependency-virtual";
6093
+ let markerEnd;
6094
+ if (hovered) markerEnd = `url(#${markerPrefix}-arrowhead-hover)`;
6095
+ else if (selected) markerEnd = `url(#${markerPrefix}-arrowhead-selected)`;
6096
+ else if (hasCycle) markerEnd = `url(#${markerPrefix}-arrowhead-cycle)`;
6097
+ else if (line.isCritical) markerEnd = `url(#${markerPrefix}-arrowhead-critical)`;
6098
+ else markerEnd = `url(#${markerPrefix}-arrowhead)`;
6099
+ const lagColor = selected ? "#ef4444" : hasCycle ? "var(--gantt-dependency-cycle-color, #ef4444)" : line.isCritical ? "var(--gantt-critical-path-color, #dc2626)" : "var(--gantt-dependency-line-color, #666666)";
6100
+ return /* @__PURE__ */ jsxs5(React6.Fragment, { children: [
6101
+ /* @__PURE__ */ jsx7(
6102
+ "g",
6103
+ {
6104
+ className: `gantt-dependency-line${interactive ? "" : " gantt-dependency-line-static"}${hovered && interactive ? " gantt-dependency-line-hovered" : ""}`,
6105
+ onPointerEnter: interactive ? () => onLineHover(id) : void 0,
6106
+ onPointerLeave: interactive ? () => onLineLeave(id) : void 0,
6107
+ onClick: interactive ? (event) => {
6108
+ event.stopPropagation();
6109
+ onDependencyClick?.({
6110
+ predecessorId,
6111
+ successorId,
6112
+ linkType,
6113
+ x: toX,
6114
+ y: reverseOrder ? fromY - 4 : fromY + 12
6115
+ });
6116
+ } : void 0,
6117
+ role: interactive ? "button" : void 0,
6118
+ "aria-label": interactive ? `\u0421\u0432\u044F\u0437\u044C ${linkType}` : void 0,
6119
+ children: isCoupling ? /* @__PURE__ */ jsx7("line", { x1: toX - 4.5, y1: fromY, x2: toX + 4.5, y2: fromY, className: `${pathClassName} gantt-dependency-coupling` }) : /* @__PURE__ */ jsxs5(Fragment3, { children: [
6120
+ interactive && /* @__PURE__ */ jsx7("path", { d: path, className: "gantt-dependency-hit-area" }),
6121
+ /* @__PURE__ */ jsx7("path", { d: path, className: pathClassName, markerEnd })
6122
+ ] })
6123
+ }
6124
+ ),
6125
+ showLag && lag !== 0 && /* @__PURE__ */ jsx7(
6126
+ "text",
6127
+ {
6128
+ className: "gantt-dependency-lag-label",
6129
+ x: lag < 0 ? toX + 14 : toX - 14,
6130
+ y: reverseOrder ? fromY - 4 : fromY + 12,
6131
+ textAnchor: "middle",
6132
+ fontSize: "10",
6133
+ fill: lagColor,
6134
+ children: lag > 0 ? `+${lag}` : `${lag}`
6135
+ }
6136
+ )
6137
+ ] });
6138
+ }, (prev, next) => (
6139
+ // Сравнение по значению, а не по ссылке линии: пересчёт геометрии на каждом
6140
+ // бакете вертикальной прокрутки создаёт новые объекты линий с той же
6141
+ // геометрией — пере-рендерить их нельзя, иначе пан дёргается.
6142
+ prev.line.id === next.line.id && prev.line.predecessorId === next.line.predecessorId && prev.line.successorId === next.line.successorId && prev.line.linkType === next.line.linkType && prev.line.path === next.line.path && prev.line.hasCycle === next.line.hasCycle && prev.line.lag === next.line.lag && prev.line.toX === next.line.toX && prev.line.fromY === next.line.fromY && prev.line.reverseOrder === next.line.reverseOrder && prev.line.isVirtual === next.line.isVirtual && prev.line.isCritical === next.line.isCritical && prev.line.isCoupling === next.line.isCoupling && prev.hovered === next.hovered && prev.selected === next.selected && prev.showLag === next.showLag && prev.markerPrefix === next.markerPrefix && prev.onLineHover === next.onLineHover && prev.onLineLeave === next.onLineLeave && prev.onDependencyClick === next.onDependencyClick
6143
+ ));
5962
6144
  var DependencyLines = React6.memo(({
5963
6145
  tasks,
5964
6146
  allTasks,
@@ -5974,6 +6156,7 @@ var DependencyLines = React6.memo(({
5974
6156
  dragOverrides,
5975
6157
  selectedDep,
5976
6158
  criticalTaskIds,
6159
+ cycleTaskIds,
5977
6160
  showLag = true,
5978
6161
  activityEndpoints = false,
5979
6162
  businessDays = true,
@@ -5984,13 +6167,16 @@ var DependencyLines = React6.memo(({
5984
6167
  const markerPrefix = `gantt-dependency-${useId().replace(/[^a-zA-Z0-9_-]/g, "")}`;
5985
6168
  const markerId = (kind) => `${markerPrefix}-${kind}`;
5986
6169
  const [hoveredLineId, setHoveredLineId] = useState3(null);
6170
+ const handleLineHover = useCallback3((id) => setHoveredLineId(id), []);
6171
+ const handleLineLeave = useCallback3((id) => setHoveredLineId((current) => current === id ? null : current), []);
5987
6172
  const tasksForPositions = allTasks ?? tasks;
6173
+ const geometryTasks = activityEndpoints ? tasksForPositions : tasks;
5988
6174
  const { taskPositions, taskIndices, hiddenTaskIds } = useMemo6(() => {
5989
6175
  const positions = /* @__PURE__ */ new Map();
5990
6176
  const indices = /* @__PURE__ */ new Map();
5991
6177
  const hidden = /* @__PURE__ */ new Set();
5992
6178
  const taskMap = new Map(tasksForPositions.map((t) => [t.id, t]));
5993
- tasks.forEach((task, index) => {
6179
+ geometryTasks.forEach((task, index) => {
5994
6180
  const override = dragOverrides?.get(task.id);
5995
6181
  const computed = resolveTaskHorizontalGeometry(task, monthStart, dayWidth, override);
5996
6182
  const rowIndex = rowIndexByTaskId?.get(task.id) ?? index;
@@ -6046,18 +6232,19 @@ var DependencyLines = React6.memo(({
6046
6232
  }
6047
6233
  }
6048
6234
  return { taskPositions: positions, taskIndices: indices, hiddenTaskIds: hidden };
6049
- }, [tasks, tasksForPositions, allTasks, collapsedParentIds, monthStart, dayWidth, rowHeight, rowTops, rowHeights, dragOverrides, rowIndexByTaskId]);
6235
+ }, [geometryTasks, tasksForPositions, allTasks, collapsedParentIds, monthStart, dayWidth, rowHeight, rowTops, rowHeights, dragOverrides, rowIndexByTaskId]);
6050
6236
  const tasksForCycleDetection = allTasks ?? tasks;
6051
6237
  const cycleInfo = useMemo6(() => {
6238
+ if (cycleTaskIds) return cycleTaskIds;
6052
6239
  const result = detectCycles(tasksForCycleDetection);
6053
- const cycleTaskIds = new Set(result.cyclePath || []);
6054
- return cycleTaskIds;
6055
- }, [tasksForCycleDetection]);
6240
+ const detectedCycleIds = new Set(result.cyclePath || []);
6241
+ return detectedCycleIds;
6242
+ }, [tasksForCycleDetection, cycleTaskIds]);
6056
6243
  const lines = useMemo6(() => {
6057
- const tasksForEdges = allTasks ?? tasks;
6244
+ const tasksForEdges = allTasks ?? geometryTasks;
6058
6245
  const taskMap = new Map(tasksForEdges.map((task) => [task.id, task]));
6059
6246
  const positionedTaskIds = Array.from(taskPositions.keys());
6060
- const renderedTaskIdSet = new Set(tasks.map((t) => t.id));
6247
+ const renderedTaskIdSet = new Set(geometryTasks.map((t) => t.id));
6061
6248
  const lines2 = [];
6062
6249
  for (const successorId of positionedTaskIds) {
6063
6250
  const successorTaskForEdges = taskMap.get(successorId);
@@ -6152,16 +6339,20 @@ var DependencyLines = React6.memo(({
6152
6339
  }
6153
6340
  }
6154
6341
  return lines2;
6155
- }, [tasks, allTasks, taskPositions, taskIndices, cycleInfo, collapsedParentIds, criticalTaskIds, activityEndpoints]);
6342
+ }, [geometryTasks, allTasks, taskPositions, taskIndices, cycleInfo, collapsedParentIds, criticalTaskIds, activityEndpoints]);
6156
6343
  const visibleLines = useMemo6(() => {
6157
- if (!horizontalWindow) return lines;
6158
- return lines.filter((line) => Math.max(line.fromX, line.toX) >= horizontalWindow.startPx && Math.min(line.fromX, line.toX) <= horizontalWindow.endPx);
6159
- }, [lines, horizontalWindow?.startPx, horizontalWindow?.endPx]);
6344
+ const renderedIds = activityEndpoints ? new Set(tasks.map((task) => task.id)) : void 0;
6345
+ return lines.filter((line) => {
6346
+ if (renderedIds && !renderedIds.has(line.predecessorId) && !renderedIds.has(line.successorId)) return false;
6347
+ return !horizontalWindow || Math.max(line.fromX, line.toX) >= horizontalWindow.startPx && Math.min(line.fromX, line.toX) <= horizontalWindow.endPx;
6348
+ });
6349
+ }, [lines, activityEndpoints, tasks, horizontalWindow?.startPx, horizontalWindow?.endPx]);
6160
6350
  const svgHeight = totalHeight ?? tasks.length * rowHeight;
6351
+ const interactive = onDependencyClick !== void 0;
6161
6352
  return /* @__PURE__ */ jsxs5(
6162
6353
  "svg",
6163
6354
  {
6164
- className: "gantt-dependencies-svg",
6355
+ className: `gantt-dependencies-svg${interactive ? "" : " gantt-dependencies-svg-static"}`,
6165
6356
  "data-testid": "dependency-lines-svg",
6166
6357
  width: gridWidth,
6167
6358
  height: svgHeight,
@@ -6264,63 +6455,22 @@ var DependencyLines = React6.memo(({
6264
6455
  }
6265
6456
  )
6266
6457
  ] }),
6267
- visibleLines.map(({ id, predecessorId, successorId, linkType, path, hasCycle, lag, fromX, toX, fromY, reverseOrder, isVirtual, isCritical, isCoupling }) => {
6268
- const isHovered = hoveredLineId === id;
6269
- const isSelected = selectedDep != null && id === `${selectedDep.predecessorId}-${selectedDep.successorId}-${selectedDep.linkType}`;
6270
- let pathClassName = "gantt-dependency-path";
6271
- if (isSelected) pathClassName += " gantt-dependency-selected";
6272
- else if (hasCycle) pathClassName += " gantt-dependency-cycle";
6273
- else if (isCritical) pathClassName += " gantt-dependency-critical";
6274
- if (isVirtual && !isSelected) pathClassName += " gantt-dependency-virtual";
6275
- let markerEnd;
6276
- if (isHovered) markerEnd = `url(#${markerId("arrowhead-hover")})`;
6277
- else if (isSelected) markerEnd = `url(#${markerId("arrowhead-selected")})`;
6278
- else if (hasCycle) markerEnd = `url(#${markerId("arrowhead-cycle")})`;
6279
- else if (isCritical) markerEnd = `url(#${markerId("arrowhead-critical")})`;
6280
- else markerEnd = `url(#${markerId("arrowhead")})`;
6281
- const lagColor = isSelected ? "#ef4444" : hasCycle ? "var(--gantt-dependency-cycle-color, #ef4444)" : isCritical ? "var(--gantt-critical-path-color, #dc2626)" : "var(--gantt-dependency-line-color, #666666)";
6282
- return /* @__PURE__ */ jsxs5(React6.Fragment, { children: [
6283
- /* @__PURE__ */ jsx7(
6284
- "g",
6285
- {
6286
- className: `gantt-dependency-line${isHovered ? " gantt-dependency-line-hovered" : ""}`,
6287
- onPointerEnter: () => setHoveredLineId(id),
6288
- onPointerLeave: () => setHoveredLineId((current) => current === id ? null : current),
6289
- onClick: (event) => {
6290
- event.stopPropagation();
6291
- onDependencyClick?.({
6292
- predecessorId,
6293
- successorId,
6294
- linkType,
6295
- x: toX,
6296
- y: reverseOrder ? fromY - 4 : fromY + 12
6297
- });
6298
- },
6299
- role: "button",
6300
- "aria-label": `\u0421\u0432\u044F\u0437\u044C ${linkType}`,
6301
- children: isCoupling ? /* @__PURE__ */ jsxs5(Fragment3, { children: [
6302
- /* @__PURE__ */ jsx7("title", { children: "\u041F\u043E\u0441\u043B\u0435 \u043E\u043A\u043E\u043D\u0447\u0430\u043D\u0438\u044F \xB7 \u0431\u0435\u0437 \u043B\u0430\u0433\u0430" }),
6303
- /* @__PURE__ */ jsx7("circle", { cx: toX, cy: fromY, r: 12, className: "gantt-dependency-coupling-hit-area" }),
6304
- /* @__PURE__ */ jsx7("circle", { cx: toX, cy: fromY, r: 4, className: `${pathClassName} gantt-dependency-coupling` })
6305
- ] }) : /* @__PURE__ */ jsxs5(Fragment3, { children: [
6306
- /* @__PURE__ */ jsx7("path", { d: path, className: "gantt-dependency-hit-area" }),
6307
- /* @__PURE__ */ jsx7("path", { d: path, className: pathClassName, markerEnd })
6308
- ] })
6309
- }
6310
- ),
6311
- showLag && lag !== 0 && /* @__PURE__ */ jsx7(
6312
- "text",
6313
- {
6314
- className: "gantt-dependency-lag-label",
6315
- x: lag < 0 ? toX + 14 : toX - 14,
6316
- y: reverseOrder ? fromY - 4 : fromY + 12,
6317
- textAnchor: "middle",
6318
- fontSize: "10",
6319
- fill: lagColor,
6320
- children: lag > 0 ? `+${lag}` : `${lag}`
6321
- }
6322
- )
6323
- ] }, id);
6458
+ visibleLines.map((line) => {
6459
+ const isSelected = selectedDep != null && line.id === `${selectedDep.predecessorId}-${selectedDep.successorId}-${selectedDep.linkType}`;
6460
+ return /* @__PURE__ */ jsx7(
6461
+ DependencyLineView,
6462
+ {
6463
+ line,
6464
+ hovered: hoveredLineId === line.id,
6465
+ selected: isSelected,
6466
+ showLag,
6467
+ markerPrefix,
6468
+ onLineHover: handleLineHover,
6469
+ onLineLeave: handleLineLeave,
6470
+ onDependencyClick
6471
+ },
6472
+ line.id
6473
+ );
6324
6474
  })
6325
6475
  ]
6326
6476
  }
@@ -6330,9 +6480,17 @@ DependencyLines.displayName = "DependencyLines";
6330
6480
  var DependencyLines_default = DependencyLines;
6331
6481
 
6332
6482
  // src/components/DependencyLines/ActivityDependencyLines.tsx
6333
- import { useEffect as useEffect3, useMemo as useMemo7, useReducer } from "react";
6483
+ import { useEffect as useEffect3, useMemo as useMemo7, useReducer, useRef as useRef3 } from "react";
6334
6484
  import { jsx as jsx8 } from "react/jsx-runtime";
6335
6485
  var activityKey = (taskId, activityId) => JSON.stringify([taskId, activityId]);
6486
+ var sameDependencies = (left, right) => {
6487
+ if (left === right) return true;
6488
+ if (!left || !right || left.length !== right.length) return false;
6489
+ return left.every((dep, index) => {
6490
+ const other = right[index];
6491
+ return dep.taskId === other.taskId && dep.type === other.type && dep.lag === other.lag && dep.hidden === other.hidden;
6492
+ });
6493
+ };
6336
6494
  function ActivityDependencyLines(props) {
6337
6495
  const { tasks, dependencies, monthStart, dayWidth, previewStore } = props;
6338
6496
  const [previewVersion, refresh] = useReducer((value) => value + 1, 0);
@@ -6340,15 +6498,29 @@ function ActivityDependencyLines(props) {
6340
6498
  const cleanups = tasks.filter((task) => task.activities?.length).map((task) => previewStore?.subscribeTask(task.id, refresh));
6341
6499
  return () => cleanups.forEach((cleanup) => cleanup?.());
6342
6500
  }, [tasks, previewStore]);
6501
+ const cycleTaskIds = useMemo7(() => {
6502
+ const incoming = /* @__PURE__ */ new Map();
6503
+ for (const edge of dependencies) {
6504
+ const id = activityKey(edge.successorTaskId, edge.successorActivityId);
6505
+ const values = incoming.get(id) ?? [];
6506
+ values.push({ taskId: activityKey(edge.predecessorTaskId, edge.predecessorActivityId), type: edge.type, lag: edge.lag ?? 0 });
6507
+ incoming.set(id, values);
6508
+ }
6509
+ const nodes = tasks.flatMap((task) => (task.activities ?? []).map((activity) => ({ id: activityKey(task.id, activity.id), name: activity.name, startDate: activity.startDate, endDate: activity.endDate, dependencies: incoming.get(activityKey(task.id, activity.id)) })));
6510
+ return new Set(detectCycles(nodes).cyclePath ?? []);
6511
+ }, [tasks, dependencies]);
6512
+ const layoutCacheRef = useRef3(/* @__PURE__ */ new Map());
6343
6513
  const layout = useMemo7(() => {
6344
- const flattened = [], rendered = [], tops = [], heights = [];
6514
+ const flattened = [], tops = [], heights = [];
6515
+ const nodesByTaskId = /* @__PURE__ */ new Map();
6345
6516
  const indices = /* @__PURE__ */ new Map();
6346
6517
  const neededRows = /* @__PURE__ */ new Set();
6347
6518
  const incoming = /* @__PURE__ */ new Map();
6348
6519
  const selected = props.highlight ? new Set(props.highlight.activities.map((activity) => activityKey(activity.taskId, activity.activityId))) : void 0;
6349
6520
  const highlightMode = props.highlight?.mode ?? "chain";
6350
6521
  for (const edge of dependencies) {
6351
- if (!props.renderedTaskIds.has(edge.predecessorTaskId) && !props.renderedTaskIds.has(edge.successorTaskId)) continue;
6522
+ const isCrossRow = edge.predecessorTaskId !== edge.successorTaskId;
6523
+ if (isCrossRow && !props.highlight) continue;
6352
6524
  if (selected) {
6353
6525
  const fromSelected = selected.has(activityKey(edge.predecessorTaskId, edge.predecessorActivityId));
6354
6526
  const toSelected = selected.has(activityKey(edge.successorTaskId, edge.successorActivityId));
@@ -6361,33 +6533,75 @@ function ActivityDependencyLines(props) {
6361
6533
  neededRows.add(edge.successorTaskId);
6362
6534
  const id = activityKey(edge.successorTaskId, edge.successorActivityId);
6363
6535
  const values = incoming.get(id) ?? [];
6364
- values.push({ taskId: activityKey(edge.predecessorTaskId, edge.predecessorActivityId), type: edge.type, lag: edge.lag });
6536
+ values.push({ taskId: activityKey(edge.predecessorTaskId, edge.predecessorActivityId), type: edge.type, lag: edge.lag ?? 0 });
6365
6537
  incoming.set(id, values);
6366
6538
  }
6539
+ const monthStartMs = monthStart.getTime();
6540
+ const cache = layoutCacheRef.current;
6367
6541
  for (const task of tasks) {
6368
6542
  if (!neededRows.has(task.id)) continue;
6369
6543
  const row = props.rowIndexByTaskId.get(task.id);
6370
6544
  if (row === void 0 || !task.activities?.length) continue;
6371
6545
  const height = props.rowHeights[row] ?? props.rowHeight;
6372
6546
  if (height < props.rowHeight) continue;
6373
- const packed = computeActivityLanes(task.activities, monthStart, dayWidth);
6374
- const offset = Math.max(0, (height - packed.laneCount * ACTIVITY_LANE_STEP) / 2);
6375
- const segments2 = new Map(packed.segments.map((segment) => [segment.id, segment]));
6376
- for (const activity of task.activities) {
6377
- const segment = segments2.get(activity.id);
6378
- const id = activityKey(task.id, activity.id), index = flattened.length;
6379
- const delta = previewStore?.getTaskOverrides(task.id)?.get(activity.id) ?? 0;
6380
- const node = { id, name: activity.name, startDate: shiftActivityDate(activity.startDate, delta), endDate: shiftActivityDate(activity.endDate, delta), dependencies: incoming.get(id) };
6547
+ const activities = task.activities;
6548
+ const overrides = previewStore?.getTaskOverrides(task.id);
6549
+ let range;
6550
+ for (const activity of activities) {
6551
+ const current = previewStore?.getActivityRange?.(task.id, activity.id);
6552
+ if (current) {
6553
+ range = current;
6554
+ break;
6555
+ }
6556
+ }
6557
+ let entry = cache.get(task.id);
6558
+ const reusable = entry && entry.activities === activities && entry.monthStartMs === monthStartMs && entry.dayWidth === dayWidth && entry.overrides === overrides && entry.range === range && entry.nodes.length === activities.length && entry.nodes.every((node, index) => node.name === activities[index].name && node.startDate === activities[index].startDate && node.endDate === activities[index].endDate && sameDependencies(node.dependencies, incoming.get(node.id)));
6559
+ if (!entry || !reusable) {
6560
+ const liveActivities = activities.map((activity) => {
6561
+ const activityRange = previewStore?.getActivityRange?.(task.id, activity.id);
6562
+ if (activityRange) return { ...activity, startDate: activityRange.startDate, endDate: activityRange.endDate };
6563
+ const delta = overrides?.get(activity.id) ?? 0;
6564
+ if (delta === 0) return activity;
6565
+ return { ...activity, startDate: shiftActivityDate(activity.startDate, delta), endDate: shiftActivityDate(activity.endDate, delta) };
6566
+ });
6567
+ const packed = computeActivityLanes(liveActivities, monthStart, dayWidth);
6568
+ const lanes = new Map(packed.segments.map((segment) => [segment.id, segment.lane]));
6569
+ const rawIds = liveActivities.map((activity) => activity.id);
6570
+ const nodes = liveActivities.map((activity) => ({
6571
+ id: activityKey(task.id, activity.id),
6572
+ name: activity.name,
6573
+ startDate: activity.startDate,
6574
+ endDate: activity.endDate,
6575
+ dependencies: incoming.get(activityKey(task.id, activity.id))
6576
+ }));
6577
+ entry = { activities, monthStartMs, dayWidth, overrides, range, laneCount: packed.laneCount, lanes, rawIds, nodes };
6578
+ cache.set(task.id, entry);
6579
+ }
6580
+ const offset = Math.max(0, (height - entry.laneCount * ACTIVITY_LANE_STEP) / 2);
6581
+ nodesByTaskId.set(task.id, entry.nodes);
6582
+ entry.nodes.forEach((node, nodeIndex) => {
6583
+ const lane = entry.lanes.get(entry.rawIds[nodeIndex]) ?? 0;
6584
+ const index = flattened.length;
6381
6585
  flattened.push(node);
6382
- if (props.renderedTaskIds.has(task.id)) rendered.push(node);
6383
- indices.set(id, index);
6384
- tops.push((props.rowTops[row] ?? row * props.rowHeight) + offset + segment.lane * ACTIVITY_LANE_STEP + (ACTIVITY_LANE_STEP - ACTIVITY_LANE_BAR_HEIGHT) / 2);
6586
+ indices.set(node.id, index);
6587
+ tops.push((props.rowTops[row] ?? row * props.rowHeight) + offset + lane * ACTIVITY_LANE_STEP + (ACTIVITY_LANE_STEP - ACTIVITY_LANE_BAR_HEIGHT) / 2);
6385
6588
  heights.push(ACTIVITY_LANE_BAR_HEIGHT);
6386
- }
6589
+ });
6590
+ }
6591
+ for (const taskId of cache.keys()) {
6592
+ if (!nodesByTaskId.has(taskId)) cache.delete(taskId);
6387
6593
  }
6388
- return { flattened, rendered, indices, tops, heights };
6389
- }, [tasks, dependencies, props.highlight, monthStart, dayWidth, props.rowIndexByTaskId, props.rowTops, props.rowHeights, props.rowHeight, props.renderedTaskIds, previewStore, previewVersion]);
6390
- return /* @__PURE__ */ jsx8(DependencyLines, { tasks: layout.rendered, allTasks: layout.flattened, monthStart, dayWidth, rowHeight: ACTIVITY_LANE_BAR_HEIGHT, gridWidth: props.gridWidth, totalHeight: props.totalHeight, rowIndexByTaskId: layout.indices, rowTops: layout.tops, rowHeights: layout.heights, horizontalWindow: props.horizontalWindow, showLag: props.showLag, activityEndpoints: true });
6594
+ return { flattened, nodesByTaskId, indices, tops, heights };
6595
+ }, [tasks, dependencies, props.highlight, monthStart, dayWidth, props.rowIndexByTaskId, props.rowTops, props.rowHeights, props.rowHeight, previewStore, previewVersion]);
6596
+ const rendered = useMemo7(() => {
6597
+ const nodes = [];
6598
+ for (const taskId of props.renderedTaskIds) {
6599
+ const rowNodes = layout.nodesByTaskId.get(taskId);
6600
+ if (rowNodes) nodes.push(...rowNodes);
6601
+ }
6602
+ return nodes;
6603
+ }, [layout, props.renderedTaskIds]);
6604
+ return /* @__PURE__ */ jsx8(DependencyLines, { tasks: rendered, allTasks: layout.flattened, monthStart, dayWidth, rowHeight: ACTIVITY_LANE_BAR_HEIGHT, gridWidth: props.gridWidth, totalHeight: props.totalHeight, rowIndexByTaskId: layout.indices, rowTops: layout.tops, rowHeights: layout.heights, horizontalWindow: props.horizontalWindow, showLag: props.showLag, cycleTaskIds, activityEndpoints: true });
6391
6605
  }
6392
6606
 
6393
6607
  // src/components/DependencyCreationOverlay/DependencyCreationOverlay.tsx
@@ -6447,7 +6661,7 @@ var DependencyCreationOverlay = ({ drag, width, height }) => {
6447
6661
  };
6448
6662
 
6449
6663
  // src/components/TaskList/TaskList.tsx
6450
- import React14, { useMemo as useMemo10, useCallback as useCallback6, useState as useState8, useEffect as useEffect8, useRef as useRef8 } from "react";
6664
+ import React14, { useMemo as useMemo10, useCallback as useCallback7, useState as useState8, useEffect as useEffect8, useRef as useRef9 } from "react";
6451
6665
 
6452
6666
  // src/utils/taskListReorder.ts
6453
6667
  function getDescendantIds(taskId, tasks) {
@@ -6653,9 +6867,9 @@ var PopoverContent = ({
6653
6867
  // src/components/TaskList/TaskListRow.tsx
6654
6868
  import React11, {
6655
6869
  useState as useState6,
6656
- useRef as useRef5,
6870
+ useRef as useRef6,
6657
6871
  useEffect as useEffect6,
6658
- useCallback as useCallback5,
6872
+ useCallback as useCallback6,
6659
6873
  useMemo as useMemo9
6660
6874
  } from "react";
6661
6875
 
@@ -6677,15 +6891,15 @@ var Input = React8.forwardRef(
6677
6891
  Input.displayName = "Input";
6678
6892
 
6679
6893
  // src/components/ui/DatePicker.tsx
6680
- import { useState as useState5, useCallback as useCallback4, useEffect as useEffect5, useRef as useRef4 } from "react";
6894
+ import { useState as useState5, useCallback as useCallback5, useEffect as useEffect5, useRef as useRef5 } from "react";
6681
6895
  import { format as format3, isValid, parse, addDays, addMonths as addMonths2, addYears, subMonths as subMonths2, subYears, subDays } from "date-fns";
6682
6896
 
6683
6897
  // src/components/ui/Calendar.tsx
6684
6898
  import {
6685
6899
  useState as useState4,
6686
- useRef as useRef3,
6900
+ useRef as useRef4,
6687
6901
  useEffect as useEffect4,
6688
- useCallback as useCallback3,
6902
+ useCallback as useCallback4,
6689
6903
  useMemo as useMemo8
6690
6904
  } from "react";
6691
6905
  import {
@@ -6719,7 +6933,7 @@ var Calendar = ({
6719
6933
  disabled = false,
6720
6934
  isWeekend: isWeekendProp
6721
6935
  }) => {
6722
- const scrollRef = useRef3(null);
6936
+ const scrollRef = useRef4(null);
6723
6937
  const initialMonth = useMemo8(
6724
6938
  () => startOfMonth(initialDate ?? selected ?? /* @__PURE__ */ new Date()),
6725
6939
  // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -6730,7 +6944,7 @@ var Calendar = ({
6730
6944
  initialMonth,
6731
6945
  addMonths(initialMonth, 1)
6732
6946
  ]);
6733
- const loadMoreMonths = useCallback3((direction) => {
6947
+ const loadMoreMonths = useCallback4((direction) => {
6734
6948
  setMonths((prev) => {
6735
6949
  if (direction === "up") {
6736
6950
  return [subMonths(prev[0], 1), ...prev];
@@ -6766,7 +6980,7 @@ var Calendar = ({
6766
6980
  el.scrollIntoView({ behavior: "auto", block: "start" });
6767
6981
  }
6768
6982
  }, []);
6769
- const renderMonth = useCallback3(
6983
+ const renderMonth = useCallback4(
6770
6984
  (month) => {
6771
6985
  const firstDay = startOfMonth(month);
6772
6986
  const totalDays = getDaysInMonth(month);
@@ -6865,9 +7079,9 @@ var DatePicker = ({
6865
7079
  const [open, setOpen] = useState5(false);
6866
7080
  const [inputValue, setInputValue] = useState5("");
6867
7081
  const [draftDate, setDraftDate] = useState5(void 0);
6868
- const dateInputRef = useRef4(null);
6869
- const segIdxRef = useRef4(0);
6870
- const charPosRef = useRef4(0);
7082
+ const dateInputRef = useRef5(null);
7083
+ const segIdxRef = useRef5(0);
7084
+ const charPosRef = useRef5(0);
6871
7085
  const selectedDate = (() => {
6872
7086
  if (!value) return void 0;
6873
7087
  const d = /* @__PURE__ */ new Date(value + "T00:00:00Z");
@@ -6887,7 +7101,7 @@ var DatePicker = ({
6887
7101
  setDraftDate(void 0);
6888
7102
  }
6889
7103
  }, [value]);
6890
- const selectSegByIdx = useCallback4((idx) => {
7104
+ const selectSegByIdx = useCallback5((idx) => {
6891
7105
  if (!dateInputRef.current) return;
6892
7106
  const seg = segments[idx] ?? segments[0];
6893
7107
  dateInputRef.current.setSelectionRange(seg.start, seg.end);
@@ -6920,18 +7134,18 @@ var DatePicker = ({
6920
7134
  selectSegByIdx(segIdxRef.current);
6921
7135
  }, 0);
6922
7136
  };
6923
- const handleShiftButtonMouseDown = useCallback4(
7137
+ const handleShiftButtonMouseDown = useCallback5(
6924
7138
  (e) => {
6925
7139
  e.preventDefault();
6926
7140
  },
6927
7141
  []
6928
7142
  );
6929
- const updateFromDate = useCallback4((newDate) => {
7143
+ const updateFromDate = useCallback5((newDate) => {
6930
7144
  if (!isValid(newDate)) return;
6931
7145
  setInputValue(formatUTCDate(newDate, "dd.MM.yy"));
6932
7146
  setDraftDate(newDate);
6933
7147
  }, []);
6934
- const commitDate = useCallback4((dateToCommit) => {
7148
+ const commitDate = useCallback5((dateToCommit) => {
6935
7149
  const nextDate = dateToCommit ?? draftDate ?? selectedDate;
6936
7150
  if (!nextDate || !isValid(nextDate)) return;
6937
7151
  const iso = [
@@ -6942,7 +7156,7 @@ var DatePicker = ({
6942
7156
  if (iso === value) return;
6943
7157
  onChange?.(iso);
6944
7158
  }, [draftDate, onChange, selectedDate, value]);
6945
- const handleCalendarSelect = useCallback4(
7159
+ const handleCalendarSelect = useCallback5(
6946
7160
  (day) => {
6947
7161
  const normalizedDay = businessDays && isWeekend3 && isWeekend3(day) ? snapToBusinessDay(day, 1, isWeekend3) : day;
6948
7162
  updateFromDate(normalizedDay);
@@ -6951,7 +7165,7 @@ var DatePicker = ({
6951
7165
  },
6952
7166
  [businessDays, commitDate, isWeekend3, updateFromDate]
6953
7167
  );
6954
- const handleDayShift = useCallback4(
7168
+ const handleDayShift = useCallback5(
6955
7169
  (delta) => {
6956
7170
  const base = activeDate ?? /* @__PURE__ */ new Date();
6957
7171
  if (businessDays && isWeekend3) {
@@ -6962,7 +7176,7 @@ var DatePicker = ({
6962
7176
  },
6963
7177
  [activeDate, updateFromDate, businessDays, isWeekend3]
6964
7178
  );
6965
- const handleTriggerKeyDown = useCallback4((e) => {
7179
+ const handleTriggerKeyDown = useCallback5((e) => {
6966
7180
  if (disabled) return;
6967
7181
  if (e.key === "ArrowUp") {
6968
7182
  e.preventDefault();
@@ -6976,7 +7190,7 @@ var DatePicker = ({
6976
7190
  handleDayShift(-1);
6977
7191
  }
6978
7192
  }, [disabled, handleDayShift]);
6979
- const handleKeyDown = useCallback4((e) => {
7193
+ const handleKeyDown = useCallback5((e) => {
6980
7194
  if (!dateInputRef.current) return;
6981
7195
  const { value: inputVal } = dateInputRef.current;
6982
7196
  const segIdx = segIdxRef.current;
@@ -7077,7 +7291,7 @@ var DatePicker = ({
7077
7291
  }
7078
7292
  }
7079
7293
  }, [activeDate, businessDays, commitDate, isWeekend3, selectSegByIdx, updateFromDate]);
7080
- const handleOpenChange = useCallback4((nextOpen) => {
7294
+ const handleOpenChange = useCallback5((nextOpen) => {
7081
7295
  if (!nextOpen && open) {
7082
7296
  commitDate();
7083
7297
  }
@@ -7513,7 +7727,7 @@ var DepChip = ({
7513
7727
  onChipSelect?.(null);
7514
7728
  }
7515
7729
  };
7516
- const handleOpenChange = useCallback5(
7730
+ const handleOpenChange = useCallback6(
7517
7731
  (open) => {
7518
7732
  setPopoverOpen(open);
7519
7733
  },
@@ -7525,7 +7739,7 @@ var DepChip = ({
7525
7739
  onChipSelectClear();
7526
7740
  setPopoverOpen(false);
7527
7741
  };
7528
- const handleLagChange = useCallback5(
7742
+ const handleLagChange = useCallback6(
7529
7743
  (newLag) => {
7530
7744
  if (!onTasksChange || !allTasks) return;
7531
7745
  const taskById = new Map(allTasks.map((t) => [t.id, t]));
@@ -7585,7 +7799,7 @@ var DepChip = ({
7585
7799
  },
7586
7800
  [dep, task, allTasks, onTasksChange, businessDays, weekendPredicate]
7587
7801
  );
7588
- const handleInputCommit = useCallback5(
7802
+ const handleInputCommit = useCallback6(
7589
7803
  (raw) => {
7590
7804
  if (raw === "") {
7591
7805
  handleLagChange(0);
@@ -7901,7 +8115,7 @@ var TaskListRow = React11.memo(
7901
8115
  })
7902
8116
  );
7903
8117
  }, [resolvedColumns]);
7904
- const getColumnStyle = useCallback5((columnId, fallbackWidth) => {
8118
+ const getColumnStyle = useCallback6((columnId, fallbackWidth) => {
7905
8119
  return columnWidthStyleMap.get(columnId) ?? {
7906
8120
  width: fallbackWidth,
7907
8121
  minWidth: fallbackWidth,
@@ -7912,26 +8126,26 @@ var TaskListRow = React11.memo(
7912
8126
  const normalizedTask = useMemo9(() => normalizeTaskDatesForType(task), [task]);
7913
8127
  const isMilestone = useMemo9(() => isMilestoneTask(normalizedTask), [normalizedTask]);
7914
8128
  const [nameValue, setNameValue] = useState6("");
7915
- const nameInputRef = useRef5(null);
8129
+ const nameInputRef = useRef6(null);
7916
8130
  const [durationValue, setDurationValue] = useState6(
7917
8131
  () => getInclusiveDurationDays(normalizedTask.startDate, normalizedTask.endDate)
7918
8132
  );
7919
- const durationInputRef = useRef5(null);
7920
- const dependencySearchInputRef = useRef5(null);
7921
- const dependencySearchListRef = useRef5(null);
8133
+ const durationInputRef = useRef6(null);
8134
+ const dependencySearchInputRef = useRef6(null);
8135
+ const dependencySearchListRef = useRef6(null);
7922
8136
  const [progressValue, setProgressValue] = useState6(0);
7923
- const progressInputRef = useRef5(null);
8137
+ const progressInputRef = useRef6(null);
7924
8138
  const [overflowOpen, setOverflowOpen] = useState6(false);
7925
8139
  const [contextMenuOpen, setContextMenuOpen] = useState6(false);
7926
8140
  const [colorMenuOpen, setColorMenuOpen] = useState6(false);
7927
- const nameConfirmedRef = useRef5(false);
7928
- const durationConfirmedRef = useRef5(false);
7929
- const progressConfirmedRef = useRef5(false);
7930
- const autoEditedForRef = useRef5(null);
7931
- const editTriggerRef = useRef5(
8141
+ const nameConfirmedRef = useRef6(false);
8142
+ const durationConfirmedRef = useRef6(false);
8143
+ const progressConfirmedRef = useRef6(false);
8144
+ const autoEditedForRef = useRef6(null);
8145
+ const editTriggerRef = useRef6(
7932
8146
  "doubleclick"
7933
8147
  );
7934
- const rowRef = useRef5(null);
8148
+ const rowRef = useRef6(null);
7935
8149
  const isSelected = selectedTaskId === task.id;
7936
8150
  const isParent = useMemo9(
7937
8151
  () => isTaskParent(task.id, allTasks),
@@ -7945,13 +8159,13 @@ var TaskListRow = React11.memo(
7945
8159
  () => createCustomDayPredicate({ customDays, isWeekend: isWeekend3 }),
7946
8160
  [customDays, isWeekend3]
7947
8161
  );
7948
- const getDuration = useCallback5(
8162
+ const getDuration = useCallback6(
7949
8163
  (start, end) => {
7950
8164
  return businessDays ? getBusinessDaysCount(start, end, weekendPredicate) : getInclusiveDurationDays(start, end);
7951
8165
  },
7952
8166
  [businessDays, weekendPredicate]
7953
8167
  );
7954
- const getEndDate = useCallback5(
8168
+ const getEndDate = useCallback6(
7955
8169
  (start, duration) => {
7956
8170
  return businessDays ? addBusinessDays(start, duration, weekendPredicate).toISOString().split("T")[0] : getEndDateFromDuration(start, duration);
7957
8171
  },
@@ -7961,7 +8175,7 @@ var TaskListRow = React11.memo(
7961
8175
  const [compositeIconMode, setCompositeIconMode] = useState6(
7962
8176
  () => isCollapsed ? "composite" : "down"
7963
8177
  );
7964
- const compositeIconModeRef = useRef5(compositeIconMode);
8178
+ const compositeIconModeRef = useRef6(compositeIconMode);
7965
8179
  const [compositeIconAnimation, setCompositeIconAnimation] = useState6(null);
7966
8180
  const [compositeIconAnimationPhase, setCompositeIconAnimationPhase] = useState6(null);
7967
8181
  useEffect6(() => {
@@ -7987,7 +8201,7 @@ var TaskListRow = React11.memo(
7987
8201
  window.clearTimeout(finishTimeoutId);
7988
8202
  };
7989
8203
  }, [isCollapsed]);
7990
- const getHierarchyLineColor = useCallback5((columnDepth) => {
8204
+ const getHierarchyLineColor = useCallback6((columnDepth) => {
7991
8205
  return columnDepth % 2 === 0 ? "#93c5fd" : "var(--gantt-hierarchy-line-color)";
7992
8206
  }, []);
7993
8207
  const isPicking = selectingPredecessorFor != null;
@@ -8085,7 +8299,7 @@ var TaskListRow = React11.memo(
8085
8299
  setEditingColumnId("name");
8086
8300
  }
8087
8301
  }, [editingTaskId, task.id, disableTaskNameEditing]);
8088
- const handleNameClick = useCallback5(
8302
+ const handleNameClick = useCallback6(
8089
8303
  (e) => {
8090
8304
  e.stopPropagation();
8091
8305
  onRowClick?.(task.id);
@@ -8093,7 +8307,7 @@ var TaskListRow = React11.memo(
8093
8307
  },
8094
8308
  [task.id, onRowClick, onScrollToTask]
8095
8309
  );
8096
- const handleNameDoubleClick = useCallback5(
8310
+ const handleNameDoubleClick = useCallback6(
8097
8311
  (e) => {
8098
8312
  if (task.composite) return;
8099
8313
  if (disableTaskNameEditing) return;
@@ -8105,7 +8319,7 @@ var TaskListRow = React11.memo(
8105
8319
  },
8106
8320
  [task.name, task.composite, disableTaskNameEditing]
8107
8321
  );
8108
- const handleRowKeyDown = useCallback5(
8322
+ const handleRowKeyDown = useCallback6(
8109
8323
  (e) => {
8110
8324
  if (editingProgress) return;
8111
8325
  if (!editingName && !disableTaskNameEditing && e.key === "F2") {
@@ -8119,7 +8333,7 @@ var TaskListRow = React11.memo(
8119
8333
  },
8120
8334
  [editingName, disableTaskNameEditing, task.name]
8121
8335
  );
8122
- const handleNameSave = useCallback5(() => {
8336
+ const handleNameSave = useCallback6(() => {
8123
8337
  if (nameConfirmedRef.current) {
8124
8338
  nameConfirmedRef.current = false;
8125
8339
  return;
@@ -8129,10 +8343,10 @@ var TaskListRow = React11.memo(
8129
8343
  }
8130
8344
  setEditingColumnId(null);
8131
8345
  }, [nameValue, task, onTasksChange]);
8132
- const handleNameCancel = useCallback5(() => {
8346
+ const handleNameCancel = useCallback6(() => {
8133
8347
  setEditingColumnId(null);
8134
8348
  }, []);
8135
- const handleNameKeyDown = useCallback5(
8349
+ const handleNameKeyDown = useCallback6(
8136
8350
  (e) => {
8137
8351
  if (e.key === "Enter") {
8138
8352
  nameConfirmedRef.current = true;
@@ -8146,7 +8360,7 @@ var TaskListRow = React11.memo(
8146
8360
  },
8147
8361
  [nameValue, task, onTasksChange, handleNameCancel]
8148
8362
  );
8149
- const handleDurationClick = useCallback5(
8363
+ const handleDurationClick = useCallback6(
8150
8364
  (e) => {
8151
8365
  if (task.locked) return;
8152
8366
  e.stopPropagation();
@@ -8158,11 +8372,11 @@ var TaskListRow = React11.memo(
8158
8372
  },
8159
8373
  [task.locked, normalizedTask.startDate, normalizedTask.endDate, getDuration, isMilestone]
8160
8374
  );
8161
- const applyDurationChange = useCallback5((nextDuration) => {
8375
+ const applyDurationChange = useCallback6((nextDuration) => {
8162
8376
  const normalizedDuration = Math.max(0, Math.round(nextDuration) || 0);
8163
8377
  setDurationValue(normalizedDuration);
8164
8378
  }, []);
8165
- const emitDurationChange = useCallback5((rounded) => {
8379
+ const emitDurationChange = useCallback6((rounded) => {
8166
8380
  if (onDurationChange) {
8167
8381
  onDurationChange(
8168
8382
  isMilestone && rounded > 0 ? { ...task, type: "task" } : !isMilestone && rounded === 0 ? { ...task, type: "milestone", endDate: task.startDate } : task,
@@ -8184,7 +8398,7 @@ var TaskListRow = React11.memo(
8184
8398
  ]);
8185
8399
  }
8186
8400
  }, [getEndDate, isMilestone, onDurationChange, onTasksChange, task]);
8187
- const handleDurationSave = useCallback5(() => {
8401
+ const handleDurationSave = useCallback6(() => {
8188
8402
  if (durationConfirmedRef.current) {
8189
8403
  durationConfirmedRef.current = false;
8190
8404
  return;
@@ -8193,17 +8407,17 @@ var TaskListRow = React11.memo(
8193
8407
  emitDurationChange(rounded);
8194
8408
  setEditingColumnId(null);
8195
8409
  }, [durationValue, emitDurationChange]);
8196
- const handleDurationCancel = useCallback5(() => {
8410
+ const handleDurationCancel = useCallback6(() => {
8197
8411
  setDurationValue(isMilestone ? 0 : getDuration(normalizedTask.startDate, normalizedTask.endDate));
8198
8412
  setEditingColumnId(null);
8199
8413
  }, [normalizedTask.startDate, normalizedTask.endDate, getDuration, isMilestone]);
8200
- const handleDurationAdjust = useCallback5(
8414
+ const handleDurationAdjust = useCallback6(
8201
8415
  (delta) => {
8202
8416
  applyDurationChange(durationValue + delta);
8203
8417
  },
8204
8418
  [applyDurationChange, durationValue]
8205
8419
  );
8206
- const handleDurationKeyDown = useCallback5(
8420
+ const handleDurationKeyDown = useCallback6(
8207
8421
  (e) => {
8208
8422
  e.stopPropagation();
8209
8423
  if (e.key === "Enter") {
@@ -8217,7 +8431,7 @@ var TaskListRow = React11.memo(
8217
8431
  },
8218
8432
  [durationValue, emitDurationChange, handleDurationCancel]
8219
8433
  );
8220
- const handleProgressClick = useCallback5(
8434
+ const handleProgressClick = useCallback6(
8221
8435
  (e) => {
8222
8436
  if (task.locked) return;
8223
8437
  e.stopPropagation();
@@ -8227,7 +8441,7 @@ var TaskListRow = React11.memo(
8227
8441
  },
8228
8442
  [task.progress, task.locked]
8229
8443
  );
8230
- const handleProgressSave = useCallback5(() => {
8444
+ const handleProgressSave = useCallback6(() => {
8231
8445
  if (progressConfirmedRef.current) {
8232
8446
  progressConfirmedRef.current = false;
8233
8447
  return;
@@ -8236,15 +8450,15 @@ var TaskListRow = React11.memo(
8236
8450
  onTasksChange?.(cascadeTaskProgress({ ...task, progress: clampedValue }, allTasks));
8237
8451
  setEditingColumnId(null);
8238
8452
  }, [progressValue, task, onTasksChange, allTasks]);
8239
- const handleProgressCancel = useCallback5(() => {
8453
+ const handleProgressCancel = useCallback6(() => {
8240
8454
  setEditingColumnId(null);
8241
8455
  }, []);
8242
- const handleProgressAdjust = useCallback5((delta) => {
8456
+ const handleProgressAdjust = useCallback6((delta) => {
8243
8457
  setProgressValue(
8244
8458
  (current) => Math.max(0, Math.min(100, current + delta))
8245
8459
  );
8246
8460
  }, []);
8247
- const handleProgressKeyDown = useCallback5(
8461
+ const handleProgressKeyDown = useCallback6(
8248
8462
  (e) => {
8249
8463
  e.stopPropagation();
8250
8464
  if (e.key === "Enter") {
@@ -8273,7 +8487,7 @@ var TaskListRow = React11.memo(
8273
8487
  durationInputRef.current.select();
8274
8488
  }
8275
8489
  }, [editingDuration]);
8276
- const emitMilestoneDateChange = useCallback5((nextDateISO) => {
8490
+ const emitMilestoneDateChange = useCallback6((nextDateISO) => {
8277
8491
  const alignedDate = businessDays ? alignToWorkingDay(/* @__PURE__ */ new Date(`${nextDateISO}T00:00:00.000Z`), 1, weekendPredicate) : /* @__PURE__ */ new Date(`${nextDateISO}T00:00:00.000Z`);
8278
8492
  const clampedRange = clampTaskRangeForIncomingFS(
8279
8493
  task,
@@ -8306,7 +8520,7 @@ var TaskListRow = React11.memo(
8306
8520
  }
8307
8521
  ]);
8308
8522
  }, [task, onTasksChange, allTasks, businessDays, weekendPredicate]);
8309
- const handleStartDateChange = useCallback5(
8523
+ const handleStartDateChange = useCallback6(
8310
8524
  (newDateISO) => {
8311
8525
  if (!newDateISO) return;
8312
8526
  if (isMilestone) {
@@ -8359,7 +8573,7 @@ var TaskListRow = React11.memo(
8359
8573
  },
8360
8574
  [task, onTasksChange, businessDays, getDuration, allTasks, weekendPredicate, isMilestone, emitMilestoneDateChange, taskDateChangeMode]
8361
8575
  );
8362
- const handleEndDateChange = useCallback5(
8576
+ const handleEndDateChange = useCallback6(
8363
8577
  (newDateISO) => {
8364
8578
  if (!newDateISO) return;
8365
8579
  if (isMilestone) {
@@ -8423,41 +8637,41 @@ var TaskListRow = React11.memo(
8423
8637
  ),
8424
8638
  /* @__PURE__ */ jsx15("span", { children: "\u0421\u043E\u0445\u0440\u0430\u043D\u044F\u0442\u044C \u0434\u043B\u0438\u0442\u0435\u043B\u044C\u043D\u043E\u0441\u0442\u044C" })
8425
8639
  ] }) : null;
8426
- const handleRowClickInternal = useCallback5(() => {
8640
+ const handleRowClickInternal = useCallback6(() => {
8427
8641
  onRowClick?.(task.id);
8428
8642
  }, [task.id, onRowClick]);
8429
- const handleNumberClick = useCallback5(
8643
+ const handleNumberClick = useCallback6(
8430
8644
  (e) => {
8431
8645
  e.stopPropagation();
8432
8646
  onRowClick?.(task.id);
8433
8647
  },
8434
8648
  [task.id, onRowClick]
8435
8649
  );
8436
- const handleToggleCollapse = useCallback5(
8650
+ const handleToggleCollapse = useCallback6(
8437
8651
  (e) => {
8438
8652
  e.stopPropagation();
8439
8653
  onToggleCollapse?.(task.id);
8440
8654
  },
8441
8655
  [task.id, onToggleCollapse]
8442
8656
  );
8443
- const handlePromote = useCallback5(
8657
+ const handlePromote = useCallback6(
8444
8658
  (e) => {
8445
8659
  e.stopPropagation();
8446
8660
  onPromoteTask?.(task.id);
8447
8661
  },
8448
8662
  [task.id, onPromoteTask]
8449
8663
  );
8450
- const handleDemote = useCallback5(
8664
+ const handleDemote = useCallback6(
8451
8665
  (e) => {
8452
8666
  e.stopPropagation();
8453
8667
  onDemoteTask?.(task.id, "");
8454
8668
  },
8455
8669
  [task.id, onDemoteTask]
8456
8670
  );
8457
- const closeColorMenu = useCallback5(() => {
8671
+ const closeColorMenu = useCallback6(() => {
8458
8672
  setColorMenuOpen(false);
8459
8673
  }, []);
8460
- const handleApplyColor = useCallback5(
8674
+ const handleApplyColor = useCallback6(
8461
8675
  (color) => {
8462
8676
  if (!onTasksChange) return;
8463
8677
  const descendantIds = new Set(
@@ -8473,7 +8687,7 @@ var TaskListRow = React11.memo(
8473
8687
  },
8474
8688
  [allTasks, closeColorMenu, isParent, onTasksChange, task]
8475
8689
  );
8476
- const handleUngroup = useCallback5(
8690
+ const handleUngroup = useCallback6(
8477
8691
  (e) => {
8478
8692
  e.stopPropagation();
8479
8693
  setContextMenuOpen(false);
@@ -8494,7 +8708,7 @@ var TaskListRow = React11.memo(
8494
8708
  [taskListMenuCommands, task, isParent, isMilestoneRow]
8495
8709
  );
8496
8710
  const hasContextMenu = !hideTaskListRowActions && (visibleCustomMenuCommands.length > 0 || !!onDuplicateTask || !!onDelete || !!onTasksChange || isParent && !!onUngroupTask);
8497
- const handleCustomMenuCommandClick = useCallback5(
8711
+ const handleCustomMenuCommandClick = useCallback6(
8498
8712
  (command) => (e) => {
8499
8713
  e.stopPropagation();
8500
8714
  if (command.closeOnSelect !== false) {
@@ -8505,14 +8719,14 @@ var TaskListRow = React11.memo(
8505
8719
  },
8506
8720
  [closeColorMenu, task]
8507
8721
  );
8508
- const handleAddClick = useCallback5(
8722
+ const handleAddClick = useCallback6(
8509
8723
  (e) => {
8510
8724
  e.stopPropagation();
8511
8725
  onSetSelectingPredecessorFor?.(task.id);
8512
8726
  },
8513
8727
  [task.id, onSetSelectingPredecessorFor]
8514
8728
  );
8515
- const handlePredecessorPick = useCallback5(
8729
+ const handlePredecessorPick = useCallback6(
8516
8730
  (e) => {
8517
8731
  e.stopPropagation();
8518
8732
  if (!isPicking || isSourceRow) return;
@@ -8533,14 +8747,14 @@ var TaskListRow = React11.memo(
8533
8747
  onAddDependency
8534
8748
  ]
8535
8749
  );
8536
- const handleCancelPicking = useCallback5(
8750
+ const handleCancelPicking = useCallback6(
8537
8751
  (e) => {
8538
8752
  e.stopPropagation();
8539
8753
  onSetSelectingPredecessorFor?.(null);
8540
8754
  },
8541
8755
  [onSetSelectingPredecessorFor]
8542
8756
  );
8543
- const handleSourceCellClick = useCallback5(
8757
+ const handleSourceCellClick = useCallback6(
8544
8758
  (e) => {
8545
8759
  if (e.target === e.currentTarget) {
8546
8760
  handleCancelPicking(e);
@@ -8548,7 +8762,7 @@ var TaskListRow = React11.memo(
8548
8762
  },
8549
8763
  [handleCancelPicking]
8550
8764
  );
8551
- const handleSearchPick = useCallback5(
8765
+ const handleSearchPick = useCallback6(
8552
8766
  (pickedTaskId) => {
8553
8767
  if (!activeLinkType) return;
8554
8768
  if (dependencyPickMode === "predecessor") {
@@ -8559,7 +8773,7 @@ var TaskListRow = React11.memo(
8559
8773
  },
8560
8774
  [activeLinkType, dependencyPickMode, onAddDependency, task.id]
8561
8775
  );
8562
- const handleSearchRemove = useCallback5(
8776
+ const handleSearchRemove = useCallback6(
8563
8777
  (pickedTaskId) => {
8564
8778
  const matchingTypes = dependencyPickMode === "predecessor" ? (task.dependencies ?? []).filter((dep) => dep.taskId === pickedTaskId).map((dep) => dep.type) : (allTasks.find((candidate) => candidate.id === pickedTaskId)?.dependencies ?? []).filter((dep) => dep.taskId === task.id).map((dep) => dep.type);
8565
8779
  for (const linkType of matchingTypes) {
@@ -9526,7 +9740,7 @@ var TaskListRow = React11.memo(
9526
9740
  progress: progressCell,
9527
9741
  dependencies: dependenciesCell
9528
9742
  };
9529
- const focusCustomCell = useCallback5((taskId, columnId) => {
9743
+ const focusCustomCell = useCallback6((taskId, columnId) => {
9530
9744
  const overlay = rowRef.current?.closest(".gantt-tl-overlay");
9531
9745
  if (!overlay) {
9532
9746
  return;
@@ -9535,7 +9749,7 @@ var TaskListRow = React11.memo(
9535
9749
  const nextCell = overlay.querySelector(selector);
9536
9750
  nextCell?.focus();
9537
9751
  }, []);
9538
- const moveActiveCustomCell = useCallback5((columnId, direction) => {
9752
+ const moveActiveCustomCell = useCallback6((columnId, direction) => {
9539
9753
  const overlay = rowRef.current?.closest(".gantt-tl-overlay");
9540
9754
  if (!overlay || !resolvedColumns) {
9541
9755
  return;
@@ -9739,7 +9953,7 @@ var TaskListRow = React11.memo(
9739
9953
  TaskListRow.displayName = "TaskListRow";
9740
9954
 
9741
9955
  // src/components/TaskList/NewTaskRow.tsx
9742
- import { useState as useState7, useRef as useRef6, useEffect as useEffect7 } from "react";
9956
+ import { useState as useState7, useRef as useRef7, useEffect as useEffect7 } from "react";
9743
9957
  import { jsx as jsx16, jsxs as jsxs11 } from "react/jsx-runtime";
9744
9958
  var NewTaskRow = ({
9745
9959
  rowHeight,
@@ -9748,8 +9962,8 @@ var NewTaskRow = ({
9748
9962
  nestingDepth = 0
9749
9963
  }) => {
9750
9964
  const [nameValue, setNameValue] = useState7("");
9751
- const inputRef = useRef6(null);
9752
- const confirmedRef = useRef6(false);
9965
+ const inputRef = useRef7(null);
9966
+ const confirmedRef = useRef7(false);
9753
9967
  const inputInnerPadding = 4;
9754
9968
  const levelOffset = nestingDepth > 0 ? nestingDepth * 20 + 8 : 0;
9755
9969
  useEffect7(() => {
@@ -9805,7 +10019,7 @@ var NewTaskRow = ({
9805
10019
  };
9806
10020
 
9807
10021
  // src/components/GenerationSkeleton/GenerationSkeleton.tsx
9808
- import { useRef as useRef7 } from "react";
10022
+ import { useRef as useRef8 } from "react";
9809
10023
  import { Fragment as Fragment5, jsx as jsx17 } from "react/jsx-runtime";
9810
10024
  var MAX_SKELETON_ROWS = 200;
9811
10025
  var SHIMMER_DURATION_MS = 1450;
@@ -9830,8 +10044,8 @@ var GenerationSkeletonRows = ({
9830
10044
  chartStartJitterDays = 0
9831
10045
  }) => {
9832
10046
  const safeCount = clampCount(count);
9833
- const previousCountRef = useRef7(null);
9834
- const shimmerDelayRef = useRef7("0ms");
10047
+ const previousCountRef = useRef8(null);
10048
+ const shimmerDelayRef = useRef8("0ms");
9835
10049
  if (previousCountRef.current !== safeCount) {
9836
10050
  previousCountRef.current = safeCount;
9837
10051
  shimmerDelayRef.current = `-${Date.now() % SHIMMER_DURATION_MS}ms`;
@@ -10102,7 +10316,7 @@ var SelectAllCheckbox = ({
10102
10316
  indeterminate,
10103
10317
  onChange
10104
10318
  }) => {
10105
- const ref = useRef8(null);
10319
+ const ref = useRef9(null);
10106
10320
  useEffect8(() => {
10107
10321
  if (ref.current) {
10108
10322
  ref.current.indeterminate = indeterminate;
@@ -10188,8 +10402,8 @@ var TaskList = ({
10188
10402
  const [activeCustomCell, setActiveCustomCell] = useState8(null);
10189
10403
  const [columnWidthOverrides, setColumnWidthOverrides] = useState8(() => normalizeColumnWidthMap(taskListColumnWidths));
10190
10404
  const [isColumnResizeMode, setIsColumnResizeMode] = useState8(false);
10191
- const columnResizeHeaderRef = useRef8(null);
10192
- const resizeStateRef = useRef8(null);
10405
+ const columnResizeHeaderRef = useRef9(null);
10406
+ const resizeStateRef = useRef9(null);
10193
10407
  const effectiveSelectedTaskIds = selectedTaskIds ?? internalSelectedTaskIds;
10194
10408
  useEffect8(() => {
10195
10409
  if (!isColumnResizeMode) {
@@ -10207,7 +10421,7 @@ var TaskList = ({
10207
10421
  document.removeEventListener("pointerdown", handleOutsidePointerDown);
10208
10422
  };
10209
10423
  }, [isColumnResizeMode]);
10210
- const emitSelectedTaskIdsChange = useCallback6((nextSelectedTaskIds) => {
10424
+ const emitSelectedTaskIdsChange = useCallback7((nextSelectedTaskIds) => {
10211
10425
  if (!selectedTaskIds) {
10212
10426
  setInternalSelectedTaskIds(nextSelectedTaskIds);
10213
10427
  }
@@ -10215,7 +10429,7 @@ var TaskList = ({
10215
10429
  }, [onSelectedTaskIdsChange, selectedTaskIds]);
10216
10430
  const [internalCollapsedParentIds, setInternalCollapsedParentIds] = useState8(/* @__PURE__ */ new Set());
10217
10431
  const collapsedParentIds = externalCollapsedParentIds ?? internalCollapsedParentIds;
10218
- const handleToggleCollapse = externalOnToggleCollapse ?? useCallback6((parentId) => {
10432
+ const handleToggleCollapse = externalOnToggleCollapse ?? useCallback7((parentId) => {
10219
10433
  setInternalCollapsedParentIds((prev) => {
10220
10434
  const next = new Set(prev);
10221
10435
  if (next.has(parentId)) {
@@ -10286,7 +10500,7 @@ var TaskList = ({
10286
10500
  );
10287
10501
  const areAllVisibleTasksSelected = visibleTaskIds.length > 0 && selectedVisibleTaskCount === visibleTaskIds.length;
10288
10502
  const areSomeVisibleTasksSelected = selectedVisibleTaskCount > 0 && !areAllVisibleTasksSelected;
10289
- const handleToggleTaskSelection = useCallback6((taskId, checked) => {
10503
+ const handleToggleTaskSelection = useCallback7((taskId, checked) => {
10290
10504
  const nextSelectedTaskIds = new Set(effectiveSelectedTaskIds);
10291
10505
  if (checked) {
10292
10506
  nextSelectedTaskIds.add(taskId);
@@ -10295,7 +10509,7 @@ var TaskList = ({
10295
10509
  }
10296
10510
  emitSelectedTaskIdsChange(nextSelectedTaskIds);
10297
10511
  }, [effectiveSelectedTaskIds, emitSelectedTaskIdsChange]);
10298
- const handleToggleAllVisibleTaskSelection = useCallback6((checked) => {
10512
+ const handleToggleAllVisibleTaskSelection = useCallback7((checked) => {
10299
10513
  const nextSelectedTaskIds = new Set(effectiveSelectedTaskIds);
10300
10514
  for (const taskId of visibleTaskIds) {
10301
10515
  if (checked) {
@@ -10376,7 +10590,7 @@ var TaskList = ({
10376
10590
  }
10377
10591
  return map;
10378
10592
  }, [tasks, visibleTasks]);
10379
- const handleRowClick = useCallback6((taskId) => {
10593
+ const handleRowClick = useCallback7((taskId) => {
10380
10594
  onTaskSelect?.(taskId);
10381
10595
  }, [onTaskSelect]);
10382
10596
  const [activeLinkType, setActiveLinkType] = useState8("FS");
@@ -10384,14 +10598,14 @@ var TaskList = ({
10384
10598
  const [dependencyPickMode, setDependencyPickMode] = useState8("successor");
10385
10599
  const [typeMenuOpen, setTypeMenuOpen] = useState8(false);
10386
10600
  const [dependencyError, setDependencyError] = useState8(null);
10387
- const overlayRef = useRef8(null);
10601
+ const overlayRef = useRef9(null);
10388
10602
  const [selectedChip, setSelectedChip] = useState8(controlledSelectedChip ? { ...controlledSelectedChip, linkType: controlledSelectedChip.linkType } : null);
10389
10603
  useEffect8(() => {
10390
10604
  if (controlledSelectedChip !== void 0) {
10391
10605
  setSelectedChip(controlledSelectedChip ? { ...controlledSelectedChip, linkType: controlledSelectedChip.linkType } : null);
10392
10606
  }
10393
10607
  }, [controlledSelectedChip]);
10394
- const handleChipSelect = useCallback6((chip) => {
10608
+ const handleChipSelect = useCallback7((chip) => {
10395
10609
  setSelectedChip(chip);
10396
10610
  onSelectedChipChange?.(chip);
10397
10611
  }, [onSelectedChipChange]);
@@ -10490,7 +10704,7 @@ var TaskList = ({
10490
10704
  document.removeEventListener("mouseup", handleCanvasMouseUp, true);
10491
10705
  };
10492
10706
  }, [selectingPredecessorFor, selectedChip, selectedTaskId, activeCustomCell, onTaskSelect, onSelectedChipChange]);
10493
- const handleAddDependency = useCallback6((successorTaskId, predecessorTaskId, linkType) => {
10707
+ const handleAddDependency = useCallback7((successorTaskId, predecessorTaskId, linkType) => {
10494
10708
  if (successorTaskId === predecessorTaskId) return;
10495
10709
  if (areTasksHierarchicallyRelated(successorTaskId, predecessorTaskId, tasks)) {
10496
10710
  setDependencyError("\u0421\u0432\u044F\u0437\u0438 \u043C\u0435\u0436\u0434\u0443 \u0440\u043E\u0434\u0438\u0442\u0435\u043B\u0435\u043C \u0438 \u043F\u043E\u0442\u043E\u043C\u043A\u043E\u043C \u0437\u0430\u043F\u0440\u0435\u0449\u0435\u043D\u044B");
@@ -10569,7 +10783,7 @@ var TaskList = ({
10569
10783
  }
10570
10784
  setSelectingPredecessorFor(null);
10571
10785
  }, [tasks, onTasksChange]);
10572
- const handleRemoveDependency = useCallback6((taskId, predecessorTaskId, linkType) => {
10786
+ const handleRemoveDependency = useCallback7((taskId, predecessorTaskId, linkType) => {
10573
10787
  const task = tasks.find((t) => t.id === taskId);
10574
10788
  if (!task) return;
10575
10789
  const updatedDeps = (task.dependencies ?? []).filter(
@@ -10582,16 +10796,16 @@ var TaskList = ({
10582
10796
  const [draggingIndex, setDraggingIndex] = useState8(null);
10583
10797
  const [dragOverTarget, setDragOverTarget] = useState8(null);
10584
10798
  const [isBeforeFirstDropZoneActive, setIsBeforeFirstDropZoneActive] = useState8(false);
10585
- const dragOriginIndexRef = useRef8(null);
10586
- const dragTaskIdRef = useRef8(null);
10587
- const clearDragState = useCallback6(() => {
10799
+ const dragOriginIndexRef = useRef9(null);
10800
+ const dragTaskIdRef = useRef9(null);
10801
+ const clearDragState = useCallback7(() => {
10588
10802
  setDraggingIndex(null);
10589
10803
  setDragOverTarget(null);
10590
10804
  setIsBeforeFirstDropZoneActive(false);
10591
10805
  dragOriginIndexRef.current = null;
10592
10806
  dragTaskIdRef.current = null;
10593
10807
  }, []);
10594
- const isValidParentDrop = useCallback6((draggedTaskId, dropIndex) => {
10808
+ const isValidParentDrop = useCallback7((draggedTaskId, dropIndex) => {
10595
10809
  if (!isTaskParent(draggedTaskId, tasks)) {
10596
10810
  return true;
10597
10811
  }
@@ -10609,13 +10823,13 @@ var TaskList = ({
10609
10823
  }
10610
10824
  return true;
10611
10825
  }, [tasks, visibleTasks, orderedTasks]);
10612
- const handleDragStart = useCallback6((index, e) => {
10826
+ const handleDragStart = useCallback7((index, e) => {
10613
10827
  e.dataTransfer.effectAllowed = "move";
10614
10828
  setDraggingIndex(index);
10615
10829
  dragOriginIndexRef.current = index;
10616
10830
  dragTaskIdRef.current = visibleTasks[index]?.id ?? null;
10617
10831
  }, [visibleTasks]);
10618
- const normalizeDropTarget = useCallback6((movedTaskId, target) => {
10832
+ const normalizeDropTarget = useCallback7((movedTaskId, target) => {
10619
10833
  if (target.placement !== "before" || target.index <= 0 || target.index >= visibleTasks.length) {
10620
10834
  return target;
10621
10835
  }
@@ -10638,7 +10852,7 @@ var TaskList = ({
10638
10852
  }
10639
10853
  return target;
10640
10854
  }, [orderedTasks, visibleTasks]);
10641
- const handleDragOver = useCallback6((index, e, forcedPlacement) => {
10855
+ const handleDragOver = useCallback7((index, e, forcedPlacement) => {
10642
10856
  e.preventDefault();
10643
10857
  const draggedTaskId = dragTaskIdRef.current;
10644
10858
  if (!draggedTaskId) return;
@@ -10690,7 +10904,7 @@ var TaskList = ({
10690
10904
  isDirectChildDrop: normalizedTarget.placement === "after" && reorderPlan.inferredParentId === targetTask.id
10691
10905
  });
10692
10906
  }, [isValidParentDrop, normalizeDropTarget, orderedTasks, visibleTasks]);
10693
- const handleDrop = useCallback6((dropIndex, e, forcedPlacement) => {
10907
+ const handleDrop = useCallback7((dropIndex, e, forcedPlacement) => {
10694
10908
  e.preventDefault();
10695
10909
  const originVisibleIndex = dragOriginIndexRef.current;
10696
10910
  const movedTaskId = dragTaskIdRef.current;
@@ -10757,7 +10971,7 @@ var TaskList = ({
10757
10971
  onTaskSelect?.(moved.id);
10758
10972
  clearDragState();
10759
10973
  }, [orderedTasks, visibleTasks, onReorder, onTaskSelect, isValidParentDrop, clearDragState, normalizeDropTarget]);
10760
- const handleBeforeFirstDragOver = useCallback6((e) => {
10974
+ const handleBeforeFirstDragOver = useCallback7((e) => {
10761
10975
  const draggedTaskId = dragTaskIdRef.current;
10762
10976
  const firstTask = visibleTasks[0];
10763
10977
  const descendantIds = draggedTaskId ? new Set(getAllDescendants2(draggedTaskId, orderedTasks).map((task) => task.id)) : /* @__PURE__ */ new Set();
@@ -10765,11 +10979,11 @@ var TaskList = ({
10765
10979
  setIsBeforeFirstDropZoneActive(isValidBeforeFirstDrop);
10766
10980
  handleDragOver(0, e, "before");
10767
10981
  }, [handleDragOver, isValidParentDrop, orderedTasks, visibleTasks]);
10768
- const handleDragEnd = useCallback6(() => {
10982
+ const handleDragEnd = useCallback7(() => {
10769
10983
  clearDragState();
10770
10984
  }, [clearDragState]);
10771
10985
  const shouldShowBeforeFirstDropZone = !reorderDisabled && visibleTasks.length > 0 && draggingIndex !== null && draggingIndex > 0;
10772
- const handleConfirmNewTask = useCallback6((name) => {
10986
+ const handleConfirmNewTask = useCallback7((name) => {
10773
10987
  const range = buildDefaultTaskDateRange(getTodayISODate(), {
10774
10988
  businessDays,
10775
10989
  defaultTaskDurationDays,
@@ -10784,8 +10998,8 @@ var TaskList = ({
10784
10998
  onAdd?.(newTask);
10785
10999
  setIsCreating(false);
10786
11000
  }, [businessDays, defaultTaskDurationDays, onAdd, weekendPredicate]);
10787
- const handleCancelNewTask = useCallback6(() => setIsCreating(false), []);
10788
- const findInsertAfterTaskId = useCallback6((anchorTaskId) => {
11001
+ const handleCancelNewTask = useCallback7(() => setIsCreating(false), []);
11002
+ const findInsertAfterTaskId = useCallback7((anchorTaskId) => {
10789
11003
  const anchorIndex = orderedTasks.findIndex((task) => task.id === anchorTaskId);
10790
11004
  if (anchorIndex === -1) {
10791
11005
  return anchorTaskId;
@@ -10835,7 +11049,7 @@ var TaskList = ({
10835
11049
  [pendingInsertDisplayTaskId, visibleTasks]
10836
11050
  );
10837
11051
  const hasVisiblePendingInsert = pendingInsertRowIndex >= 0;
10838
- const handleStartInsertAfter = useCallback6((taskId, newTask) => {
11052
+ const handleStartInsertAfter = useCallback7((taskId, newTask) => {
10839
11053
  const anchorTask = orderedTasks.find((task) => task.id === taskId);
10840
11054
  if (!anchorTask) {
10841
11055
  return;
@@ -10850,7 +11064,7 @@ var TaskList = ({
10850
11064
  nestingDepth: nestingDepthMap.get(taskId) ?? 0
10851
11065
  });
10852
11066
  }, [findInsertAfterTaskId, nestingDepthMap, orderedTasks]);
10853
- const handleConfirmInsertedTask = useCallback6((name) => {
11067
+ const handleConfirmInsertedTask = useCallback7((name) => {
10854
11068
  if (!pendingInsert) {
10855
11069
  return;
10856
11070
  }
@@ -10864,7 +11078,7 @@ var TaskList = ({
10864
11078
  onInsertAfter?.(pendingInsert.insertAfterTaskId, newTask);
10865
11079
  setPendingInsert(null);
10866
11080
  }, [onInsertAfter, pendingInsert]);
10867
- const handleCancelInsertedTask = useCallback6(() => setPendingInsert(null), []);
11081
+ const handleCancelInsertedTask = useCallback7(() => setPendingInsert(null), []);
10868
11082
  function getTaskDepth(task, tasks2) {
10869
11083
  if (!task) return 0;
10870
11084
  let depth = 0;
@@ -10877,7 +11091,7 @@ var TaskList = ({
10877
11091
  }
10878
11092
  return depth;
10879
11093
  }
10880
- const handleDemoteWrapper = useCallback6((taskId, _newParentId) => {
11094
+ const handleDemoteWrapper = useCallback7((taskId, _newParentId) => {
10881
11095
  const taskIndex = visibleTasks.findIndex((t) => t.id === taskId);
10882
11096
  const currentTask = visibleTasks[taskIndex];
10883
11097
  const currentDepth = getTaskDepth(currentTask, orderedTasks);
@@ -10911,7 +11125,7 @@ var TaskList = ({
10911
11125
  ];
10912
11126
  onReorder?.(updatedTasks, taskId, newSectionTask.id);
10913
11127
  }, [visibleTasks, orderedTasks, onDemoteTask, onReorder]);
10914
- const handleDuplicateTask = useCallback6((taskId) => {
11128
+ const handleDuplicateTask = useCallback7((taskId) => {
10915
11129
  const duplicatedTasks = duplicateTaskSubtree(taskId, orderedTasks);
10916
11130
  onReorder?.(duplicatedTasks);
10917
11131
  }, [orderedTasks, onReorder]);
@@ -10961,7 +11175,7 @@ var TaskList = ({
10961
11175
  const requestedTaskListWidth = taskListWidth ?? Math.min(MIN_TASK_LIST_WIDTH, resolvedColumnWidthTotal);
10962
11176
  const effectiveTaskListWidth = Math.max(requestedTaskListWidth, resolvedColumnWidthTotal);
10963
11177
  const tableHeaderHeight = headerHeight + 1;
10964
- const updateColumnWidth = useCallback6((columnId, width) => {
11178
+ const updateColumnWidth = useCallback7((columnId, width) => {
10965
11179
  setColumnWidthOverrides((prev) => {
10966
11180
  if (prev[columnId] === width) {
10967
11181
  return prev;
@@ -11047,7 +11261,7 @@ var TaskList = ({
11047
11261
  document.body.style.removeProperty("touch-action");
11048
11262
  };
11049
11263
  }, [resolvedColumns, updateColumnWidth]);
11050
- const startColumnResize = useCallback6((columnId, event) => {
11264
+ const startColumnResize = useCallback7((columnId, event) => {
11051
11265
  if (resizeStateRef.current) {
11052
11266
  return;
11053
11267
  }
@@ -11074,7 +11288,7 @@ var TaskList = ({
11074
11288
  document.body.style.userSelect = "none";
11075
11289
  document.body.style.touchAction = "none";
11076
11290
  }, [resolvedColumns]);
11077
- const renderResizeHandle = useCallback6((columnId) => /* @__PURE__ */ jsx18(
11291
+ const renderResizeHandle = useCallback7((columnId) => /* @__PURE__ */ jsx18(
11078
11292
  "button",
11079
11293
  {
11080
11294
  type: "button",
@@ -11431,7 +11645,7 @@ var TaskList = ({
11431
11645
  };
11432
11646
 
11433
11647
  // src/components/ResourceTimelineChart/ResourceTimelineChart.tsx
11434
- import React15, { useCallback as useCallback8, useEffect as useEffect10, useMemo as useMemo11, useRef as useRef10, useState as useState10 } from "react";
11648
+ import React15, { useCallback as useCallback9, useEffect as useEffect10, useMemo as useMemo11, useRef as useRef11, useState as useState10 } from "react";
11435
11649
 
11436
11650
  // src/utils/resourceTimelineLayout.ts
11437
11651
  var isInvalidDate = (date) => Number.isNaN(date.getTime());
@@ -11633,7 +11847,7 @@ var layoutResourceTimelineItems = (resources, options) => {
11633
11847
  };
11634
11848
 
11635
11849
  // src/hooks/useResourceItemDrag.ts
11636
- import { useCallback as useCallback7, useEffect as useEffect9, useRef as useRef9, useState as useState9 } from "react";
11850
+ import { useCallback as useCallback8, useEffect as useEffect9, useRef as useRef10, useState as useState9 } from "react";
11637
11851
  var RESOURCE_CURSOR_STYLE_ID = "gantt-resource-global-drag-cursor-style";
11638
11852
  function ensureResourceGlobalCursorStyle() {
11639
11853
  if (typeof document === "undefined") return;
@@ -11745,10 +11959,10 @@ var useResourceItemDrag = ({
11745
11959
  weekendPredicate,
11746
11960
  onResourceItemMove
11747
11961
  }) => {
11748
- const activeDragRef = useRef9(null);
11749
- const rowsRef = useRef9(rows);
11750
- const onResourceItemMoveRef = useRef9(onResourceItemMove);
11751
- const rafRef = useRef9(null);
11962
+ const activeDragRef = useRef10(null);
11963
+ const rowsRef = useRef10(rows);
11964
+ const onResourceItemMoveRef = useRef10(onResourceItemMove);
11965
+ const rafRef = useRef10(null);
11752
11966
  const [preview, setPreview] = useState9(null);
11753
11967
  useEffect9(() => {
11754
11968
  rowsRef.current = rows;
@@ -11756,13 +11970,13 @@ var useResourceItemDrag = ({
11756
11970
  useEffect9(() => {
11757
11971
  onResourceItemMoveRef.current = onResourceItemMove;
11758
11972
  }, [onResourceItemMove]);
11759
- const clearRaf = useCallback7(() => {
11973
+ const clearRaf = useCallback8(() => {
11760
11974
  if (rafRef.current !== null) {
11761
11975
  cancelAnimationFrame(rafRef.current);
11762
11976
  rafRef.current = null;
11763
11977
  }
11764
11978
  }, []);
11765
- const cancelDrag2 = useCallback7(() => {
11979
+ const cancelDrag2 = useCallback8(() => {
11766
11980
  clearRaf();
11767
11981
  clearResourceGlobalCursor();
11768
11982
  activeDragRef.current = null;
@@ -11841,7 +12055,7 @@ var useResourceItemDrag = ({
11841
12055
  cancelDrag2();
11842
12056
  };
11843
12057
  }, [cancelDrag2, clearRaf, disableResourceReassignment, gridElementRef]);
11844
- const startDrag = useCallback7((event, layoutItem) => {
12058
+ const startDrag = useCallback8((event, layoutItem) => {
11845
12059
  if (readonly || layoutItem.item.locked || event.button !== 0) {
11846
12060
  return;
11847
12061
  }
@@ -12106,8 +12320,8 @@ var ResourceHeader = ({
12106
12320
  const [scopeMenuOpen, setScopeMenuOpen] = useState10(false);
12107
12321
  const [editingName, setEditingName] = useState10(false);
12108
12322
  const [nameValue, setNameValue] = useState10(resource.name);
12109
- const nameInputRef = useRef10(null);
12110
- const nameConfirmedRef = useRef10(false);
12323
+ const nameInputRef = useRef11(null);
12324
+ const nameConfirmedRef = useRef11(false);
12111
12325
  const visibleCommands = useMemo11(
12112
12326
  () => menuCommands.filter((command) => command.isVisible?.(resource) ?? true),
12113
12327
  [menuCommands, resource]
@@ -12117,7 +12331,7 @@ var ResourceHeader = ({
12117
12331
  const scope = resource.scope ?? "Project";
12118
12332
  const scopeLabel = RESOURCE_SCOPE_LABELS[scope] ?? scope;
12119
12333
  const isInactive = isInactiveResourceStatus(resource.status);
12120
- const applyResourcePatch = useCallback8((patch) => {
12334
+ const applyResourcePatch = useCallback9((patch) => {
12121
12335
  onResourceChange?.({ ...resource, ...patch });
12122
12336
  }, [onResourceChange, resource]);
12123
12337
  useEffect10(() => {
@@ -12138,7 +12352,7 @@ var ResourceHeader = ({
12138
12352
  }
12139
12353
  command.onSelect(resource);
12140
12354
  };
12141
- const handleNameDoubleClick = useCallback8((event) => {
12355
+ const handleNameDoubleClick = useCallback9((event) => {
12142
12356
  if (!onResourceChange) {
12143
12357
  return;
12144
12358
  }
@@ -12147,7 +12361,7 @@ var ResourceHeader = ({
12147
12361
  setNameValue(resource.name);
12148
12362
  setEditingName(true);
12149
12363
  }, [onResourceChange, resource.name]);
12150
- const handleNameSave = useCallback8(() => {
12364
+ const handleNameSave = useCallback9(() => {
12151
12365
  if (nameConfirmedRef.current) {
12152
12366
  nameConfirmedRef.current = false;
12153
12367
  return;
@@ -12158,11 +12372,11 @@ var ResourceHeader = ({
12158
12372
  }
12159
12373
  setEditingName(false);
12160
12374
  }, [applyResourcePatch, nameValue, resource.name]);
12161
- const handleNameCancel = useCallback8(() => {
12375
+ const handleNameCancel = useCallback9(() => {
12162
12376
  setNameValue(resource.name);
12163
12377
  setEditingName(false);
12164
12378
  }, [resource.name]);
12165
- const handleNameKeyDown = useCallback8((event) => {
12379
+ const handleNameKeyDown = useCallback9((event) => {
12166
12380
  if (event.key === "Enter") {
12167
12381
  nameConfirmedRef.current = true;
12168
12382
  const nextName = nameValue.trim();
@@ -12367,8 +12581,8 @@ var ResourceHeader = ({
12367
12581
  };
12368
12582
  var NewResourceRow = ({ height, onConfirm, onCancel, columnTemplate }) => {
12369
12583
  const [nameValue, setNameValue] = useState10("");
12370
- const inputRef = useRef10(null);
12371
- const confirmedRef = useRef10(false);
12584
+ const inputRef = useRef11(null);
12585
+ const confirmedRef = useRef11(false);
12372
12586
  useEffect10(() => {
12373
12587
  inputRef.current?.focus();
12374
12588
  inputRef.current?.select();
@@ -12454,13 +12668,13 @@ function ResourceTimelineChart({
12454
12668
  resourceTableColumnWidths,
12455
12669
  onResourceTableColumnWidthsChange
12456
12670
  }) {
12457
- const scrollContainerRef = useRef10(null);
12458
- const gridRef = useRef10(null);
12459
- const panStateRef = useRef10(null);
12460
- const resourceColumnResizeRef = useRef10(null);
12461
- const conflictNavigationIndexRef = useRef10(/* @__PURE__ */ new Map());
12462
- const resourceNavigationIndexRef = useRef10(/* @__PURE__ */ new Map());
12463
- const conflictHighlightTimeoutRef = useRef10(null);
12671
+ const scrollContainerRef = useRef11(null);
12672
+ const gridRef = useRef11(null);
12673
+ const panStateRef = useRef11(null);
12674
+ const resourceColumnResizeRef = useRef11(null);
12675
+ const conflictNavigationIndexRef = useRef11(/* @__PURE__ */ new Map());
12676
+ const resourceNavigationIndexRef = useRef11(/* @__PURE__ */ new Map());
12677
+ const conflictHighlightTimeoutRef = useRef11(null);
12464
12678
  const [isCreatingResource, setIsCreatingResource] = useState10(false);
12465
12679
  const [creatingResourceGroupType, setCreatingResourceGroupType] = useState10(null);
12466
12680
  const [activeConflictItemId, setActiveConflictItemId] = useState10(null);
@@ -12534,7 +12748,7 @@ function ResourceTimelineChart({
12534
12748
  const canAddResource = enableAddResource && Boolean(onAddResource);
12535
12749
  const resourceAddRowHeight = laneHeight + DEFAULT_RESOURCE_ROW_GAP;
12536
12750
  const [collapsedResourceGroups, setCollapsedResourceGroups] = useState10(/* @__PURE__ */ new Set());
12537
- const updateResourceColumnWidth = useCallback8((columnId, width) => {
12751
+ const updateResourceColumnWidth = useCallback9((columnId, width) => {
12538
12752
  setResourceColumnWidthOverrides((prev) => {
12539
12753
  if (prev[columnId] === width) {
12540
12754
  return prev;
@@ -12573,7 +12787,7 @@ function ResourceTimelineChart({
12573
12787
  document.body.style.removeProperty("user-select");
12574
12788
  };
12575
12789
  }, [updateResourceColumnWidth]);
12576
- const startResourceColumnResize = useCallback8((columnId, event) => {
12790
+ const startResourceColumnResize = useCallback9((columnId, event) => {
12577
12791
  const width = resolvedResourceColumnWidths[columnId];
12578
12792
  if (typeof width !== "number") {
12579
12793
  return;
@@ -12588,7 +12802,7 @@ function ResourceTimelineChart({
12588
12802
  document.body.style.cursor = "col-resize";
12589
12803
  document.body.style.userSelect = "none";
12590
12804
  }, [resolvedResourceColumnWidths]);
12591
- const renderResizeHandle = useCallback8((columnId) => /* @__PURE__ */ jsx19(
12805
+ const renderResizeHandle = useCallback9((columnId) => /* @__PURE__ */ jsx19(
12592
12806
  "button",
12593
12807
  {
12594
12808
  type: "button",
@@ -12602,7 +12816,7 @@ function ResourceTimelineChart({
12602
12816
  }
12603
12817
  }
12604
12818
  ), [startResourceColumnResize]);
12605
- const toggleResourceGroupCollapsed = useCallback8((groupKey) => {
12819
+ const toggleResourceGroupCollapsed = useCallback9((groupKey) => {
12606
12820
  setCollapsedResourceGroups((prev) => {
12607
12821
  const next = new Set(prev);
12608
12822
  if (next.has(groupKey)) {
@@ -12728,7 +12942,7 @@ function ResourceTimelineChart({
12728
12942
  }, [displayLayout.items]);
12729
12943
  const displayTotalHeight = displayLayout.totalHeight + (canAddResource ? resourceAddRowHeight : 0);
12730
12944
  const timelineHeaderHeight = headerHeight + 1;
12731
- const handleConfirmNewResource = useCallback8((name) => {
12945
+ const handleConfirmNewResource = useCallback9((name) => {
12732
12946
  onAddResource?.({
12733
12947
  id: crypto.randomUUID(),
12734
12948
  name,
@@ -12739,7 +12953,7 @@ function ResourceTimelineChart({
12739
12953
  setIsCreatingResource(false);
12740
12954
  setCreatingResourceGroupType(null);
12741
12955
  }, [creatingResourceGroupType, onAddResource]);
12742
- const handleStartAddResourceToGroup = useCallback8((type) => {
12956
+ const handleStartAddResourceToGroup = useCallback9((type) => {
12743
12957
  setIsCreatingResource(false);
12744
12958
  setCreatingResourceGroupType(type);
12745
12959
  setCollapsedResourceGroups((prev) => {
@@ -12751,11 +12965,11 @@ function ResourceTimelineChart({
12751
12965
  return next;
12752
12966
  });
12753
12967
  }, []);
12754
- const handleCancelNewResource = useCallback8(() => {
12968
+ const handleCancelNewResource = useCallback9(() => {
12755
12969
  setIsCreatingResource(false);
12756
12970
  setCreatingResourceGroupType(null);
12757
12971
  }, []);
12758
- const handleConflictBadgeClick = useCallback8((resourceId) => {
12972
+ const handleConflictBadgeClick = useCallback9((resourceId) => {
12759
12973
  const conflictItems = conflictItemsByResourceId.get(resourceId) ?? [];
12760
12974
  if (conflictItems.length === 0) {
12761
12975
  return;
@@ -12780,7 +12994,7 @@ function ResourceTimelineChart({
12780
12994
  conflictHighlightTimeoutRef.current = null;
12781
12995
  }, 1600);
12782
12996
  }, [conflictItemsByResourceId, dayWidth, laneHeight]);
12783
- const handleResourceNameClick = useCallback8((resourceId) => {
12997
+ const handleResourceNameClick = useCallback9((resourceId) => {
12784
12998
  const resourceItems = itemsByResourceId.get(resourceId) ?? [];
12785
12999
  if (resourceItems.length === 0) {
12786
13000
  return;
@@ -12825,7 +13039,7 @@ function ResourceTimelineChart({
12825
13039
  container.removeEventListener("scroll", updateShadow);
12826
13040
  };
12827
13041
  }, []);
12828
- const handlePanStart = useCallback8((event) => {
13042
+ const handlePanStart = useCallback9((event) => {
12829
13043
  if (event.button !== 0) {
12830
13044
  return;
12831
13045
  }
@@ -13312,7 +13526,7 @@ function ResourceTimelineChart({
13312
13526
  }
13313
13527
 
13314
13528
  // src/components/TableMatrix/TableMatrix.tsx
13315
- import { useLayoutEffect, useMemo as useMemo12, useRef as useRef11, useState as useState11 } from "react";
13529
+ import { useLayoutEffect, useMemo as useMemo12, useRef as useRef12, useState as useState11 } from "react";
13316
13530
  import { jsx as jsx20, jsxs as jsxs14 } from "react/jsx-runtime";
13317
13531
  var AUTO_COLUMN_MIN_WIDTH = 72;
13318
13532
  var AUTO_COLUMN_MAX_WIDTH = 180;
@@ -13379,7 +13593,7 @@ function TableMatrix({
13379
13593
  filterMode = "highlight",
13380
13594
  visibleRowIndices
13381
13595
  }) {
13382
- const measureRef = useRef11(null);
13596
+ const measureRef = useRef12(null);
13383
13597
  const [measuredAutoWidths, setMeasuredAutoWidths] = useState11([]);
13384
13598
  const hasAutoWidthColumns = useMemo12(
13385
13599
  () => columns.some((column) => typeof column.width !== "number"),
@@ -13680,7 +13894,7 @@ function TableMatrix({
13680
13894
  }
13681
13895
 
13682
13896
  // src/components/PlanFactMatrix/PlanFactMatrix.tsx
13683
- import React17, { useCallback as useCallback9, useEffect as useEffect11, useMemo as useMemo13, useRef as useRef12, useState as useState12 } from "react";
13897
+ import React17, { useCallback as useCallback10, useEffect as useEffect11, useMemo as useMemo13, useRef as useRef13, useState as useState12 } from "react";
13684
13898
  import { jsx as jsx21, jsxs as jsxs15 } from "react/jsx-runtime";
13685
13899
  var DAY_MS6 = 24 * 60 * 60 * 1e3;
13686
13900
  function joinClasses2(...values) {
@@ -13773,7 +13987,7 @@ function PlanFactCellEditor({
13773
13987
  onCancel
13774
13988
  }) {
13775
13989
  const [draft, setDraft] = useState12(startValue ?? (value === void 0 ? "" : String(value)));
13776
- const inputRef = useRef12(null);
13990
+ const inputRef = useRef13(null);
13777
13991
  useEffect11(() => {
13778
13992
  inputRef.current?.focus();
13779
13993
  if (startValue === void 0) {
@@ -13782,7 +13996,7 @@ function PlanFactCellEditor({
13782
13996
  inputRef.current?.setSelectionRange(startValue.length, startValue.length);
13783
13997
  }
13784
13998
  }, [startValue]);
13785
- const commit = useCallback9(() => {
13999
+ const commit = useCallback10(() => {
13786
14000
  const parsed = parseNumberInput(draft);
13787
14001
  if (parsed === null) {
13788
14002
  onCancel();
@@ -14132,13 +14346,13 @@ function PlanFactMatrix({
14132
14346
  const [selectedRange, setSelectedRange] = useState12(null);
14133
14347
  const [fillRange, setFillRange] = useState12(null);
14134
14348
  const [overflowTooltip, setOverflowTooltip] = useState12(null);
14135
- const isSelectingRef = useRef12(false);
14136
- const isFillDraggingRef = useRef12(false);
14137
- const didDragSelectRef = useRef12(false);
14138
- const pendingHoverCellRef = useRef12(null);
14139
- const hoverFrameRef = useRef12(null);
14140
- const rootRef = useRef12(null);
14141
- const bodyRef = useRef12(null);
14349
+ const isSelectingRef = useRef13(false);
14350
+ const isFillDraggingRef = useRef13(false);
14351
+ const didDragSelectRef = useRef13(false);
14352
+ const pendingHoverCellRef = useRef13(null);
14353
+ const hoverFrameRef = useRef13(null);
14354
+ const rootRef = useRef13(null);
14355
+ const bodyRef = useRef13(null);
14142
14356
  const totalWidth = dateRange.length * dayWidth;
14143
14357
  const subrowHeight = rowHeight / 2;
14144
14358
  const renderedRowIndices = useMemo13(
@@ -14187,7 +14401,7 @@ function PlanFactMatrix({
14187
14401
  }
14188
14402
  return rangeByTaskId;
14189
14403
  }, [dateRange.length, dateRangeStartMs, tasks]);
14190
- const focusCell = useCallback9((cell) => {
14404
+ const focusCell = useCallback10((cell) => {
14191
14405
  window.requestAnimationFrame(() => {
14192
14406
  const selector = [
14193
14407
  `[data-plan-fact-task-id="${escapeAttributeValue(cell.taskId)}"]`,
@@ -14197,7 +14411,7 @@ function PlanFactMatrix({
14197
14411
  bodyRef.current?.querySelector(selector)?.focus();
14198
14412
  });
14199
14413
  }, []);
14200
- const clearSelection = useCallback9(() => {
14414
+ const clearSelection = useCallback10(() => {
14201
14415
  if (hoverFrameRef.current !== null) {
14202
14416
  window.cancelAnimationFrame(hoverFrameRef.current);
14203
14417
  hoverFrameRef.current = null;
@@ -14212,10 +14426,10 @@ function PlanFactMatrix({
14212
14426
  setFillRange(null);
14213
14427
  setOverflowTooltip(null);
14214
14428
  }, []);
14215
- const hideOverflowTooltip = useCallback9(() => {
14429
+ const hideOverflowTooltip = useCallback10(() => {
14216
14430
  setOverflowTooltip(null);
14217
14431
  }, []);
14218
- const flushPendingHoverCell = useCallback9(() => {
14432
+ const flushPendingHoverCell = useCallback10(() => {
14219
14433
  hoverFrameRef.current = null;
14220
14434
  const currentCell = pendingHoverCellRef.current;
14221
14435
  if (!currentCell) return;
@@ -14233,12 +14447,12 @@ function PlanFactMatrix({
14233
14447
  }));
14234
14448
  onTaskSelect?.(currentCell.taskId);
14235
14449
  }, [onTaskSelect, selectedRange]);
14236
- const queueHoverCellUpdate = useCallback9((cell) => {
14450
+ const queueHoverCellUpdate = useCallback10((cell) => {
14237
14451
  pendingHoverCellRef.current = cell;
14238
14452
  if (hoverFrameRef.current !== null) return;
14239
14453
  hoverFrameRef.current = window.requestAnimationFrame(flushPendingHoverCell);
14240
14454
  }, [flushPendingHoverCell]);
14241
- const showOverflowTooltip = useCallback9((target, label, force = false) => {
14455
+ const showOverflowTooltip = useCallback10((target, label, force = false) => {
14242
14456
  if (!rootRef.current || !label) return;
14243
14457
  if (!force && target.scrollWidth <= target.clientWidth) {
14244
14458
  setOverflowTooltip(null);
@@ -14252,12 +14466,12 @@ function PlanFactMatrix({
14252
14466
  top: targetRect.top - rootRect.top
14253
14467
  });
14254
14468
  }, []);
14255
- const selectSingleCell = useCallback9((cell) => {
14469
+ const selectSingleCell = useCallback10((cell) => {
14256
14470
  setActiveCell(cell);
14257
14471
  setSelectedRange({ anchor: cell, focus: cell });
14258
14472
  setFillRange(null);
14259
14473
  }, []);
14260
- const getRangeBounds = useCallback9((range) => {
14474
+ const getRangeBounds = useCallback10((range) => {
14261
14475
  const anchorTaskIndex = taskIndexById.get(range.anchor.taskId);
14262
14476
  const focusTaskIndex = taskIndexById.get(range.focus.taskId);
14263
14477
  if (anchorTaskIndex === void 0 || focusTaskIndex === void 0) {
@@ -14281,7 +14495,7 @@ function PlanFactMatrix({
14281
14495
  () => renderedRange ? getRangeBounds(renderedRange) : null,
14282
14496
  [getRangeBounds, renderedRange]
14283
14497
  );
14284
- const getCellFromPosition = useCallback9((subrowIndex, dateIndex) => {
14498
+ const getCellFromPosition = useCallback10((subrowIndex, dateIndex) => {
14285
14499
  const task = tasks[Math.floor(subrowIndex / 2)];
14286
14500
  if (!task) return null;
14287
14501
  return {
@@ -14290,7 +14504,7 @@ function PlanFactMatrix({
14290
14504
  kind: subrowIndex % 2 === 0 ? "plan" : "fact"
14291
14505
  };
14292
14506
  }, [tasks]);
14293
- const isCellInRange = useCallback9((cell, range) => {
14507
+ const isCellInRange = useCallback10((cell, range) => {
14294
14508
  const bounds = getRangeBounds(range);
14295
14509
  if (!bounds) return false;
14296
14510
  const cellTaskIndex = taskIndexById.get(cell.taskId);
@@ -14300,7 +14514,7 @@ function PlanFactMatrix({
14300
14514
  const cellSubrowIndex = getSubrowIndex(cellTaskIndex, cell.kind);
14301
14515
  return cell.dateIndex >= bounds.fromDateIndex && cell.dateIndex <= bounds.toDateIndex && cellSubrowIndex >= bounds.fromSubrowIndex && cellSubrowIndex <= bounds.toSubrowIndex;
14302
14516
  }, [getRangeBounds, taskIndexById]);
14303
- const commitCell = useCallback9((task, dateIndex, kind, value) => {
14517
+ const commitCell = useCallback10((task, dateIndex, kind, value) => {
14304
14518
  const dateKey = dateKeys[dateIndex];
14305
14519
  const source = kind === "plan" ? task.planByDate : task.factByDate;
14306
14520
  const nextValues = { ...source ?? {} };
@@ -14322,7 +14536,7 @@ function PlanFactMatrix({
14322
14536
  value
14323
14537
  });
14324
14538
  }, [dateKeys, dateRange, onCellCommit, onTasksChange]);
14325
- const commitRangeCells = useCallback9((bounds, value, mode) => {
14539
+ const commitRangeCells = useCallback10((bounds, value, mode) => {
14326
14540
  const changedTasksById = /* @__PURE__ */ new Map();
14327
14541
  for (let subrowIndex = bounds.fromSubrowIndex; subrowIndex <= bounds.toSubrowIndex; subrowIndex += 1) {
14328
14542
  const task = tasks[Math.floor(subrowIndex / 2)];
@@ -14369,7 +14583,7 @@ function PlanFactMatrix({
14369
14583
  onTasksChange?.(changedTasks);
14370
14584
  }
14371
14585
  }, [dateKeys, onTasksChange, parentTaskIds, tasks]);
14372
- const clearSelectedCells = useCallback9(() => {
14586
+ const clearSelectedCells = useCallback10(() => {
14373
14587
  const activeRange = fillRange ?? selectedRange;
14374
14588
  if (!activeRange) {
14375
14589
  if (!activeCell) return;
@@ -14383,7 +14597,7 @@ function PlanFactMatrix({
14383
14597
  commitRangeCells(bounds, void 0, "clear");
14384
14598
  }
14385
14599
  }, [activeCell, commitCell, commitRangeCells, fillRange, getRangeBounds, parentTaskIds, selectedRange, taskById]);
14386
- const commitSelectedCells = useCallback9((value) => {
14600
+ const commitSelectedCells = useCallback10((value) => {
14387
14601
  const activeRange = fillRange ?? selectedRange;
14388
14602
  if (!activeRange) {
14389
14603
  if (!activeCell) return;
@@ -14397,13 +14611,13 @@ function PlanFactMatrix({
14397
14611
  commitRangeCells(bounds, value, "set");
14398
14612
  }
14399
14613
  }, [activeCell, commitCell, commitRangeCells, fillRange, getRangeBounds, parentTaskIds, selectedRange, taskById]);
14400
- const getCellValue = useCallback9((cell) => {
14614
+ const getCellValue = useCallback10((cell) => {
14401
14615
  const task = taskById.get(cell.taskId);
14402
14616
  if (!task) return void 0;
14403
14617
  const dateKey = dateKeys[cell.dateIndex];
14404
14618
  return cell.kind === "plan" ? task.planByDate?.[dateKey] : task.factByDate?.[dateKey];
14405
14619
  }, [dateKeys, taskById]);
14406
- const applyFillRange = useCallback9((nextFillRange) => {
14620
+ const applyFillRange = useCallback10((nextFillRange) => {
14407
14621
  const targetRange = nextFillRange ?? fillRange;
14408
14622
  if (!selectedRange || !targetRange) return;
14409
14623
  const sourceBounds = getRangeBounds(selectedRange);
@@ -14476,7 +14690,7 @@ function PlanFactMatrix({
14476
14690
  selectedRange,
14477
14691
  taskById
14478
14692
  ]);
14479
- const moveActiveCell = useCallback9((cell, direction) => {
14693
+ const moveActiveCell = useCallback10((cell, direction) => {
14480
14694
  const taskIndex = tasks.findIndex((task) => task.id === cell.taskId);
14481
14695
  if (taskIndex < 0) return;
14482
14696
  let nextCell = { ...cell };
@@ -14508,7 +14722,7 @@ function PlanFactMatrix({
14508
14722
  onTaskSelect?.(nextCell.taskId);
14509
14723
  focusCell(nextCell);
14510
14724
  }, [dateRange.length, focusCell, onTaskSelect, parentTaskIds, tasks]);
14511
- const extendSelectedRange = useCallback9((cell, direction) => {
14725
+ const extendSelectedRange = useCallback10((cell, direction) => {
14512
14726
  const taskIndex = tasks.findIndex((task) => task.id === cell.taskId);
14513
14727
  if (taskIndex < 0) return;
14514
14728
  let nextCell = { ...cell };
@@ -15303,17 +15517,6 @@ function TaskGanttChartInner(props, ref) {
15303
15517
  onTaskDateChangeModeChange: externalOnTaskDateChangeModeChange,
15304
15518
  printDependencyLabels = false
15305
15519
  } = props;
15306
- const resolvedActivityDependencies = useMemo14(() => {
15307
- if (activityDependencies !== void 0) return activityDependencies;
15308
- return tasks.flatMap((task) => (task.activities ?? []).slice(1).map((successor, index) => ({
15309
- predecessorTaskId: task.id,
15310
- predecessorActivityId: task.activities[index].id,
15311
- successorTaskId: task.id,
15312
- successorActivityId: successor.id,
15313
- type: "FS",
15314
- lag: successor.lag ?? 0
15315
- })));
15316
- }, [tasks, activityDependencies]);
15317
15520
  const dayWidth = !isTableMatrixMode ? props.dayWidth ?? 40 : 40;
15318
15521
  const criticalPathMode = !isTableMatrixMode && !isPlanFactMode ? props.criticalPathMode : void 0;
15319
15522
  const onSubtreeScaleResult = !isTableMatrixMode && !isPlanFactMode ? props.onSubtreeScaleResult : void 0;
@@ -15327,17 +15530,17 @@ function TaskGanttChartInner(props, ref) {
15327
15530
  const onMatrixCellClick = isTableMatrixMode ? props.onMatrixCellClick : void 0;
15328
15531
  const matrixDateOverlay = isTableMatrixMode ? props.matrixDateOverlay : void 0;
15329
15532
  const onPlanFactCellCommit = isPlanFactMode ? props.onPlanFactCellCommit : void 0;
15330
- const containerRef = useRef13(null);
15331
- const scrollContainerRef = useRef13(null);
15332
- const scrollContentRef = useRef13(null);
15333
- const clearSelectedTaskTimeoutRef = useRef13(null);
15334
- const hasAutoScrolledToTodayRef = useRef13(false);
15335
- const previewPositionStoreRef = useRef13(null);
15336
- const activityPreviewStoreRef = useRef13(null);
15337
- const activityBlockStoreRef = useRef13(null);
15338
- const activityDragOwnerRef = useRef13(null);
15339
- const activityActivationStoreRef = useRef13(null);
15340
- const renderedTaskIdsRef = useRef13(/* @__PURE__ */ new Set());
15533
+ const containerRef = useRef14(null);
15534
+ const scrollContainerRef = useRef14(null);
15535
+ const scrollContentRef = useRef14(null);
15536
+ const clearSelectedTaskTimeoutRef = useRef14(null);
15537
+ const hasAutoScrolledToTodayRef = useRef14(false);
15538
+ const previewPositionStoreRef = useRef14(null);
15539
+ const activityPreviewStoreRef = useRef14(null);
15540
+ const activityBlockStoreRef = useRef14(null);
15541
+ const activityDragOwnerRef = useRef14(null);
15542
+ const activityActivationStoreRef = useRef14(null);
15543
+ const renderedTaskIdsRef = useRef14(/* @__PURE__ */ new Set());
15341
15544
  if (previewPositionStoreRef.current === null) {
15342
15545
  previewPositionStoreRef.current = createTaskPreviewPositionStore();
15343
15546
  }
@@ -15373,10 +15576,10 @@ function TaskGanttChartInner(props, ref) {
15373
15576
  const [planFactDateWindow, setPlanFactDateWindow] = useState13({ start: 0, end: 0 });
15374
15577
  const [selectedChip, setSelectedChip] = useState13(null);
15375
15578
  const [dependencyCreationDrag, setDependencyCreationDrag] = useState13(null);
15376
- const dependencyCreationRef = useRef13(null);
15579
+ const dependencyCreationRef = useRef14(null);
15377
15580
  const [dependencyCreationError, setDependencyCreationError] = useState13(null);
15378
15581
  const [dependencyLineMenu, setDependencyLineMenu] = useState13(null);
15379
- const getDependencyPortPoint = useCallback10((element, chartRect) => {
15582
+ const getDependencyPortPoint = useCallback11((element, chartRect) => {
15380
15583
  const rect = element.getBoundingClientRect();
15381
15584
  const side = element.getAttribute("data-port-side");
15382
15585
  return {
@@ -15390,13 +15593,13 @@ function TaskGanttChartInner(props, ref) {
15390
15593
  y: rect.top + rect.height / 2 - chartRect.top
15391
15594
  };
15392
15595
  }, []);
15393
- const getVisualDependencyType = useCallback10((sourceSide, targetSide) => {
15596
+ const getVisualDependencyType = useCallback11((sourceSide, targetSide) => {
15394
15597
  if (sourceSide === "right" && targetSide === "left") return "FS";
15395
15598
  if (sourceSide === "left" && targetSide === "left") return "SS";
15396
15599
  if (sourceSide === "right" && targetSide === "right") return "FF";
15397
15600
  return "SF";
15398
15601
  }, []);
15399
- const handleDependencyPortPointerDown = useCallback10((sourceId, sourceSide, event) => {
15602
+ const handleDependencyPortPointerDown = useCallback11((sourceId, sourceSide, event) => {
15400
15603
  if (disableDependencyEditing || event.button !== 0) return;
15401
15604
  const chartElement = event.currentTarget.closest(".gantt-taskArea");
15402
15605
  if (!(chartElement instanceof HTMLElement)) return;
@@ -15514,7 +15717,7 @@ function TaskGanttChartInner(props, ref) {
15514
15717
  document.removeEventListener("keydown", closeOnEscape);
15515
15718
  };
15516
15719
  }, [dependencyLineMenu]);
15517
- const handleDependencyLineClick = useCallback10((dependency) => {
15720
+ const handleDependencyLineClick = useCallback11((dependency) => {
15518
15721
  setSelectedChip({
15519
15722
  predecessorId: dependency.predecessorId,
15520
15723
  successorId: dependency.successorId,
@@ -15522,10 +15725,10 @@ function TaskGanttChartInner(props, ref) {
15522
15725
  });
15523
15726
  setDependencyLineMenu(dependency);
15524
15727
  }, []);
15525
- const handleDependencyLineClose = useCallback10(() => {
15728
+ const handleDependencyLineClose = useCallback11(() => {
15526
15729
  setDependencyLineMenu(null);
15527
15730
  }, []);
15528
- const handleDependencyLineDelete = useCallback10(() => {
15731
+ const handleDependencyLineDelete = useCallback11(() => {
15529
15732
  if (!dependencyLineMenu) return;
15530
15733
  const successor = tasks.find((task) => task.id === dependencyLineMenu.successorId);
15531
15734
  if (!successor) return;
@@ -15582,7 +15785,7 @@ function TaskGanttChartInner(props, ref) {
15582
15785
  () => buildControlledScheduleIdentity(normalizedTasks),
15583
15786
  [normalizedTasks]
15584
15787
  );
15585
- const previousControlledScheduleIdentityRef = useRef13(null);
15788
+ const previousControlledScheduleIdentityRef = useRef14(null);
15586
15789
  const controlledScheduleChanged = previousControlledScheduleIdentityRef.current !== null && previousControlledScheduleIdentityRef.current !== controlledScheduleIdentity;
15587
15790
  const [previewTasksById, setPreviewTasksById] = useState13(/* @__PURE__ */ new Map());
15588
15791
  const previewNormalizedTasks = useMemo14(() => {
@@ -15831,7 +16034,7 @@ function TaskGanttChartInner(props, ref) {
15831
16034
  window.removeEventListener("resize", scheduleUpdate);
15832
16035
  };
15833
16036
  }, [dateRange.length, dayWidth, isPlanFactMode, showTaskList, taskListWidth, timelineHeaderHeight]);
15834
- const scrollToToday = useCallback10(() => {
16037
+ const scrollToToday = useCallback11(() => {
15835
16038
  if (isTableMatrixMode) return;
15836
16039
  const container = scrollContainerRef.current;
15837
16040
  if (!container || dateRange.length === 0) return;
@@ -15843,7 +16046,7 @@ function TaskGanttChartInner(props, ref) {
15843
16046
  const scrollLeft = Math.round(todayOffset + dayWidth / 2 - containerWidth * 0.3);
15844
16047
  container.scrollTo({ left: Math.max(0, scrollLeft), behavior: "smooth" });
15845
16048
  }, [dateRange, dayWidth, isTableMatrixMode]);
15846
- const scrollToTask = useCallback10((taskId) => {
16049
+ const scrollToTask = useCallback11((taskId) => {
15847
16050
  if (isTableMatrixMode) {
15848
16051
  const container2 = scrollContainerRef.current;
15849
16052
  if (!container2) return;
@@ -15870,7 +16073,7 @@ function TaskGanttChartInner(props, ref) {
15870
16073
  const scrollLeft = Math.round(taskOffset - dayWidth * 2);
15871
16074
  container.scrollTo({ left: Math.max(0, scrollLeft), behavior: "smooth" });
15872
16075
  }, [dateRange, dayWidth, effectiveRowHeight, compositeRowLayout, isTableMatrixMode, tasks, visibleTasks]);
15873
- const scrollToRow = useCallback10((taskId, options = {}) => {
16076
+ const scrollToRow = useCallback11((taskId, options = {}) => {
15874
16077
  const container = scrollContainerRef.current;
15875
16078
  if (!container) return;
15876
16079
  const task = tasks.find((t) => t.id === taskId);
@@ -15932,7 +16135,7 @@ function TaskGanttChartInner(props, ref) {
15932
16135
  activityDragOwner.set(null);
15933
16136
  activityActivationStore.setActiveKey(null);
15934
16137
  }, [previewPositionStore, activityPreviewStore, activityBlockStore, activityDragOwner, activityActivationStore]);
15935
- const handleTaskChange = useCallback10((updatedTasks, durationEdit) => {
16138
+ const handleTaskChange = useCallback11((updatedTasks, durationEdit) => {
15936
16139
  let updatedTask = updatedTasks[0];
15937
16140
  if (!updatedTask) return;
15938
16141
  const originalTask = normalizedTasks.find((t) => t.id === updatedTask.id);
@@ -16068,7 +16271,7 @@ function TaskGanttChartInner(props, ref) {
16068
16271
  onTasksChange?.(cascadedTasks);
16069
16272
  }
16070
16273
  }, [tasks, normalizedTasks, onTasksChange, onScheduleIntent, disableConstraints, editingTaskId, businessDays, isCustomWeekend, onSubtreeScaleResult]);
16071
- const handleTaskDurationChange = useCallback10((task, duration) => {
16274
+ const handleTaskDurationChange = useCallback11((task, duration) => {
16072
16275
  const updatedTask = {
16073
16276
  ...task,
16074
16277
  endDate: task.type === "milestone" ? task.startDate : buildTaskRangeFromStart(
@@ -16080,7 +16283,7 @@ function TaskGanttChartInner(props, ref) {
16080
16283
  };
16081
16284
  handleTaskChange([updatedTask], { duration, anchor: "start" });
16082
16285
  }, [businessDays, handleTaskChange, isCustomWeekend]);
16083
- const handleDelete = useCallback10((taskId) => {
16286
+ const handleDelete = useCallback11((taskId) => {
16084
16287
  const toDelete = /* @__PURE__ */ new Set([taskId]);
16085
16288
  function collectDescendants(parentId) {
16086
16289
  const children = getChildren(parentId, tasks);
@@ -16105,10 +16308,10 @@ function TaskGanttChartInner(props, ref) {
16105
16308
  }
16106
16309
  toDelete.forEach((id) => onDelete?.(id));
16107
16310
  }, [tasks, onTasksChange, onDelete]);
16108
- const handleInsertAfter = useCallback10((taskId, newTask) => {
16311
+ const handleInsertAfter = useCallback11((taskId, newTask) => {
16109
16312
  onInsertAfter?.(taskId, newTask);
16110
16313
  }, [onInsertAfter]);
16111
- const handleReorder = useCallback10((reorderedTasks, movedTaskId, inferredParentId) => {
16314
+ const handleReorder = useCallback11((reorderedTasks, movedTaskId, inferredParentId) => {
16112
16315
  let updated = reorderedTasks;
16113
16316
  if (movedTaskId) {
16114
16317
  updated = updated.map((t) => {
@@ -16140,7 +16343,7 @@ function TaskGanttChartInner(props, ref) {
16140
16343
  }
16141
16344
  return map;
16142
16345
  }, [cascadeOverrides, controlledScheduleChanged, draggedTaskOverride]);
16143
- const handleCascadeProgress = useCallback10((overrides, previewTasks = []) => {
16346
+ const handleCascadeProgress = useCallback11((overrides, previewTasks = []) => {
16144
16347
  previewPositionStore.setPositions(overrides);
16145
16348
  const renderedTaskIds = renderedTaskIdsRef.current;
16146
16349
  const renderedOverrides = /* @__PURE__ */ new Map();
@@ -16220,7 +16423,7 @@ function TaskGanttChartInner(props, ref) {
16220
16423
  }
16221
16424
  }
16222
16425
  return Array.from(indices).sort((left, right) => left - right);
16223
- }, [compositeRowLayout, forceFullRenderForPrint, forcedRenderedTaskIds, scrollViewport, visibleTaskIndexMap, visibleTasks.length]);
16426
+ }, [compositeRowLayout, forceFullRenderForPrint, forcedRenderedTaskIds, scrollViewport.scrollTop, scrollViewport.viewportHeight, visibleTaskIndexMap, visibleTasks.length]);
16224
16427
  const visiblePlanFactDateIndices = useMemo14(() => {
16225
16428
  if (forceFullRenderForPrint) {
16226
16429
  return void 0;
@@ -16249,22 +16452,22 @@ function TaskGanttChartInner(props, ref) {
16249
16452
  () => new Set(renderedChartTasks.map(({ task }) => task.id)),
16250
16453
  [renderedChartTasks]
16251
16454
  );
16252
- const handleCascade = useCallback10((cascadedTasks) => {
16455
+ const handleCascade = useCallback11((cascadedTasks) => {
16253
16456
  if (!onScheduleIntent) {
16254
16457
  onTasksChange?.(cascadedTasks);
16255
16458
  }
16256
16459
  }, [onScheduleIntent, onTasksChange]);
16257
- const handleTaskSelect = useCallback10((taskId) => {
16460
+ const handleTaskSelect = useCallback11((taskId) => {
16258
16461
  setSelectedTaskId(taskId);
16259
16462
  }, []);
16260
- const hoveredRowElementsRef = useRef13([]);
16261
- const clearHoveredRows = useCallback10(() => {
16463
+ const hoveredRowElementsRef = useRef14([]);
16464
+ const clearHoveredRows = useCallback11(() => {
16262
16465
  for (const element of hoveredRowElementsRef.current) {
16263
16466
  element.classList.remove("gantt-tl-row-hovered", "gantt-tr-row-hovered", "gantt-mx-row-hovered", "gantt-pf-row-hovered");
16264
16467
  }
16265
16468
  hoveredRowElementsRef.current = [];
16266
16469
  }, []);
16267
- const applyHoveredRows = useCallback10((taskId) => {
16470
+ const applyHoveredRows = useCallback11((taskId) => {
16268
16471
  const root = scrollContentRef.current;
16269
16472
  if (!root) return;
16270
16473
  clearHoveredRows();
@@ -16287,7 +16490,7 @@ function TaskGanttChartInner(props, ref) {
16287
16490
  }
16288
16491
  hoveredRowElementsRef.current = nextHoveredRows;
16289
16492
  }, [clearHoveredRows]);
16290
- const handleSharedRowHover = useCallback10((event) => {
16493
+ const handleSharedRowHover = useCallback11((event) => {
16291
16494
  const target = event.target;
16292
16495
  const row = target.closest("[data-gantt-task-row-id]");
16293
16496
  const taskId = row?.dataset.ganttTaskRowId;
@@ -16317,7 +16520,7 @@ function TaskGanttChartInner(props, ref) {
16317
16520
  return next;
16318
16521
  });
16319
16522
  });
16320
- const lastCompositeBarToggleRef = useRef13(null);
16523
+ const lastCompositeBarToggleRef = useRef14(null);
16321
16524
  const handleCompositeBarToggle = (taskId, source) => {
16322
16525
  const now = Date.now();
16323
16526
  if (source === "click" && lastCompositeBarToggleRef.current?.source === "release" && lastCompositeBarToggleRef.current.id === taskId && now - lastCompositeBarToggleRef.current.time < 150) return;
@@ -16328,17 +16531,17 @@ function TaskGanttChartInner(props, ref) {
16328
16531
  const taskIds = new Set(normalizedTasks.map((task) => task.id));
16329
16532
  return new Set(normalizedTasks.map((task) => task.parentId).filter((parentId) => Boolean(parentId && taskIds.has(parentId))));
16330
16533
  }, [normalizedTasks]);
16331
- const handleCollapseAll = useCallback10(() => {
16534
+ const handleCollapseAll = useCallback11(() => {
16332
16535
  if (externalCollapsedParentIds) return;
16333
16536
  setInternalCollapsedParentIds(allParentIds);
16334
16537
  setExpandedCompositeIds(/* @__PURE__ */ new Set());
16335
16538
  }, [allParentIds, externalCollapsedParentIds]);
16336
- const handleExpandAll = useCallback10(() => {
16539
+ const handleExpandAll = useCallback11(() => {
16337
16540
  if (externalCollapsedParentIds) return;
16338
16541
  setInternalCollapsedParentIds(/* @__PURE__ */ new Set());
16339
16542
  setExpandedCompositeIds(new Set(normalizedTasks.filter((task) => task.composite).map((task) => task.id)));
16340
16543
  }, [externalCollapsedParentIds, normalizedTasks]);
16341
- const exportToPdf = useCallback10(async (options) => {
16544
+ const exportToPdf = useCallback11(async (options) => {
16342
16545
  const sourceContainer = containerRef.current;
16343
16546
  if (!sourceContainer || typeof window === "undefined" || typeof document === "undefined") {
16344
16547
  return;
@@ -16411,7 +16614,7 @@ function TaskGanttChartInner(props, ref) {
16411
16614
  }
16412
16615
  return depth;
16413
16616
  }
16414
- const handlePromoteTask = useCallback10((taskId) => {
16617
+ const handlePromoteTask = useCallback11((taskId) => {
16415
16618
  if (onPromoteTask) {
16416
16619
  onPromoteTask(taskId);
16417
16620
  return;
@@ -16443,7 +16646,7 @@ function TaskGanttChartInner(props, ref) {
16443
16646
  ]);
16444
16647
  onTasksChange?.(reorderedTasks);
16445
16648
  }, [tasks, onTasksChange, onPromoteTask]);
16446
- const handleDemoteTask = useCallback10((taskId, newParentId) => {
16649
+ const handleDemoteTask = useCallback11((taskId, newParentId) => {
16447
16650
  if (onDemoteTask) {
16448
16651
  onDemoteTask(taskId, newParentId);
16449
16652
  return;
@@ -16484,7 +16687,7 @@ function TaskGanttChartInner(props, ref) {
16484
16687
  };
16485
16688
  onTasksChange?.([updatedDemotedTask]);
16486
16689
  }, [tasks, onTasksChange, onDemoteTask]);
16487
- const handleUngroupTask = useCallback10((taskId) => {
16690
+ const handleUngroupTask = useCallback11((taskId) => {
16488
16691
  if (onUngroupTask) {
16489
16692
  onUngroupTask(taskId);
16490
16693
  return;
@@ -16509,8 +16712,8 @@ function TaskGanttChartInner(props, ref) {
16509
16712
  onTasksChange?.(changedTasks);
16510
16713
  }
16511
16714
  }, [tasks, onTasksChange, onUngroupTask]);
16512
- const panStateRef = useRef13(null);
16513
- const handlePanStart = useCallback10((e) => {
16715
+ const panStateRef = useRef14(null);
16716
+ const handlePanStart = useCallback11((e) => {
16514
16717
  if (e.button !== 0) return;
16515
16718
  const target = e.target;
16516
16719
  if (!target.closest(".gantt-tr-activityBar")) {
@@ -16534,6 +16737,7 @@ function TaskGanttChartInner(props, ref) {
16534
16737
  if (document.activeElement instanceof HTMLElement) {
16535
16738
  document.activeElement.blur();
16536
16739
  }
16740
+ container.setAttribute("data-panning", "true");
16537
16741
  container.style.cursor = "grabbing";
16538
16742
  e.preventDefault();
16539
16743
  }, [activityActivationStore]);
@@ -16571,7 +16775,10 @@ function TaskGanttChartInner(props, ref) {
16571
16775
  }
16572
16776
  panStateRef.current = null;
16573
16777
  const container = scrollContainerRef.current;
16574
- if (container) container.style.cursor = "";
16778
+ if (container) {
16779
+ container.removeAttribute("data-panning");
16780
+ container.style.cursor = "";
16781
+ }
16575
16782
  };
16576
16783
  window.addEventListener("mousemove", handlePanMove);
16577
16784
  window.addEventListener("mouseup", handlePanEnd);
@@ -16790,7 +16997,7 @@ function TaskGanttChartInner(props, ref) {
16790
16997
  onHoverEnd: () => setActiveTimelineTooltip(null)
16791
16998
  }
16792
16999
  ),
16793
- showActivityLinks && resolvedActivityDependencies.length > 0 && /* @__PURE__ */ jsx22(ActivityDependencyLines, { tasks: visibleTasks, renderedTaskIds: renderedTaskIdsRef.current, dependencies: resolvedActivityDependencies, highlight: activityDependencyHighlight, monthStart, dayWidth, rowHeight: effectiveRowHeight, gridWidth: renderGridWidth, totalHeight: totalGridHeight, rowIndexByTaskId: visibleTaskIndexMap, rowTops: compositeRowLayout.tops, rowHeights: compositeRowLayout.heights, showLag: showActivityLag, previewStore: activityPreviewStore, horizontalWindow }),
17000
+ showActivityLinks && activityDependencies !== void 0 && /* @__PURE__ */ jsx22(ActivityDependencyLines, { tasks: previewVisibleTasks, renderedTaskIds: renderedTaskIdsRef.current, dependencies: activityDependencies, highlight: activityDependencyHighlight, monthStart, dayWidth, rowHeight: effectiveRowHeight, gridWidth: renderGridWidth, totalHeight: totalGridHeight, rowIndexByTaskId: visibleTaskIndexMap, rowTops: compositeRowLayout.tops, rowHeights: compositeRowLayout.heights, showLag: showActivityLag, previewStore: activityPreviewStore, horizontalWindow }),
16794
17001
  /* @__PURE__ */ jsx22(
16795
17002
  DependencyLines_default,
16796
17003
  {
@@ -16933,10 +17140,10 @@ function TaskGanttChartInner(props, ref) {
16933
17140
  activityActivationStore,
16934
17141
  activityClickToDrag,
16935
17142
  activityActivationMode,
16936
- showActivityLinks: false,
17143
+ showActivityLinks: showActivityLinks && activityDependencies === void 0,
16937
17144
  showActivityLag,
16938
17145
  activityTooltip,
16939
- horizontalWindow,
17146
+ horizontalWindow: forceFullRenderForPrint ? void 0 : horizontalWindow,
16940
17147
  onCascadeProgress: handleCascadeProgress,
16941
17148
  onCascade: handleCascade,
16942
17149
  onScheduleIntent,