gantt-task-react-v 1.3.6 → 1.4.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/gantt-task-react.es.js +178 -77
- package/dist/gantt-task-react.umd.js +178 -77
- package/dist/types/public-types.d.ts +10 -0
- package/package.json +1 -1
|
@@ -4688,9 +4688,9 @@ const getStartAndEnd = (containerEl, property, cellSize) => {
|
|
|
4688
4688
|
const scrollValue = property === "scrollLeft" ? el.scrollLeft : el.scrollTop;
|
|
4689
4689
|
const maxScrollValue = property === "scrollLeft" ? el.scrollWidth : el.scrollHeight;
|
|
4690
4690
|
const fullValue = property === "scrollLeft" ? el.clientWidth : el.clientHeight;
|
|
4691
|
-
const firstIndex = Math.max(0, Math.floor(scrollValue / cellSize));
|
|
4692
4691
|
const visibleCount = Math.max(1, Math.ceil(fullValue / cellSize));
|
|
4693
4692
|
const overscan = Math.min(100, Math.max(10, Math.ceil(visibleCount * 0.5)));
|
|
4693
|
+
const firstIndex = Math.max(0, Math.floor(scrollValue / cellSize) - overscan);
|
|
4694
4694
|
const lastIndex = Math.floor((scrollValue + fullValue) / cellSize) + overscan;
|
|
4695
4695
|
const isStartOfScroll = scrollValue < DELTA;
|
|
4696
4696
|
const isEndOfScroll = scrollValue + fullValue > maxScrollValue - DELTA;
|
|
@@ -5536,6 +5536,37 @@ const TaskListTableHeadersDefaultInner = ({
|
|
|
5536
5536
|
canMoveTasks,
|
|
5537
5537
|
onColumnResizeStart
|
|
5538
5538
|
}) => {
|
|
5539
|
+
const pinnedStyles = useMemo(() => {
|
|
5540
|
+
const result = {};
|
|
5541
|
+
let leftOffset = 0;
|
|
5542
|
+
if (canMoveTasks) {
|
|
5543
|
+
leftOffset = 24;
|
|
5544
|
+
}
|
|
5545
|
+
for (let i = 0; i < columns.length; i++) {
|
|
5546
|
+
if (columns[i].pinned === "left") {
|
|
5547
|
+
result[i] = {
|
|
5548
|
+
position: "sticky",
|
|
5549
|
+
left: leftOffset,
|
|
5550
|
+
zIndex: 2,
|
|
5551
|
+
backgroundColor: "var(--gantt-table-header-background-color, #fff)"
|
|
5552
|
+
};
|
|
5553
|
+
leftOffset += columns[i].width;
|
|
5554
|
+
}
|
|
5555
|
+
}
|
|
5556
|
+
let rightOffset = 0;
|
|
5557
|
+
for (let i = columns.length - 1; i >= 0; i--) {
|
|
5558
|
+
if (columns[i].pinned === "right") {
|
|
5559
|
+
result[i] = {
|
|
5560
|
+
position: "sticky",
|
|
5561
|
+
right: rightOffset,
|
|
5562
|
+
zIndex: 2,
|
|
5563
|
+
backgroundColor: "var(--gantt-table-header-background-color, #fff)"
|
|
5564
|
+
};
|
|
5565
|
+
rightOffset += columns[i].width;
|
|
5566
|
+
}
|
|
5567
|
+
}
|
|
5568
|
+
return result;
|
|
5569
|
+
}, [columns, canMoveTasks]);
|
|
5539
5570
|
return /* @__PURE__ */ jsx(
|
|
5540
5571
|
"div",
|
|
5541
5572
|
{
|
|
@@ -5572,7 +5603,8 @@ const TaskListTableHeadersDefaultInner = ({
|
|
|
5572
5603
|
className: styles$h.ganttTable_HeaderItem,
|
|
5573
5604
|
style: {
|
|
5574
5605
|
minWidth: width,
|
|
5575
|
-
maxWidth: width
|
|
5606
|
+
maxWidth: width,
|
|
5607
|
+
...pinnedStyles[index2]
|
|
5576
5608
|
},
|
|
5577
5609
|
children: [
|
|
5578
5610
|
title,
|
|
@@ -10135,6 +10167,37 @@ const TaskListTableRowInner = forwardRef(
|
|
|
10135
10167
|
}
|
|
10136
10168
|
return classNames.join(" ");
|
|
10137
10169
|
}, [isCut2, moveOverPosition, isOverlay2, isDragging]);
|
|
10170
|
+
const pinnedStyles = useMemo(() => {
|
|
10171
|
+
const result = {};
|
|
10172
|
+
let leftOffset = 0;
|
|
10173
|
+
if (moveHandleProps || !isOverlay2 && task.type !== "project" && task.id !== "no-project-asigned") {
|
|
10174
|
+
leftOffset = 24;
|
|
10175
|
+
}
|
|
10176
|
+
for (let i = 0; i < columns.length; i++) {
|
|
10177
|
+
if (columns[i].pinned === "left") {
|
|
10178
|
+
result[i] = {
|
|
10179
|
+
position: "sticky",
|
|
10180
|
+
left: leftOffset,
|
|
10181
|
+
zIndex: 1,
|
|
10182
|
+
backgroundColor: "inherit"
|
|
10183
|
+
};
|
|
10184
|
+
leftOffset += columns[i].width;
|
|
10185
|
+
}
|
|
10186
|
+
}
|
|
10187
|
+
let rightOffset = 0;
|
|
10188
|
+
for (let i = columns.length - 1; i >= 0; i--) {
|
|
10189
|
+
if (columns[i].pinned === "right") {
|
|
10190
|
+
result[i] = {
|
|
10191
|
+
position: "sticky",
|
|
10192
|
+
right: rightOffset,
|
|
10193
|
+
zIndex: 1,
|
|
10194
|
+
backgroundColor: "inherit"
|
|
10195
|
+
};
|
|
10196
|
+
rightOffset += columns[i].width;
|
|
10197
|
+
}
|
|
10198
|
+
}
|
|
10199
|
+
return result;
|
|
10200
|
+
}, [columns, moveHandleProps, isOverlay2, task.type, task.id]);
|
|
10138
10201
|
return /* @__PURE__ */ jsxs(
|
|
10139
10202
|
"div",
|
|
10140
10203
|
{
|
|
@@ -10156,7 +10219,8 @@ const TaskListTableRowInner = forwardRef(
|
|
|
10156
10219
|
className: styles$f.taskListCell,
|
|
10157
10220
|
style: {
|
|
10158
10221
|
minWidth: width,
|
|
10159
|
-
maxWidth: width
|
|
10222
|
+
maxWidth: width,
|
|
10223
|
+
...pinnedStyles[index2]
|
|
10160
10224
|
},
|
|
10161
10225
|
children: /* @__PURE__ */ jsx(Component, { data: columnData })
|
|
10162
10226
|
},
|
|
@@ -13115,19 +13179,73 @@ const TaskGanttContentInner = (props) => {
|
|
|
13115
13179
|
const safeProgressWidth = isNaN(progressWidth) || !isFinite(progressWidth) ? 0 : Math.max(progressWidth, 0);
|
|
13116
13180
|
const safeInnerX1 = isNaN(innerX1) || !isFinite(innerX1) ? 0 : innerX1;
|
|
13117
13181
|
const safeInnerX2 = isNaN(innerX2) || !isFinite(innerX2) ? safeInnerX1 + safeWidth : innerX2;
|
|
13118
|
-
|
|
13182
|
+
tasksRes.push(
|
|
13183
|
+
/* @__PURE__ */ jsx(
|
|
13184
|
+
"svg",
|
|
13185
|
+
{
|
|
13186
|
+
id: task.id,
|
|
13187
|
+
className: `${styles$4.TaskItemWrapper} TaskItemWrapper`,
|
|
13188
|
+
x: Math.max(safeContainerX + (additionalLeftSpace || 0), 0),
|
|
13189
|
+
y: safeLevelY,
|
|
13190
|
+
width: Math.max(safeContainerWidth, 0),
|
|
13191
|
+
height: fullRowHeight,
|
|
13192
|
+
children: /* @__PURE__ */ jsx(
|
|
13193
|
+
TaskItem,
|
|
13194
|
+
{
|
|
13195
|
+
movingAction: taskBarMovingAction(task),
|
|
13196
|
+
allowMoveTaskBar,
|
|
13197
|
+
hasChildren: checkHasChildren(task, childTasksMap),
|
|
13198
|
+
progressWidth: safeProgressWidth,
|
|
13199
|
+
progressX: rtl ? safeInnerX2 : safeInnerX1,
|
|
13200
|
+
onSelectTaskOnMouseDown: selectTaskOnMouseDown,
|
|
13201
|
+
task,
|
|
13202
|
+
taskYOffset,
|
|
13203
|
+
width: safeWidth,
|
|
13204
|
+
x1: safeInnerX1,
|
|
13205
|
+
x2: safeInnerX2,
|
|
13206
|
+
distances,
|
|
13207
|
+
taskHeight,
|
|
13208
|
+
taskHalfHeight,
|
|
13209
|
+
isProgressChangeable: (t) => isProgressChangeable(t) && !waitCommitTasks,
|
|
13210
|
+
isDateChangeable: (t) => isDateChangeable(t) && !waitCommitTasks,
|
|
13211
|
+
isRelationChangeable: (t) => isRelationChangeable(t) && !waitCommitTasks,
|
|
13212
|
+
authorizedRelations,
|
|
13213
|
+
ganttRelationEvent,
|
|
13214
|
+
canDelete: !task.isDisabled && !waitCommitTasks,
|
|
13215
|
+
onDoubleClick,
|
|
13216
|
+
onClick,
|
|
13217
|
+
onEventStart: onTaskBarDragStart,
|
|
13218
|
+
onTooltipTask,
|
|
13219
|
+
onRelationStart: onTaskBarRelationStart,
|
|
13220
|
+
isSelected: Boolean(selectedIdsMirror[taskId]),
|
|
13221
|
+
isCritical,
|
|
13222
|
+
rtl,
|
|
13223
|
+
onDeleteTask,
|
|
13224
|
+
renderCustomLabel,
|
|
13225
|
+
viewMode,
|
|
13226
|
+
showProgress,
|
|
13227
|
+
progressColor
|
|
13228
|
+
}
|
|
13229
|
+
)
|
|
13230
|
+
},
|
|
13231
|
+
key2
|
|
13232
|
+
)
|
|
13233
|
+
);
|
|
13119
13234
|
if (task.comparisonDates && comparisonDates) {
|
|
13120
13235
|
const safeComparisonX = isNaN(comparisonDates.x) || !isFinite(comparisonDates.x) ? 0 : comparisonDates.x;
|
|
13121
|
-
const
|
|
13122
|
-
const
|
|
13123
|
-
const
|
|
13124
|
-
|
|
13125
|
-
|
|
13126
|
-
|
|
13127
|
-
comparisonBarElement = /* @__PURE__ */ jsx(
|
|
13128
|
-
"g",
|
|
13236
|
+
const safeComparisonY = isNaN(comparisonDates.y) || !isFinite(comparisonDates.y) ? safeLevelY : comparisonDates.y;
|
|
13237
|
+
const safeComparisonWidth = isNaN(comparisonDates.width) || !isFinite(comparisonDates.width) ? 0 : Math.max(comparisonDates.width, 0);
|
|
13238
|
+
const safeComparisonHeight = isNaN(comparisonDates.height) || !isFinite(comparisonDates.height) ? 0 : Math.max(comparisonDates.height, 0);
|
|
13239
|
+
tasksRes.push(
|
|
13240
|
+
/* @__PURE__ */ jsx(
|
|
13241
|
+
"svg",
|
|
13129
13242
|
{
|
|
13130
|
-
|
|
13243
|
+
id: task.id + "_comparison",
|
|
13244
|
+
className: "TaskItemWrapperComparison",
|
|
13245
|
+
x: Math.max(safeComparisonX + (additionalLeftSpace || 0), 0),
|
|
13246
|
+
y: safeComparisonY,
|
|
13247
|
+
width: safeComparisonWidth,
|
|
13248
|
+
height: safeComparisonHeight * 2,
|
|
13131
13249
|
children: /* @__PURE__ */ jsx(
|
|
13132
13250
|
BarComparison,
|
|
13133
13251
|
{
|
|
@@ -13139,70 +13257,16 @@ const TaskGanttContentInner = (props) => {
|
|
|
13139
13257
|
height: safeComparisonHeight,
|
|
13140
13258
|
width: safeComparisonWidth,
|
|
13141
13259
|
borderHeight: distances.barComparisonTaskBorderHeight,
|
|
13142
|
-
yOffset:
|
|
13260
|
+
yOffset: distances.barComparisonTaskYOffset,
|
|
13143
13261
|
task,
|
|
13144
13262
|
onTooltipTask
|
|
13145
13263
|
}
|
|
13146
13264
|
)
|
|
13147
|
-
}
|
|
13148
|
-
|
|
13149
|
-
|
|
13265
|
+
},
|
|
13266
|
+
key2 + "_comparison"
|
|
13267
|
+
)
|
|
13268
|
+
);
|
|
13150
13269
|
}
|
|
13151
|
-
tasksRes.push(
|
|
13152
|
-
/* @__PURE__ */ jsxs(
|
|
13153
|
-
"svg",
|
|
13154
|
-
{
|
|
13155
|
-
id: task.id,
|
|
13156
|
-
className: `${styles$4.TaskItemWrapper} TaskItemWrapper`,
|
|
13157
|
-
x: Math.max(safeContainerX + (additionalLeftSpace || 0), 0),
|
|
13158
|
-
y: safeLevelY,
|
|
13159
|
-
width: Math.max(safeContainerWidth, 0),
|
|
13160
|
-
height: fullRowHeight,
|
|
13161
|
-
children: [
|
|
13162
|
-
/* @__PURE__ */ jsx(
|
|
13163
|
-
TaskItem,
|
|
13164
|
-
{
|
|
13165
|
-
movingAction: taskBarMovingAction(task),
|
|
13166
|
-
allowMoveTaskBar,
|
|
13167
|
-
hasChildren: checkHasChildren(task, childTasksMap),
|
|
13168
|
-
progressWidth: safeProgressWidth,
|
|
13169
|
-
progressX: rtl ? safeInnerX2 : safeInnerX1,
|
|
13170
|
-
onSelectTaskOnMouseDown: selectTaskOnMouseDown,
|
|
13171
|
-
task,
|
|
13172
|
-
taskYOffset,
|
|
13173
|
-
width: safeWidth,
|
|
13174
|
-
x1: safeInnerX1,
|
|
13175
|
-
x2: safeInnerX2,
|
|
13176
|
-
distances,
|
|
13177
|
-
taskHeight,
|
|
13178
|
-
taskHalfHeight,
|
|
13179
|
-
isProgressChangeable: (t) => isProgressChangeable(t) && !waitCommitTasks,
|
|
13180
|
-
isDateChangeable: (t) => isDateChangeable(t) && !waitCommitTasks,
|
|
13181
|
-
isRelationChangeable: (t) => isRelationChangeable(t) && !waitCommitTasks,
|
|
13182
|
-
authorizedRelations,
|
|
13183
|
-
ganttRelationEvent,
|
|
13184
|
-
canDelete: !task.isDisabled && !waitCommitTasks,
|
|
13185
|
-
onDoubleClick,
|
|
13186
|
-
onClick,
|
|
13187
|
-
onEventStart: onTaskBarDragStart,
|
|
13188
|
-
onTooltipTask,
|
|
13189
|
-
onRelationStart: onTaskBarRelationStart,
|
|
13190
|
-
isSelected: Boolean(selectedIdsMirror[taskId]),
|
|
13191
|
-
isCritical,
|
|
13192
|
-
rtl,
|
|
13193
|
-
onDeleteTask,
|
|
13194
|
-
renderCustomLabel,
|
|
13195
|
-
viewMode,
|
|
13196
|
-
showProgress,
|
|
13197
|
-
progressColor
|
|
13198
|
-
}
|
|
13199
|
-
),
|
|
13200
|
-
comparisonBarElement
|
|
13201
|
-
]
|
|
13202
|
-
},
|
|
13203
|
-
key2
|
|
13204
|
-
)
|
|
13205
|
-
);
|
|
13206
13270
|
const addedDependenciesAtLevel = addedDependencies[comparisonLevel] || {};
|
|
13207
13271
|
if (!addedDependencies[comparisonLevel]) {
|
|
13208
13272
|
addedDependencies[comparisonLevel] = addedDependenciesAtLevel;
|
|
@@ -13860,12 +13924,10 @@ const countTaskCoordinates = (task, taskToRowIndexMap, startDate, viewMode, rtl,
|
|
|
13860
13924
|
);
|
|
13861
13925
|
cx1 = isNaN(cx1) || !isFinite(cx1) ? x1 : cx1;
|
|
13862
13926
|
cx2 = isNaN(cx2) || !isFinite(cx2) ? x2 : cx2;
|
|
13863
|
-
const comparisonWidth = Math.max(Math.abs(cx2 - cx1), 3);
|
|
13864
|
-
const comparisonX = Math.min(cx1, cx2);
|
|
13865
13927
|
comparisonDates = {
|
|
13866
|
-
x:
|
|
13928
|
+
x: cx1,
|
|
13867
13929
|
y: y + taskHeight,
|
|
13868
|
-
width:
|
|
13930
|
+
width: Math.max(cx2 - cx1, 0),
|
|
13869
13931
|
height: barComparisonTaskHeight
|
|
13870
13932
|
};
|
|
13871
13933
|
}
|
|
@@ -19059,7 +19121,8 @@ const Gantt = (props) => {
|
|
|
19059
19121
|
todayLabel = "Today",
|
|
19060
19122
|
dataDateLabel = "Data Date",
|
|
19061
19123
|
showProgress = true,
|
|
19062
|
-
progressColor
|
|
19124
|
+
progressColor,
|
|
19125
|
+
scrollToTaskId
|
|
19063
19126
|
} = props;
|
|
19064
19127
|
const ganttSVGRef = useRef(null);
|
|
19065
19128
|
const wrapperRef = useRef(null);
|
|
@@ -19367,6 +19430,44 @@ const Gantt = (props) => {
|
|
|
19367
19430
|
},
|
|
19368
19431
|
[mapTaskToCoordinates, setScrollXProgrammatically]
|
|
19369
19432
|
);
|
|
19433
|
+
const prevScrollToTaskIdRef = useRef(void 0);
|
|
19434
|
+
useEffect(() => {
|
|
19435
|
+
if (!scrollToTaskId || scrollToTaskId === prevScrollToTaskIdRef.current) {
|
|
19436
|
+
return;
|
|
19437
|
+
}
|
|
19438
|
+
prevScrollToTaskIdRef.current = scrollToTaskId;
|
|
19439
|
+
for (const [comparisonLevel, levelMap] of tasksMap) {
|
|
19440
|
+
const task = levelMap.get(scrollToTaskId);
|
|
19441
|
+
if (!task || task.type === "empty") {
|
|
19442
|
+
continue;
|
|
19443
|
+
}
|
|
19444
|
+
const { x1 } = getTaskCoordinates(task, mapTaskToCoordinates);
|
|
19445
|
+
setScrollXProgrammatically(Math.max(0, x1 - 100));
|
|
19446
|
+
const rowIndexMap = taskToRowIndexMap.get(comparisonLevel);
|
|
19447
|
+
if (rowIndexMap) {
|
|
19448
|
+
const rowIndex = rowIndexMap.get(scrollToTaskId);
|
|
19449
|
+
if (typeof rowIndex === "number") {
|
|
19450
|
+
const targetScrollY = rowIndex * fullRowHeight - ganttHeight / 2 + fullRowHeight / 2;
|
|
19451
|
+
setScrollYProgrammatically(
|
|
19452
|
+
Math.max(0, Math.min(targetScrollY, ganttFullHeight - ganttHeight))
|
|
19453
|
+
);
|
|
19454
|
+
}
|
|
19455
|
+
}
|
|
19456
|
+
selectTask(scrollToTaskId);
|
|
19457
|
+
break;
|
|
19458
|
+
}
|
|
19459
|
+
}, [
|
|
19460
|
+
scrollToTaskId,
|
|
19461
|
+
tasksMap,
|
|
19462
|
+
mapTaskToCoordinates,
|
|
19463
|
+
taskToRowIndexMap,
|
|
19464
|
+
fullRowHeight,
|
|
19465
|
+
ganttHeight,
|
|
19466
|
+
ganttFullHeight,
|
|
19467
|
+
setScrollXProgrammatically,
|
|
19468
|
+
setScrollYProgrammatically,
|
|
19469
|
+
selectTask
|
|
19470
|
+
]);
|
|
19370
19471
|
const { contextMenu, handleCloseContextMenu, handleOpenContextMenu } = useContextMenu(wrapperRef, scrollToTask);
|
|
19371
19472
|
const [ganttContextMenu, setGanttContextMenu] = useState({
|
|
19372
19473
|
task: null,
|
|
@@ -4705,9 +4705,9 @@
|
|
|
4705
4705
|
const scrollValue = property === "scrollLeft" ? el.scrollLeft : el.scrollTop;
|
|
4706
4706
|
const maxScrollValue = property === "scrollLeft" ? el.scrollWidth : el.scrollHeight;
|
|
4707
4707
|
const fullValue = property === "scrollLeft" ? el.clientWidth : el.clientHeight;
|
|
4708
|
-
const firstIndex = Math.max(0, Math.floor(scrollValue / cellSize));
|
|
4709
4708
|
const visibleCount = Math.max(1, Math.ceil(fullValue / cellSize));
|
|
4710
4709
|
const overscan = Math.min(100, Math.max(10, Math.ceil(visibleCount * 0.5)));
|
|
4710
|
+
const firstIndex = Math.max(0, Math.floor(scrollValue / cellSize) - overscan);
|
|
4711
4711
|
const lastIndex = Math.floor((scrollValue + fullValue) / cellSize) + overscan;
|
|
4712
4712
|
const isStartOfScroll = scrollValue < DELTA;
|
|
4713
4713
|
const isEndOfScroll = scrollValue + fullValue > maxScrollValue - DELTA;
|
|
@@ -5553,6 +5553,37 @@
|
|
|
5553
5553
|
canMoveTasks,
|
|
5554
5554
|
onColumnResizeStart
|
|
5555
5555
|
}) => {
|
|
5556
|
+
const pinnedStyles = React.useMemo(() => {
|
|
5557
|
+
const result = {};
|
|
5558
|
+
let leftOffset = 0;
|
|
5559
|
+
if (canMoveTasks) {
|
|
5560
|
+
leftOffset = 24;
|
|
5561
|
+
}
|
|
5562
|
+
for (let i = 0; i < columns.length; i++) {
|
|
5563
|
+
if (columns[i].pinned === "left") {
|
|
5564
|
+
result[i] = {
|
|
5565
|
+
position: "sticky",
|
|
5566
|
+
left: leftOffset,
|
|
5567
|
+
zIndex: 2,
|
|
5568
|
+
backgroundColor: "var(--gantt-table-header-background-color, #fff)"
|
|
5569
|
+
};
|
|
5570
|
+
leftOffset += columns[i].width;
|
|
5571
|
+
}
|
|
5572
|
+
}
|
|
5573
|
+
let rightOffset = 0;
|
|
5574
|
+
for (let i = columns.length - 1; i >= 0; i--) {
|
|
5575
|
+
if (columns[i].pinned === "right") {
|
|
5576
|
+
result[i] = {
|
|
5577
|
+
position: "sticky",
|
|
5578
|
+
right: rightOffset,
|
|
5579
|
+
zIndex: 2,
|
|
5580
|
+
backgroundColor: "var(--gantt-table-header-background-color, #fff)"
|
|
5581
|
+
};
|
|
5582
|
+
rightOffset += columns[i].width;
|
|
5583
|
+
}
|
|
5584
|
+
}
|
|
5585
|
+
return result;
|
|
5586
|
+
}, [columns, canMoveTasks]);
|
|
5556
5587
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5557
5588
|
"div",
|
|
5558
5589
|
{
|
|
@@ -5589,7 +5620,8 @@
|
|
|
5589
5620
|
className: styles$h.ganttTable_HeaderItem,
|
|
5590
5621
|
style: {
|
|
5591
5622
|
minWidth: width,
|
|
5592
|
-
maxWidth: width
|
|
5623
|
+
maxWidth: width,
|
|
5624
|
+
...pinnedStyles[index2]
|
|
5593
5625
|
},
|
|
5594
5626
|
children: [
|
|
5595
5627
|
title,
|
|
@@ -10152,6 +10184,37 @@
|
|
|
10152
10184
|
}
|
|
10153
10185
|
return classNames.join(" ");
|
|
10154
10186
|
}, [isCut2, moveOverPosition, isOverlay2, isDragging]);
|
|
10187
|
+
const pinnedStyles = React.useMemo(() => {
|
|
10188
|
+
const result = {};
|
|
10189
|
+
let leftOffset = 0;
|
|
10190
|
+
if (moveHandleProps || !isOverlay2 && task.type !== "project" && task.id !== "no-project-asigned") {
|
|
10191
|
+
leftOffset = 24;
|
|
10192
|
+
}
|
|
10193
|
+
for (let i = 0; i < columns.length; i++) {
|
|
10194
|
+
if (columns[i].pinned === "left") {
|
|
10195
|
+
result[i] = {
|
|
10196
|
+
position: "sticky",
|
|
10197
|
+
left: leftOffset,
|
|
10198
|
+
zIndex: 1,
|
|
10199
|
+
backgroundColor: "inherit"
|
|
10200
|
+
};
|
|
10201
|
+
leftOffset += columns[i].width;
|
|
10202
|
+
}
|
|
10203
|
+
}
|
|
10204
|
+
let rightOffset = 0;
|
|
10205
|
+
for (let i = columns.length - 1; i >= 0; i--) {
|
|
10206
|
+
if (columns[i].pinned === "right") {
|
|
10207
|
+
result[i] = {
|
|
10208
|
+
position: "sticky",
|
|
10209
|
+
right: rightOffset,
|
|
10210
|
+
zIndex: 1,
|
|
10211
|
+
backgroundColor: "inherit"
|
|
10212
|
+
};
|
|
10213
|
+
rightOffset += columns[i].width;
|
|
10214
|
+
}
|
|
10215
|
+
}
|
|
10216
|
+
return result;
|
|
10217
|
+
}, [columns, moveHandleProps, isOverlay2, task.type, task.id]);
|
|
10155
10218
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
10156
10219
|
"div",
|
|
10157
10220
|
{
|
|
@@ -10173,7 +10236,8 @@
|
|
|
10173
10236
|
className: styles$f.taskListCell,
|
|
10174
10237
|
style: {
|
|
10175
10238
|
minWidth: width,
|
|
10176
|
-
maxWidth: width
|
|
10239
|
+
maxWidth: width,
|
|
10240
|
+
...pinnedStyles[index2]
|
|
10177
10241
|
},
|
|
10178
10242
|
children: /* @__PURE__ */ jsxRuntime.jsx(Component, { data: columnData })
|
|
10179
10243
|
},
|
|
@@ -13132,19 +13196,73 @@
|
|
|
13132
13196
|
const safeProgressWidth = isNaN(progressWidth) || !isFinite(progressWidth) ? 0 : Math.max(progressWidth, 0);
|
|
13133
13197
|
const safeInnerX1 = isNaN(innerX1) || !isFinite(innerX1) ? 0 : innerX1;
|
|
13134
13198
|
const safeInnerX2 = isNaN(innerX2) || !isFinite(innerX2) ? safeInnerX1 + safeWidth : innerX2;
|
|
13135
|
-
|
|
13199
|
+
tasksRes.push(
|
|
13200
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
13201
|
+
"svg",
|
|
13202
|
+
{
|
|
13203
|
+
id: task.id,
|
|
13204
|
+
className: `${styles$4.TaskItemWrapper} TaskItemWrapper`,
|
|
13205
|
+
x: Math.max(safeContainerX + (additionalLeftSpace || 0), 0),
|
|
13206
|
+
y: safeLevelY,
|
|
13207
|
+
width: Math.max(safeContainerWidth, 0),
|
|
13208
|
+
height: fullRowHeight,
|
|
13209
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
13210
|
+
TaskItem,
|
|
13211
|
+
{
|
|
13212
|
+
movingAction: taskBarMovingAction(task),
|
|
13213
|
+
allowMoveTaskBar,
|
|
13214
|
+
hasChildren: checkHasChildren(task, childTasksMap),
|
|
13215
|
+
progressWidth: safeProgressWidth,
|
|
13216
|
+
progressX: rtl ? safeInnerX2 : safeInnerX1,
|
|
13217
|
+
onSelectTaskOnMouseDown: selectTaskOnMouseDown,
|
|
13218
|
+
task,
|
|
13219
|
+
taskYOffset,
|
|
13220
|
+
width: safeWidth,
|
|
13221
|
+
x1: safeInnerX1,
|
|
13222
|
+
x2: safeInnerX2,
|
|
13223
|
+
distances,
|
|
13224
|
+
taskHeight,
|
|
13225
|
+
taskHalfHeight,
|
|
13226
|
+
isProgressChangeable: (t) => isProgressChangeable(t) && !waitCommitTasks,
|
|
13227
|
+
isDateChangeable: (t) => isDateChangeable(t) && !waitCommitTasks,
|
|
13228
|
+
isRelationChangeable: (t) => isRelationChangeable(t) && !waitCommitTasks,
|
|
13229
|
+
authorizedRelations,
|
|
13230
|
+
ganttRelationEvent,
|
|
13231
|
+
canDelete: !task.isDisabled && !waitCommitTasks,
|
|
13232
|
+
onDoubleClick,
|
|
13233
|
+
onClick,
|
|
13234
|
+
onEventStart: onTaskBarDragStart,
|
|
13235
|
+
onTooltipTask,
|
|
13236
|
+
onRelationStart: onTaskBarRelationStart,
|
|
13237
|
+
isSelected: Boolean(selectedIdsMirror[taskId]),
|
|
13238
|
+
isCritical,
|
|
13239
|
+
rtl,
|
|
13240
|
+
onDeleteTask,
|
|
13241
|
+
renderCustomLabel,
|
|
13242
|
+
viewMode,
|
|
13243
|
+
showProgress,
|
|
13244
|
+
progressColor
|
|
13245
|
+
}
|
|
13246
|
+
)
|
|
13247
|
+
},
|
|
13248
|
+
key2
|
|
13249
|
+
)
|
|
13250
|
+
);
|
|
13136
13251
|
if (task.comparisonDates && comparisonDates) {
|
|
13137
13252
|
const safeComparisonX = isNaN(comparisonDates.x) || !isFinite(comparisonDates.x) ? 0 : comparisonDates.x;
|
|
13138
|
-
const
|
|
13139
|
-
const
|
|
13140
|
-
const
|
|
13141
|
-
|
|
13142
|
-
|
|
13143
|
-
|
|
13144
|
-
comparisonBarElement = /* @__PURE__ */ jsxRuntime.jsx(
|
|
13145
|
-
"g",
|
|
13253
|
+
const safeComparisonY = isNaN(comparisonDates.y) || !isFinite(comparisonDates.y) ? safeLevelY : comparisonDates.y;
|
|
13254
|
+
const safeComparisonWidth = isNaN(comparisonDates.width) || !isFinite(comparisonDates.width) ? 0 : Math.max(comparisonDates.width, 0);
|
|
13255
|
+
const safeComparisonHeight = isNaN(comparisonDates.height) || !isFinite(comparisonDates.height) ? 0 : Math.max(comparisonDates.height, 0);
|
|
13256
|
+
tasksRes.push(
|
|
13257
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
13258
|
+
"svg",
|
|
13146
13259
|
{
|
|
13147
|
-
|
|
13260
|
+
id: task.id + "_comparison",
|
|
13261
|
+
className: "TaskItemWrapperComparison",
|
|
13262
|
+
x: Math.max(safeComparisonX + (additionalLeftSpace || 0), 0),
|
|
13263
|
+
y: safeComparisonY,
|
|
13264
|
+
width: safeComparisonWidth,
|
|
13265
|
+
height: safeComparisonHeight * 2,
|
|
13148
13266
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
13149
13267
|
BarComparison,
|
|
13150
13268
|
{
|
|
@@ -13156,70 +13274,16 @@
|
|
|
13156
13274
|
height: safeComparisonHeight,
|
|
13157
13275
|
width: safeComparisonWidth,
|
|
13158
13276
|
borderHeight: distances.barComparisonTaskBorderHeight,
|
|
13159
|
-
yOffset:
|
|
13277
|
+
yOffset: distances.barComparisonTaskYOffset,
|
|
13160
13278
|
task,
|
|
13161
13279
|
onTooltipTask
|
|
13162
13280
|
}
|
|
13163
13281
|
)
|
|
13164
|
-
}
|
|
13165
|
-
|
|
13166
|
-
|
|
13282
|
+
},
|
|
13283
|
+
key2 + "_comparison"
|
|
13284
|
+
)
|
|
13285
|
+
);
|
|
13167
13286
|
}
|
|
13168
|
-
tasksRes.push(
|
|
13169
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
13170
|
-
"svg",
|
|
13171
|
-
{
|
|
13172
|
-
id: task.id,
|
|
13173
|
-
className: `${styles$4.TaskItemWrapper} TaskItemWrapper`,
|
|
13174
|
-
x: Math.max(safeContainerX + (additionalLeftSpace || 0), 0),
|
|
13175
|
-
y: safeLevelY,
|
|
13176
|
-
width: Math.max(safeContainerWidth, 0),
|
|
13177
|
-
height: fullRowHeight,
|
|
13178
|
-
children: [
|
|
13179
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
13180
|
-
TaskItem,
|
|
13181
|
-
{
|
|
13182
|
-
movingAction: taskBarMovingAction(task),
|
|
13183
|
-
allowMoveTaskBar,
|
|
13184
|
-
hasChildren: checkHasChildren(task, childTasksMap),
|
|
13185
|
-
progressWidth: safeProgressWidth,
|
|
13186
|
-
progressX: rtl ? safeInnerX2 : safeInnerX1,
|
|
13187
|
-
onSelectTaskOnMouseDown: selectTaskOnMouseDown,
|
|
13188
|
-
task,
|
|
13189
|
-
taskYOffset,
|
|
13190
|
-
width: safeWidth,
|
|
13191
|
-
x1: safeInnerX1,
|
|
13192
|
-
x2: safeInnerX2,
|
|
13193
|
-
distances,
|
|
13194
|
-
taskHeight,
|
|
13195
|
-
taskHalfHeight,
|
|
13196
|
-
isProgressChangeable: (t) => isProgressChangeable(t) && !waitCommitTasks,
|
|
13197
|
-
isDateChangeable: (t) => isDateChangeable(t) && !waitCommitTasks,
|
|
13198
|
-
isRelationChangeable: (t) => isRelationChangeable(t) && !waitCommitTasks,
|
|
13199
|
-
authorizedRelations,
|
|
13200
|
-
ganttRelationEvent,
|
|
13201
|
-
canDelete: !task.isDisabled && !waitCommitTasks,
|
|
13202
|
-
onDoubleClick,
|
|
13203
|
-
onClick,
|
|
13204
|
-
onEventStart: onTaskBarDragStart,
|
|
13205
|
-
onTooltipTask,
|
|
13206
|
-
onRelationStart: onTaskBarRelationStart,
|
|
13207
|
-
isSelected: Boolean(selectedIdsMirror[taskId]),
|
|
13208
|
-
isCritical,
|
|
13209
|
-
rtl,
|
|
13210
|
-
onDeleteTask,
|
|
13211
|
-
renderCustomLabel,
|
|
13212
|
-
viewMode,
|
|
13213
|
-
showProgress,
|
|
13214
|
-
progressColor
|
|
13215
|
-
}
|
|
13216
|
-
),
|
|
13217
|
-
comparisonBarElement
|
|
13218
|
-
]
|
|
13219
|
-
},
|
|
13220
|
-
key2
|
|
13221
|
-
)
|
|
13222
|
-
);
|
|
13223
13287
|
const addedDependenciesAtLevel = addedDependencies[comparisonLevel] || {};
|
|
13224
13288
|
if (!addedDependencies[comparisonLevel]) {
|
|
13225
13289
|
addedDependencies[comparisonLevel] = addedDependenciesAtLevel;
|
|
@@ -13877,12 +13941,10 @@
|
|
|
13877
13941
|
);
|
|
13878
13942
|
cx1 = isNaN(cx1) || !isFinite(cx1) ? x1 : cx1;
|
|
13879
13943
|
cx2 = isNaN(cx2) || !isFinite(cx2) ? x2 : cx2;
|
|
13880
|
-
const comparisonWidth = Math.max(Math.abs(cx2 - cx1), 3);
|
|
13881
|
-
const comparisonX = Math.min(cx1, cx2);
|
|
13882
13944
|
comparisonDates = {
|
|
13883
|
-
x:
|
|
13945
|
+
x: cx1,
|
|
13884
13946
|
y: y + taskHeight,
|
|
13885
|
-
width:
|
|
13947
|
+
width: Math.max(cx2 - cx1, 0),
|
|
13886
13948
|
height: barComparisonTaskHeight
|
|
13887
13949
|
};
|
|
13888
13950
|
}
|
|
@@ -19076,7 +19138,8 @@
|
|
|
19076
19138
|
todayLabel = "Today",
|
|
19077
19139
|
dataDateLabel = "Data Date",
|
|
19078
19140
|
showProgress = true,
|
|
19079
|
-
progressColor
|
|
19141
|
+
progressColor,
|
|
19142
|
+
scrollToTaskId
|
|
19080
19143
|
} = props;
|
|
19081
19144
|
const ganttSVGRef = React.useRef(null);
|
|
19082
19145
|
const wrapperRef = React.useRef(null);
|
|
@@ -19384,6 +19447,44 @@
|
|
|
19384
19447
|
},
|
|
19385
19448
|
[mapTaskToCoordinates, setScrollXProgrammatically]
|
|
19386
19449
|
);
|
|
19450
|
+
const prevScrollToTaskIdRef = React.useRef(void 0);
|
|
19451
|
+
React.useEffect(() => {
|
|
19452
|
+
if (!scrollToTaskId || scrollToTaskId === prevScrollToTaskIdRef.current) {
|
|
19453
|
+
return;
|
|
19454
|
+
}
|
|
19455
|
+
prevScrollToTaskIdRef.current = scrollToTaskId;
|
|
19456
|
+
for (const [comparisonLevel, levelMap] of tasksMap) {
|
|
19457
|
+
const task = levelMap.get(scrollToTaskId);
|
|
19458
|
+
if (!task || task.type === "empty") {
|
|
19459
|
+
continue;
|
|
19460
|
+
}
|
|
19461
|
+
const { x1 } = getTaskCoordinates(task, mapTaskToCoordinates);
|
|
19462
|
+
setScrollXProgrammatically(Math.max(0, x1 - 100));
|
|
19463
|
+
const rowIndexMap = taskToRowIndexMap.get(comparisonLevel);
|
|
19464
|
+
if (rowIndexMap) {
|
|
19465
|
+
const rowIndex = rowIndexMap.get(scrollToTaskId);
|
|
19466
|
+
if (typeof rowIndex === "number") {
|
|
19467
|
+
const targetScrollY = rowIndex * fullRowHeight - ganttHeight / 2 + fullRowHeight / 2;
|
|
19468
|
+
setScrollYProgrammatically(
|
|
19469
|
+
Math.max(0, Math.min(targetScrollY, ganttFullHeight - ganttHeight))
|
|
19470
|
+
);
|
|
19471
|
+
}
|
|
19472
|
+
}
|
|
19473
|
+
selectTask(scrollToTaskId);
|
|
19474
|
+
break;
|
|
19475
|
+
}
|
|
19476
|
+
}, [
|
|
19477
|
+
scrollToTaskId,
|
|
19478
|
+
tasksMap,
|
|
19479
|
+
mapTaskToCoordinates,
|
|
19480
|
+
taskToRowIndexMap,
|
|
19481
|
+
fullRowHeight,
|
|
19482
|
+
ganttHeight,
|
|
19483
|
+
ganttFullHeight,
|
|
19484
|
+
setScrollXProgrammatically,
|
|
19485
|
+
setScrollYProgrammatically,
|
|
19486
|
+
selectTask
|
|
19487
|
+
]);
|
|
19387
19488
|
const { contextMenu, handleCloseContextMenu, handleOpenContextMenu } = useContextMenu(wrapperRef, scrollToTask);
|
|
19388
19489
|
const [ganttContextMenu, setGanttContextMenu] = React.useState({
|
|
19389
19490
|
task: null,
|
|
@@ -368,6 +368,11 @@ export interface GanttProps {
|
|
|
368
368
|
* Custom color for progress bars. If not provided, theme progress colors are used.
|
|
369
369
|
*/
|
|
370
370
|
progressColor?: string;
|
|
371
|
+
/**
|
|
372
|
+
* When set (or changed), the gantt will scroll to reveal and select this task.
|
|
373
|
+
* Set to a task id to scroll both horizontally and vertically to that task.
|
|
374
|
+
*/
|
|
375
|
+
scrollToTaskId?: TaskId;
|
|
371
376
|
}
|
|
372
377
|
export interface GanttTaskBarActions {
|
|
373
378
|
allowMoveTaskBar?: (action: TaskBarMoveAction, task: RenderTask) => boolean;
|
|
@@ -397,6 +402,11 @@ export type Column = {
|
|
|
397
402
|
width: number;
|
|
398
403
|
title?: ReactNode;
|
|
399
404
|
canResize?: boolean;
|
|
405
|
+
/**
|
|
406
|
+
* Pin column to the left or right side of the table.
|
|
407
|
+
* Pinned columns stay visible while scrolling horizontally.
|
|
408
|
+
*/
|
|
409
|
+
pinned?: "left" | "right";
|
|
400
410
|
};
|
|
401
411
|
export type OnResizeColumn = (nextColumns: readonly Column[], columnIndex: number, deltaWidth: number) => void;
|
|
402
412
|
export type ChangeAction = {
|
package/package.json
CHANGED