gantt-lib 0.62.0 → 0.64.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.js CHANGED
@@ -4641,12 +4641,11 @@ var TaskListRow = import_react10.default.memo(
4641
4641
  }, [editingTaskId, task.id, disableTaskNameEditing]);
4642
4642
  const handleNameClick = (0, import_react10.useCallback)(
4643
4643
  (e) => {
4644
- if (disableTaskNameEditing) return;
4645
4644
  e.stopPropagation();
4646
4645
  onRowClick?.(task.id);
4647
4646
  onScrollToTask?.(task.id);
4648
4647
  },
4649
- [task.id, disableTaskNameEditing, onRowClick, onScrollToTask]
4648
+ [task.id, onRowClick, onScrollToTask]
4650
4649
  );
4651
4650
  const handleNameDoubleClick = (0, import_react10.useCallback)(
4652
4651
  (e) => {
@@ -5433,7 +5432,8 @@ var TaskListRow = import_react10.default.memo(
5433
5432
  id: crypto.randomUUID(),
5434
5433
  name: "\u041D\u043E\u0432\u0430\u044F \u0437\u0430\u0434\u0430\u0447\u0430",
5435
5434
  startDate: todayISO,
5436
- endDate: endISO
5435
+ endDate: endISO,
5436
+ parentId: task.parentId
5437
5437
  };
5438
5438
  onInsertAfter(task.id, newTask);
5439
5439
  },
@@ -6001,10 +6001,17 @@ TaskListRow.displayName = "TaskListRow";
6001
6001
  // src/components/TaskList/NewTaskRow.tsx
6002
6002
  var import_react11 = require("react");
6003
6003
  var import_jsx_runtime13 = require("react/jsx-runtime");
6004
- var NewTaskRow = ({ rowHeight, onConfirm, onCancel }) => {
6004
+ var NewTaskRow = ({
6005
+ rowHeight,
6006
+ onConfirm,
6007
+ onCancel,
6008
+ nestingDepth = 0
6009
+ }) => {
6005
6010
  const [nameValue, setNameValue] = (0, import_react11.useState)("");
6006
6011
  const inputRef = (0, import_react11.useRef)(null);
6007
6012
  const confirmedRef = (0, import_react11.useRef)(false);
6013
+ const inputInnerPadding = 4;
6014
+ const levelOffset = nestingDepth > 0 ? nestingDepth * 20 + 8 : 0;
6008
6015
  (0, import_react11.useEffect)(() => {
6009
6016
  if (inputRef.current) {
6010
6017
  inputRef.current.focus();
@@ -6043,7 +6050,12 @@ var NewTaskRow = ({ rowHeight, onConfirm, onCancel }) => {
6043
6050
  onKeyDown: handleKeyDown,
6044
6051
  onBlur: handleBlur,
6045
6052
  placeholder: "\u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435",
6046
- className: "gantt-tl-name-input"
6053
+ className: "gantt-tl-name-input",
6054
+ style: {
6055
+ left: `${Math.max(0, levelOffset - inputInnerPadding)}px`,
6056
+ width: levelOffset > 0 ? `calc(100% - ${Math.max(0, levelOffset - inputInnerPadding)}px)` : "100%",
6057
+ paddingLeft: `${inputInnerPadding}px`
6058
+ }
6047
6059
  }
6048
6060
  ) }),
6049
6061
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "gantt-tl-cell" }),
@@ -6467,6 +6479,7 @@ var TaskList = ({
6467
6479
  onTasksChange?.([{ ...task, dependencies: updatedDeps }]);
6468
6480
  }, [tasks, onTasksChange]);
6469
6481
  const [isCreating, setIsCreating] = (0, import_react12.useState)(false);
6482
+ const [pendingInsert, setPendingInsert] = (0, import_react12.useState)(null);
6470
6483
  const [draggingIndex, setDraggingIndex] = (0, import_react12.useState)(null);
6471
6484
  const [dragOverIndex, setDragOverIndex] = (0, import_react12.useState)(null);
6472
6485
  const dragOriginIndexRef = (0, import_react12.useRef)(null);
@@ -6625,6 +6638,81 @@ var TaskList = ({
6625
6638
  setIsCreating(false);
6626
6639
  }, [onAdd]);
6627
6640
  const handleCancelNewTask = (0, import_react12.useCallback)(() => setIsCreating(false), []);
6641
+ const findInsertAfterTaskId = (0, import_react12.useCallback)((anchorTaskId) => {
6642
+ const anchorIndex = orderedTasks.findIndex((task) => task.id === anchorTaskId);
6643
+ if (anchorIndex === -1) {
6644
+ return anchorTaskId;
6645
+ }
6646
+ const taskById = new Map(orderedTasks.map((task) => [task.id, task]));
6647
+ let insertAfterTaskId = anchorTaskId;
6648
+ for (let index = anchorIndex + 1; index < orderedTasks.length; index += 1) {
6649
+ let currentParentId = orderedTasks[index]?.parentId;
6650
+ let isDescendant = false;
6651
+ while (currentParentId) {
6652
+ if (currentParentId === anchorTaskId) {
6653
+ isDescendant = true;
6654
+ break;
6655
+ }
6656
+ currentParentId = taskById.get(currentParentId)?.parentId;
6657
+ }
6658
+ if (!isDescendant) {
6659
+ break;
6660
+ }
6661
+ insertAfterTaskId = orderedTasks[index].id;
6662
+ }
6663
+ return insertAfterTaskId;
6664
+ }, [orderedTasks]);
6665
+ const pendingInsertDisplayTaskId = (0, import_react12.useMemo)(() => {
6666
+ if (!pendingInsert) {
6667
+ return null;
6668
+ }
6669
+ const taskById = new Map(visibleTasks.map((task) => [task.id, task]));
6670
+ if (!taskById.has(pendingInsert.anchorTaskId)) {
6671
+ return null;
6672
+ }
6673
+ let displayTaskId = pendingInsert.anchorTaskId;
6674
+ for (const task of visibleTasks) {
6675
+ let currentParentId = task.parentId;
6676
+ while (currentParentId) {
6677
+ if (currentParentId === pendingInsert.anchorTaskId) {
6678
+ displayTaskId = task.id;
6679
+ break;
6680
+ }
6681
+ currentParentId = taskById.get(currentParentId)?.parentId;
6682
+ }
6683
+ }
6684
+ return displayTaskId;
6685
+ }, [pendingInsert, visibleTasks]);
6686
+ const handleStartInsertAfter = (0, import_react12.useCallback)((taskId, newTask) => {
6687
+ const anchorTask = orderedTasks.find((task) => task.id === taskId);
6688
+ if (!anchorTask) {
6689
+ return;
6690
+ }
6691
+ setIsCreating(false);
6692
+ setPendingInsert({
6693
+ anchorTaskId: taskId,
6694
+ insertAfterTaskId: findInsertAfterTaskId(taskId),
6695
+ parentId: anchorTask.parentId,
6696
+ startDate: newTask.startDate,
6697
+ endDate: newTask.endDate,
6698
+ nestingDepth: nestingDepthMap.get(taskId) ?? 0
6699
+ });
6700
+ }, [findInsertAfterTaskId, nestingDepthMap, orderedTasks]);
6701
+ const handleConfirmInsertedTask = (0, import_react12.useCallback)((name) => {
6702
+ if (!pendingInsert) {
6703
+ return;
6704
+ }
6705
+ const newTask = {
6706
+ id: crypto.randomUUID(),
6707
+ name,
6708
+ startDate: pendingInsert.startDate,
6709
+ endDate: pendingInsert.endDate,
6710
+ parentId: pendingInsert.parentId
6711
+ };
6712
+ onInsertAfter?.(pendingInsert.insertAfterTaskId, newTask);
6713
+ setPendingInsert(null);
6714
+ }, [onInsertAfter, pendingInsert]);
6715
+ const handleCancelInsertedTask = (0, import_react12.useCallback)(() => setPendingInsert(null), []);
6628
6716
  function getTaskDepth(task, tasks2) {
6629
6717
  if (!task) return 0;
6630
6718
  let depth = 0;
@@ -6764,73 +6852,87 @@ var TaskList = ({
6764
6852
  /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "gantt-tl-body", style: { height: `${totalHeight}px` }, children: visibleTasks.map((task, index) => {
6765
6853
  const previousVisibleTask = index > 0 ? visibleTasks[index - 1] : void 0;
6766
6854
  const canDemoteTask = index === 0 || !task.parentId || previousVisibleTask?.id !== task.parentId;
6767
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
6768
- TaskListRow,
6769
- {
6770
- task,
6771
- rowIndex: index,
6772
- taskNumber: originalTaskNumberMap[task.id] || "",
6773
- taskNumberMap: originalTaskNumberMap,
6774
- rowHeight,
6775
- onTasksChange,
6776
- selectedTaskId,
6777
- onRowClick: handleRowClick,
6778
- disableTaskNameEditing,
6779
- disableDependencyEditing,
6780
- allTasks: tasks,
6781
- activeLinkType,
6782
- onSetActiveLinkType: setActiveLinkType,
6783
- selectingPredecessorFor,
6784
- dependencyPickMode,
6785
- onSetDependencyPickMode: setDependencyPickMode,
6786
- onSetSelectingPredecessorFor: setSelectingPredecessorFor,
6787
- onAddDependency: handleAddDependency,
6788
- onRemoveDependency: handleRemoveDependency,
6789
- selectedChip,
6790
- onChipSelect: handleChipSelect,
6791
- onScrollToTask,
6792
- onDelete,
6793
- onAdd,
6794
- onInsertAfter,
6795
- editingTaskId: propEditingTaskId,
6796
- isDragging: draggingIndex === index,
6797
- isDragOver: dragOverIndex === index,
6798
- onDragStart: handleDragStart,
6799
- onDragOver: handleDragOver,
6800
- onDrop: handleDrop,
6801
- onDragEnd: handleDragEnd,
6802
- collapsedParentIds,
6803
- onToggleCollapse: handleToggleCollapse,
6804
- onPromoteTask,
6805
- onDemoteTask: onDemoteTask ? handleDemoteWrapper : void 0,
6806
- onDuplicateTask: onReorder ? handleDuplicateTask : void 0,
6807
- canDemoteTask,
6808
- isLastChild: lastChildIds.has(task.id),
6809
- nestingDepth: nestingDepthMap.get(task.id) ?? 0,
6810
- ancestorContinues: ancestorContinuesMap.get(task.id) ?? [],
6811
- customDays,
6812
- isWeekend: isWeekend3,
6813
- businessDays,
6814
- isFilterMatch: filterMode === "highlight" ? highlightedTaskIds.has(task.id) : false,
6815
- isFilterHideMode: filterMode === "hide" && isFilterActive,
6816
- resolvedColumns
6817
- },
6818
- task.id
6819
- );
6855
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_react12.default.Fragment, { children: [
6856
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
6857
+ TaskListRow,
6858
+ {
6859
+ task,
6860
+ rowIndex: index,
6861
+ taskNumber: originalTaskNumberMap[task.id] || "",
6862
+ taskNumberMap: originalTaskNumberMap,
6863
+ rowHeight,
6864
+ onTasksChange,
6865
+ selectedTaskId,
6866
+ onRowClick: handleRowClick,
6867
+ disableTaskNameEditing,
6868
+ disableDependencyEditing,
6869
+ allTasks: tasks,
6870
+ activeLinkType,
6871
+ onSetActiveLinkType: setActiveLinkType,
6872
+ selectingPredecessorFor,
6873
+ dependencyPickMode,
6874
+ onSetDependencyPickMode: setDependencyPickMode,
6875
+ onSetSelectingPredecessorFor: setSelectingPredecessorFor,
6876
+ onAddDependency: handleAddDependency,
6877
+ onRemoveDependency: handleRemoveDependency,
6878
+ selectedChip,
6879
+ onChipSelect: handleChipSelect,
6880
+ onScrollToTask,
6881
+ onDelete,
6882
+ onAdd,
6883
+ onInsertAfter: handleStartInsertAfter,
6884
+ editingTaskId: propEditingTaskId,
6885
+ isDragging: draggingIndex === index,
6886
+ isDragOver: dragOverIndex === index,
6887
+ onDragStart: handleDragStart,
6888
+ onDragOver: handleDragOver,
6889
+ onDrop: handleDrop,
6890
+ onDragEnd: handleDragEnd,
6891
+ collapsedParentIds,
6892
+ onToggleCollapse: handleToggleCollapse,
6893
+ onPromoteTask,
6894
+ onDemoteTask: onDemoteTask ? handleDemoteWrapper : void 0,
6895
+ onDuplicateTask: onReorder ? handleDuplicateTask : void 0,
6896
+ canDemoteTask,
6897
+ isLastChild: lastChildIds.has(task.id),
6898
+ nestingDepth: nestingDepthMap.get(task.id) ?? 0,
6899
+ ancestorContinues: ancestorContinuesMap.get(task.id) ?? [],
6900
+ customDays,
6901
+ isWeekend: isWeekend3,
6902
+ businessDays,
6903
+ isFilterMatch: filterMode === "highlight" ? highlightedTaskIds.has(task.id) : false,
6904
+ isFilterHideMode: filterMode === "hide" && isFilterActive,
6905
+ resolvedColumns
6906
+ }
6907
+ ),
6908
+ pendingInsertDisplayTaskId === task.id && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
6909
+ NewTaskRow,
6910
+ {
6911
+ rowHeight,
6912
+ onConfirm: handleConfirmInsertedTask,
6913
+ onCancel: handleCancelInsertedTask,
6914
+ nestingDepth: pendingInsert?.nestingDepth ?? 0
6915
+ }
6916
+ )
6917
+ ] }, task.id);
6820
6918
  }) }),
6821
- isCreating && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
6919
+ isCreating && !pendingInsert && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
6822
6920
  NewTaskRow,
6823
6921
  {
6824
6922
  rowHeight,
6825
6923
  onConfirm: handleConfirmNewTask,
6826
- onCancel: handleCancelNewTask
6924
+ onCancel: handleCancelNewTask,
6925
+ nestingDepth: 0
6827
6926
  }
6828
6927
  ),
6829
- enableAddTask && onAdd && !isCreating && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
6928
+ enableAddTask && onAdd && !isCreating && !pendingInsert && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
6830
6929
  "button",
6831
6930
  {
6832
6931
  className: `gantt-tl-add-btn${dragOverIndex === visibleTasks.length ? " gantt-tl-add-btn-drag-over" : ""}`,
6833
- onClick: () => setIsCreating(true),
6932
+ onClick: () => {
6933
+ setPendingInsert(null);
6934
+ setIsCreating(true);
6935
+ },
6834
6936
  onDragEnter: (e) => {
6835
6937
  e.preventDefault();
6836
6938
  setDragOverIndex(visibleTasks.length);
@@ -6972,7 +7074,7 @@ function GanttChartInner(props, ref) {
6972
7074
  if (todayIndex === -1) return;
6973
7075
  const todayOffset = todayIndex * dayWidth;
6974
7076
  const containerWidth = container.clientWidth;
6975
- const scrollLeft = Math.round(todayOffset - containerWidth / 2 + dayWidth / 2);
7077
+ const scrollLeft = Math.round(todayOffset + dayWidth / 2 - containerWidth * 0.3);
6976
7078
  container.scrollLeft = Math.max(0, scrollLeft);
6977
7079
  }, []);
6978
7080
  (0, import_react13.useEffect)(() => {
@@ -6996,7 +7098,7 @@ function GanttChartInner(props, ref) {
6996
7098
  if (todayIndex === -1) return;
6997
7099
  const todayOffset = todayIndex * dayWidth;
6998
7100
  const containerWidth = container.clientWidth;
6999
- const scrollLeft = Math.round(todayOffset - containerWidth / 2 + dayWidth / 2);
7101
+ const scrollLeft = Math.round(todayOffset + dayWidth / 2 - containerWidth * 0.3);
7000
7102
  container.scrollTo({ left: Math.max(0, scrollLeft), behavior: "smooth" });
7001
7103
  }, [dateRange, dayWidth]);
7002
7104
  const scrollToTask = (0, import_react13.useCallback)((taskId) => {
@@ -7107,7 +7209,6 @@ function GanttChartInner(props, ref) {
7107
7209
  toDelete.forEach((id) => onDelete?.(id));
7108
7210
  }, [tasks, onTasksChange, onDelete]);
7109
7211
  const handleInsertAfter = (0, import_react13.useCallback)((taskId, newTask) => {
7110
- setEditingTaskId(newTask.id);
7111
7212
  onInsertAfter?.(taskId, newTask);
7112
7213
  }, [onInsertAfter]);
7113
7214
  const handleReorder = (0, import_react13.useCallback)((reorderedTasks, movedTaskId, inferredParentId) => {