gantt-lib 0.3.3 → 0.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/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
 
3
3
  // src/components/GanttChart/GanttChart.tsx
4
- import { useMemo as useMemo9, useCallback as useCallback6, useRef as useRef5, useState as useState6, useEffect as useEffect5, useImperativeHandle, forwardRef } from "react";
4
+ import { useMemo as useMemo9, useCallback as useCallback6, useRef as useRef6, useState as useState7, useEffect as useEffect6, useImperativeHandle, forwardRef } from "react";
5
5
 
6
6
  // src/utils/dateUtils.ts
7
7
  var parseUTCDate = (date) => {
@@ -42,9 +42,9 @@ var getDayOffset = (date, monthStart) => {
42
42
  var isToday = (date) => {
43
43
  const now = /* @__PURE__ */ new Date();
44
44
  const today = new Date(Date.UTC(
45
- now.getUTCFullYear(),
46
- now.getUTCMonth(),
47
- now.getUTCDate()
45
+ now.getFullYear(),
46
+ now.getMonth(),
47
+ now.getDate()
48
48
  ));
49
49
  const compareDate = new Date(Date.UTC(
50
50
  date.getUTCFullYear(),
@@ -523,7 +523,7 @@ var calculateGridLines = (dateRange, dayWidth) => {
523
523
  for (let i = 0; i < dateRange.length; i++) {
524
524
  const date = dateRange[i];
525
525
  const x = Math.round(i * dayWidth);
526
- const isMonthStart = date.getUTCDate() === 1;
526
+ const isMonthStart = i === 0 ? false : date.getUTCDate() === 1;
527
527
  const isWeekStart = date.getUTCDay() === 1;
528
528
  lines.push({ x, isMonthStart, isWeekStart });
529
529
  }
@@ -1102,7 +1102,7 @@ var TaskRow = React2.memo(
1102
1102
  const isExpired = useMemo2(() => {
1103
1103
  if (!highlightExpiredTasks) return false;
1104
1104
  const now = /* @__PURE__ */ new Date();
1105
- const today = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()));
1105
+ const today = new Date(Date.UTC(now.getFullYear(), now.getMonth(), now.getDate()));
1106
1106
  const taskStart = parseUTCDate(task.startDate);
1107
1107
  const taskEnd = parseUTCDate(task.endDate);
1108
1108
  const actualProgress = task.progress ?? 0;
@@ -1322,7 +1322,7 @@ var TodayIndicator_default = TodayIndicator;
1322
1322
  import React4, { useMemo as useMemo4 } from "react";
1323
1323
  import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
1324
1324
  var arePropsEqual2 = (prevProps, nextProps) => {
1325
- return prevProps.dayWidth === nextProps.dayWidth && prevProps.dateRange.length === nextProps.dateRange.length && prevProps.totalHeight !== nextProps.totalHeight;
1325
+ return prevProps.dayWidth === nextProps.dayWidth && prevProps.dateRange.length === nextProps.dateRange.length && prevProps.totalHeight === nextProps.totalHeight;
1326
1326
  };
1327
1327
  var GridBackground = React4.memo(
1328
1328
  ({ dateRange, dayWidth, totalHeight }) => {
@@ -1609,7 +1609,7 @@ DependencyLines.displayName = "DependencyLines";
1609
1609
  var DependencyLines_default = DependencyLines;
1610
1610
 
1611
1611
  // src/components/TaskList/TaskList.tsx
1612
- import React10, { useMemo as useMemo8, useCallback as useCallback5, useState as useState5, useEffect as useEffect4, useRef as useRef4 } from "react";
1612
+ import React11, { useMemo as useMemo8, useCallback as useCallback5, useState as useState6, useEffect as useEffect5, useRef as useRef5 } from "react";
1613
1613
 
1614
1614
  // src/components/ui/Popover.tsx
1615
1615
  import * as RadixPopover from "@radix-ui/react-popover";
@@ -1683,6 +1683,7 @@ import {
1683
1683
  format as format2,
1684
1684
  addMonths,
1685
1685
  subMonths,
1686
+ addDays,
1686
1687
  isSameDay,
1687
1688
  getDay,
1688
1689
  isToday as isToday2,
@@ -1796,7 +1797,73 @@ var Calendar = ({
1796
1797
  () => months.map(renderMonth),
1797
1798
  [months, renderMonth]
1798
1799
  );
1799
- return /* @__PURE__ */ jsx9("div", { ref: scrollRef, className: "gantt-cal-container", children: renderedMonths });
1800
+ const handleDayShift = useCallback2(
1801
+ (deltaDays) => {
1802
+ if (!onSelect || disabled) return;
1803
+ const baseDate = selected ?? /* @__PURE__ */ new Date();
1804
+ onSelect(addDays(baseDate, deltaDays));
1805
+ },
1806
+ [onSelect, selected, disabled]
1807
+ );
1808
+ const handleToday = useCallback2(() => {
1809
+ if (!onSelect || disabled) return;
1810
+ onSelect(/* @__PURE__ */ new Date());
1811
+ }, [onSelect, disabled]);
1812
+ return /* @__PURE__ */ jsxs6("div", { ref: scrollRef, className: "gantt-cal-container", children: [
1813
+ renderedMonths,
1814
+ /* @__PURE__ */ jsxs6("div", { className: "gantt-cal-nav", children: [
1815
+ /* @__PURE__ */ jsx9(
1816
+ "button",
1817
+ {
1818
+ type: "button",
1819
+ className: "gantt-btn gantt-btn-sm",
1820
+ onClick: () => handleDayShift(-7),
1821
+ disabled,
1822
+ children: "-7"
1823
+ }
1824
+ ),
1825
+ /* @__PURE__ */ jsx9(
1826
+ "button",
1827
+ {
1828
+ type: "button",
1829
+ className: "gantt-btn gantt-btn-sm",
1830
+ onClick: () => handleDayShift(-1),
1831
+ disabled,
1832
+ children: "-1"
1833
+ }
1834
+ ),
1835
+ /* @__PURE__ */ jsx9(
1836
+ "button",
1837
+ {
1838
+ type: "button",
1839
+ className: "gantt-btn gantt-btn-sm",
1840
+ onClick: handleToday,
1841
+ disabled,
1842
+ children: "\u0421\u0435\u0433\u043E\u0434\u043D\u044F"
1843
+ }
1844
+ ),
1845
+ /* @__PURE__ */ jsx9(
1846
+ "button",
1847
+ {
1848
+ type: "button",
1849
+ className: "gantt-btn gantt-btn-sm",
1850
+ onClick: () => handleDayShift(1),
1851
+ disabled,
1852
+ children: "+1"
1853
+ }
1854
+ ),
1855
+ /* @__PURE__ */ jsx9(
1856
+ "button",
1857
+ {
1858
+ type: "button",
1859
+ className: "gantt-btn gantt-btn-sm",
1860
+ onClick: () => handleDayShift(7),
1861
+ disabled,
1862
+ children: "+7"
1863
+ }
1864
+ )
1865
+ ] })
1866
+ ] });
1800
1867
  };
1801
1868
  Calendar.displayName = "Calendar";
1802
1869
 
@@ -1904,6 +1971,7 @@ var TrashIcon = () => /* @__PURE__ */ jsxs9("svg", { xmlns: "http://www.w3.org/2
1904
1971
  /* @__PURE__ */ jsx12("path", { d: "M3 6h18" }),
1905
1972
  /* @__PURE__ */ jsx12("path", { d: "M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" })
1906
1973
  ] });
1974
+ var PlusIcon = () => /* @__PURE__ */ jsx12("svg", { xmlns: "http://www.w3.org/2000/svg", width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx12("path", { d: "M12 5v14M5 12h14" }) });
1907
1975
  function formatDepDescription(type, lag) {
1908
1976
  const effectiveLag = lag ?? 0;
1909
1977
  if (type === "FS") {
@@ -1945,12 +2013,19 @@ var DepChip = ({
1945
2013
  const handleClick = (e) => {
1946
2014
  e.stopPropagation();
1947
2015
  if (disableDependencyEditing) return;
1948
- onChipSelect?.(isSelected ? null : { successorId: taskId, predecessorId: dep.taskId, linkType: dep.type });
1949
- if (!isSelected) {
1950
- onRowClick?.(taskId);
1951
- onScrollToTask?.(taskId);
2016
+ if (isSelected) {
2017
+ e.preventDefault();
2018
+ onChipSelect?.(null);
2019
+ return;
1952
2020
  }
2021
+ onChipSelect?.({ successorId: taskId, predecessorId: dep.taskId, linkType: dep.type });
2022
+ onScrollToTask?.(dep.taskId);
1953
2023
  };
2024
+ const handleOpenChange = useCallback4((open) => {
2025
+ if (!open) {
2026
+ onChipSelect?.(null);
2027
+ }
2028
+ }, [onChipSelect]);
1954
2029
  const handleTrashClick = (e) => {
1955
2030
  e.stopPropagation();
1956
2031
  onRemoveDependency?.(taskId, dep.taskId, dep.type);
@@ -1959,50 +2034,26 @@ var DepChip = ({
1959
2034
  const Icon = LINK_TYPE_ICONS[dep.type];
1960
2035
  const depPrefix = formatDepDescription(dep.type, lag);
1961
2036
  const depName = predecessorName ?? dep.taskId;
1962
- return /* @__PURE__ */ jsxs9(Popover, { open: isSelected, onOpenChange: (open) => {
1963
- }, children: [
1964
- /* @__PURE__ */ jsx12(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs9("span", { className: "gantt-tl-dep-chip-wrapper", children: [
1965
- /* @__PURE__ */ jsx12(
1966
- "span",
1967
- {
1968
- className: `gantt-tl-dep-chip${isSelected ? " gantt-tl-dep-chip-selected" : ""}`,
1969
- onClick: handleClick,
1970
- children: /* @__PURE__ */ jsxs9(Fragment2, { children: [
1971
- /* @__PURE__ */ jsx12(Icon, {}),
1972
- lag != null && lag !== 0 ? lag > 0 ? `+${lag}` : `${lag}` : ""
1973
- ] })
1974
- }
1975
- ),
1976
- !disableDependencyEditing && /* @__PURE__ */ jsx12(
1977
- "button",
1978
- {
1979
- type: "button",
1980
- className: "gantt-tl-dep-chip-trash",
1981
- "aria-label": "\u0423\u0434\u0430\u043B\u0438\u0442\u044C \u0441\u0432\u044F\u0437\u044C",
1982
- onClick: handleTrashClick,
1983
- children: /* @__PURE__ */ jsx12(TrashIcon, {})
1984
- }
1985
- )
1986
- ] }) }),
1987
- /* @__PURE__ */ jsxs9(
1988
- PopoverContent,
2037
+ return /* @__PURE__ */ jsxs9("span", { className: "gantt-tl-dep-chip-wrapper", children: [
2038
+ /* @__PURE__ */ jsx12(
2039
+ "span",
1989
2040
  {
1990
- portal: true,
1991
- side: "bottom",
1992
- align: "start",
1993
- className: "gantt-tl-dep-info-popover",
1994
- onInteractOutside: (event) => {
1995
- const target = event.target;
1996
- if (target?.closest?.(".gantt-tl-dep-chip") || target?.closest?.(".gantt-tl-dep-delete-label") || target?.closest?.(".gantt-tl-dep-chip-trash")) {
1997
- event.preventDefault();
1998
- } else {
1999
- onChipSelectClear();
2000
- }
2001
- },
2002
- children: [
2003
- /* @__PURE__ */ jsx12("span", { className: "gantt-tl-dep-info-prefix", children: depPrefix }),
2004
- /* @__PURE__ */ jsx12("span", { className: "gantt-tl-dep-info-name", children: depName })
2005
- ]
2041
+ className: `gantt-tl-dep-chip${isSelected ? " gantt-tl-dep-chip-selected" : ""}`,
2042
+ onClick: handleClick,
2043
+ children: /* @__PURE__ */ jsxs9(Fragment2, { children: [
2044
+ /* @__PURE__ */ jsx12(Icon, {}),
2045
+ lag != null && lag !== 0 ? lag > 0 ? `+${lag}` : `${lag}` : ""
2046
+ ] })
2047
+ }
2048
+ ),
2049
+ !disableDependencyEditing && /* @__PURE__ */ jsx12(
2050
+ "button",
2051
+ {
2052
+ type: "button",
2053
+ className: "gantt-tl-dep-chip-trash",
2054
+ "aria-label": "\u0423\u0434\u0430\u043B\u0438\u0442\u044C \u0441\u0432\u044F\u0437\u044C",
2055
+ onClick: handleTrashClick,
2056
+ children: /* @__PURE__ */ jsx12(TrashIcon, {})
2006
2057
  }
2007
2058
  )
2008
2059
  ] });
@@ -2030,12 +2081,19 @@ var TaskListRow = React9.memo(
2030
2081
  onRemoveDependency,
2031
2082
  selectedChip,
2032
2083
  onChipSelect,
2033
- onScrollToTask
2084
+ onScrollToTask,
2085
+ onDelete,
2086
+ onAdd,
2087
+ onInsertAfter,
2088
+ editingTaskId
2034
2089
  }) => {
2035
2090
  const [editingName, setEditingName] = useState4(false);
2036
2091
  const [nameValue, setNameValue] = useState4("");
2037
2092
  const nameInputRef = useRef3(null);
2038
2093
  const [overflowOpen, setOverflowOpen] = useState4(false);
2094
+ const confirmedRef = useRef3(false);
2095
+ const autoEditedForRef = useRef3(null);
2096
+ const editTriggerRef = useRef3("doubleclick");
2039
2097
  const isSelected = selectedTaskId === task.id;
2040
2098
  const isPicking = selectingPredecessorFor != null;
2041
2099
  const isSourceRow = isPicking && selectingPredecessorFor === task.id;
@@ -2059,15 +2117,59 @@ var TaskListRow = React9.memo(
2059
2117
  useEffect3(() => {
2060
2118
  if (editingName && nameInputRef.current) {
2061
2119
  nameInputRef.current.focus();
2120
+ if (editTriggerRef.current === "keypress") {
2121
+ const len = nameInputRef.current.value.length;
2122
+ nameInputRef.current.setSelectionRange(len, len);
2123
+ } else {
2124
+ nameInputRef.current.select();
2125
+ }
2062
2126
  }
2063
2127
  }, [editingName]);
2128
+ useEffect3(() => {
2129
+ if (editingTaskId === task.id && !disableTaskNameEditing && autoEditedForRef.current !== editingTaskId) {
2130
+ autoEditedForRef.current = editingTaskId;
2131
+ confirmedRef.current = false;
2132
+ editTriggerRef.current = "autoedit";
2133
+ setNameValue(task.name);
2134
+ setEditingName(true);
2135
+ }
2136
+ }, [editingTaskId, task.id, disableTaskNameEditing]);
2064
2137
  const handleNameClick = useCallback4((e) => {
2065
2138
  if (disableTaskNameEditing) return;
2066
2139
  e.stopPropagation();
2140
+ onRowClick?.(task.id);
2141
+ onScrollToTask?.(task.id);
2142
+ }, [task.id, disableTaskNameEditing, onRowClick, onScrollToTask]);
2143
+ const handleNameDoubleClick = useCallback4((e) => {
2144
+ if (disableTaskNameEditing) return;
2145
+ e.stopPropagation();
2146
+ confirmedRef.current = false;
2147
+ editTriggerRef.current = "doubleclick";
2067
2148
  setNameValue(task.name);
2068
2149
  setEditingName(true);
2069
2150
  }, [task.name, disableTaskNameEditing]);
2151
+ const handleRowKeyDown = useCallback4((e) => {
2152
+ if (!editingName && !disableTaskNameEditing && e.key === "F2") {
2153
+ e.preventDefault();
2154
+ confirmedRef.current = false;
2155
+ editTriggerRef.current = "keypress";
2156
+ setNameValue(task.name);
2157
+ setEditingName(true);
2158
+ return;
2159
+ }
2160
+ if (!editingName && !disableTaskNameEditing && e.key.length === 1 && !e.ctrlKey && !e.metaKey && !e.altKey) {
2161
+ e.preventDefault();
2162
+ confirmedRef.current = false;
2163
+ editTriggerRef.current = "keypress";
2164
+ setNameValue(e.key);
2165
+ setEditingName(true);
2166
+ }
2167
+ }, [editingName, disableTaskNameEditing, task.name]);
2070
2168
  const handleNameSave = useCallback4(() => {
2169
+ if (confirmedRef.current) {
2170
+ confirmedRef.current = false;
2171
+ return;
2172
+ }
2071
2173
  if (nameValue.trim()) {
2072
2174
  onTaskChange?.({ ...task, name: nameValue.trim() });
2073
2175
  }
@@ -2077,9 +2179,16 @@ var TaskListRow = React9.memo(
2077
2179
  setEditingName(false);
2078
2180
  }, []);
2079
2181
  const handleNameKeyDown = useCallback4((e) => {
2080
- if (e.key === "Enter") handleNameSave();
2081
- else if (e.key === "Escape") handleNameCancel();
2082
- }, [handleNameSave, handleNameCancel]);
2182
+ if (e.key === "Enter") {
2183
+ confirmedRef.current = true;
2184
+ if (nameValue.trim()) {
2185
+ onTaskChange?.({ ...task, name: nameValue.trim() });
2186
+ }
2187
+ setEditingName(false);
2188
+ } else if (e.key === "Escape") {
2189
+ handleNameCancel();
2190
+ }
2191
+ }, [nameValue, task, onTaskChange, handleNameCancel]);
2083
2192
  const handleStartDateChange = useCallback4((newDateISO) => {
2084
2193
  if (!newDateISO) return;
2085
2194
  const origStart = parseUTCDate(task.startDate);
@@ -2104,8 +2213,7 @@ var TaskListRow = React9.memo(
2104
2213
  const handleNumberClick = useCallback4((e) => {
2105
2214
  e.stopPropagation();
2106
2215
  onRowClick?.(task.id);
2107
- onScrollToTask?.(task.id);
2108
- }, [task.id, onRowClick, onScrollToTask]);
2216
+ }, [task.id, onRowClick]);
2109
2217
  const handleAddClick = useCallback4((e) => {
2110
2218
  e.stopPropagation();
2111
2219
  onSetSelectingPredecessorFor?.(task.id);
@@ -2116,6 +2224,10 @@ var TaskListRow = React9.memo(
2116
2224
  if (!selectingPredecessorFor || !activeLinkType) return;
2117
2225
  onAddDependency?.(task.id, selectingPredecessorFor, activeLinkType);
2118
2226
  }, [isPicking, isSourceRow, selectingPredecessorFor, task.id, activeLinkType, onAddDependency]);
2227
+ const handleCancelPicking = useCallback4((e) => {
2228
+ e.stopPropagation();
2229
+ onSetSelectingPredecessorFor?.(null);
2230
+ }, [onSetSelectingPredecessorFor]);
2119
2231
  const isSelectedPredecessor = selectedChip != null && selectedChip.predecessorId === task.id;
2120
2232
  const handleDeleteSelected = useCallback4((e) => {
2121
2233
  e.stopPropagation();
@@ -2134,23 +2246,17 @@ var TaskListRow = React9.memo(
2134
2246
  isPicking && !isSourceRow ? "gantt-tl-row-picking" : "",
2135
2247
  isSourceRow ? "gantt-tl-row-picking-self" : ""
2136
2248
  ].filter(Boolean).join(" "),
2137
- style: { minHeight: `${rowHeight}px` },
2249
+ style: { minHeight: `${rowHeight}px`, position: "relative" },
2138
2250
  onClick: handleRowClickInternal,
2251
+ onKeyDown: handleRowKeyDown,
2252
+ tabIndex: isSelected ? 0 : -1,
2139
2253
  children: [
2140
- /* @__PURE__ */ jsxs9(
2254
+ /* @__PURE__ */ jsx12(
2141
2255
  "div",
2142
2256
  {
2143
2257
  className: "gantt-tl-cell gantt-tl-cell-number",
2144
2258
  onClick: handleNumberClick,
2145
- title: "\u041F\u0435\u0440\u0435\u0439\u0442\u0438 \u043A \u0440\u0430\u0431\u043E\u0442\u0435",
2146
- children: [
2147
- /* @__PURE__ */ jsx12("span", { className: "gantt-tl-num-label", children: rowIndex + 1 }),
2148
- /* @__PURE__ */ jsxs9("svg", { className: "gantt-tl-num-icon", xmlns: "http://www.w3.org/2000/svg", width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
2149
- /* @__PURE__ */ jsx12("path", { d: "M17 12H3" }),
2150
- /* @__PURE__ */ jsx12("path", { d: "m11 18 6-6-6-6" }),
2151
- /* @__PURE__ */ jsx12("path", { d: "M21 5v14" })
2152
- ] })
2153
- ]
2259
+ children: /* @__PURE__ */ jsx12("span", { className: "gantt-tl-num-label", children: rowIndex + 1 })
2154
2260
  }
2155
2261
  ),
2156
2262
  /* @__PURE__ */ jsxs9("div", { className: "gantt-tl-cell gantt-tl-cell-name", children: [
@@ -2173,10 +2279,56 @@ var TaskListRow = React9.memo(
2173
2279
  type: "button",
2174
2280
  className: `gantt-tl-name-trigger ${disableTaskNameEditing ? "gantt-tl-name-locked" : ""}`,
2175
2281
  onClick: handleNameClick,
2282
+ onDoubleClick: handleNameDoubleClick,
2176
2283
  style: editingName ? { visibility: "hidden", pointerEvents: "none" } : void 0,
2177
2284
  children: task.name
2178
2285
  }
2179
- )
2286
+ ),
2287
+ !editingName && /* @__PURE__ */ jsxs9("div", { className: "gantt-tl-name-actions", children: [
2288
+ onInsertAfter && /* @__PURE__ */ jsx12(
2289
+ "button",
2290
+ {
2291
+ type: "button",
2292
+ className: "gantt-tl-name-action-btn gantt-tl-action-insert",
2293
+ onClick: (e) => {
2294
+ e.stopPropagation();
2295
+ const now = /* @__PURE__ */ new Date();
2296
+ const todayISO = new Date(Date.UTC(
2297
+ now.getUTCFullYear(),
2298
+ now.getUTCMonth(),
2299
+ now.getUTCDate()
2300
+ )).toISOString().split("T")[0];
2301
+ const endISO = new Date(Date.UTC(
2302
+ now.getUTCFullYear(),
2303
+ now.getUTCMonth(),
2304
+ now.getUTCDate() + 7
2305
+ )).toISOString().split("T")[0];
2306
+ const newTask = {
2307
+ id: crypto.randomUUID(),
2308
+ name: "\u041D\u043E\u0432\u0430\u044F \u0437\u0430\u0434\u0430\u0447\u0430",
2309
+ startDate: todayISO,
2310
+ endDate: endISO
2311
+ };
2312
+ onInsertAfter(task.id, newTask);
2313
+ },
2314
+ "aria-label": "\u0412\u0441\u0442\u0430\u0432\u0438\u0442\u044C \u0437\u0430\u0434\u0430\u0447\u0443 \u043F\u043E\u0441\u043B\u0435 \u044D\u0442\u043E\u0439",
2315
+ children: /* @__PURE__ */ jsx12(PlusIcon, {})
2316
+ }
2317
+ ),
2318
+ onDelete && /* @__PURE__ */ jsx12(
2319
+ "button",
2320
+ {
2321
+ type: "button",
2322
+ className: "gantt-tl-name-action-btn gantt-tl-action-delete",
2323
+ onClick: (e) => {
2324
+ e.stopPropagation();
2325
+ onDelete(task.id);
2326
+ },
2327
+ "aria-label": "\u0423\u0434\u0430\u043B\u0438\u0442\u044C \u0437\u0430\u0434\u0430\u0447\u0443",
2328
+ children: /* @__PURE__ */ jsx12(TrashIcon, {})
2329
+ }
2330
+ )
2331
+ ] })
2180
2332
  ] }),
2181
2333
  /* @__PURE__ */ jsx12("div", { className: "gantt-tl-cell gantt-tl-cell-date", onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsx12(
2182
2334
  DatePicker,
@@ -2202,7 +2354,7 @@ var TaskListRow = React9.memo(
2202
2354
  "div",
2203
2355
  {
2204
2356
  className: "gantt-tl-cell gantt-tl-cell-deps",
2205
- onClick: isPicking && !isSourceRow ? handlePredecessorPick : void 0,
2357
+ onClick: isSourceRow ? handleCancelPicking : isPicking ? handlePredecessorPick : void 0,
2206
2358
  children: isSourceRow ? /* @__PURE__ */ jsx12("span", { className: "gantt-tl-dep-source-hint", children: "\u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u0437\u0430\u0434\u0430\u0447\u0443" }) : isSelectedPredecessor && !disableDependencyEditing ? (
2207
2359
  /* Full-replacement: "Зависит от [name]" → hover → "Удалить" */
2208
2360
  /* @__PURE__ */ jsxs9(
@@ -2279,7 +2431,7 @@ var TaskListRow = React9.memo(
2279
2431
  "button",
2280
2432
  {
2281
2433
  type: "button",
2282
- className: "gantt-tl-dep-add",
2434
+ className: `gantt-tl-dep-add gantt-tl-dep-add-hover${selectedChip ? " gantt-tl-dep-add-hidden" : ""}`,
2283
2435
  onClick: handleAddClick,
2284
2436
  "aria-label": "\u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0441\u0432\u044F\u0437\u044C",
2285
2437
  children: "+"
@@ -2295,14 +2447,68 @@ var TaskListRow = React9.memo(
2295
2447
  );
2296
2448
  TaskListRow.displayName = "TaskListRow";
2297
2449
 
2298
- // src/components/TaskList/TaskList.tsx
2450
+ // src/components/TaskList/NewTaskRow.tsx
2451
+ import { useState as useState5, useRef as useRef4, useEffect as useEffect4 } from "react";
2299
2452
  import { jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
2453
+ var NewTaskRow = ({ rowHeight, onConfirm, onCancel }) => {
2454
+ const [nameValue, setNameValue] = useState5("");
2455
+ const inputRef = useRef4(null);
2456
+ const confirmedRef = useRef4(false);
2457
+ useEffect4(() => {
2458
+ if (inputRef.current) {
2459
+ inputRef.current.focus();
2460
+ inputRef.current.select();
2461
+ }
2462
+ }, []);
2463
+ const handleKeyDown = (e) => {
2464
+ if (e.key === "Enter") {
2465
+ if (nameValue.trim()) {
2466
+ confirmedRef.current = true;
2467
+ onConfirm(nameValue.trim());
2468
+ } else {
2469
+ onCancel();
2470
+ }
2471
+ } else if (e.key === "Escape") {
2472
+ onCancel();
2473
+ }
2474
+ };
2475
+ const handleBlur = () => {
2476
+ if (confirmedRef.current) return;
2477
+ if (nameValue.trim()) {
2478
+ confirmedRef.current = true;
2479
+ onConfirm(nameValue.trim());
2480
+ } else {
2481
+ onCancel();
2482
+ }
2483
+ };
2484
+ return /* @__PURE__ */ jsxs10("div", { className: "gantt-tl-row gantt-tl-row-new", style: { minHeight: `${rowHeight}px` }, children: [
2485
+ /* @__PURE__ */ jsx13("div", { className: "gantt-tl-cell gantt-tl-cell-number" }),
2486
+ /* @__PURE__ */ jsx13("div", { className: "gantt-tl-cell gantt-tl-cell-name gantt-tl-cell-new-name", children: /* @__PURE__ */ jsx13(
2487
+ Input,
2488
+ {
2489
+ ref: inputRef,
2490
+ value: nameValue,
2491
+ onChange: (e) => setNameValue(e.target.value),
2492
+ onKeyDown: handleKeyDown,
2493
+ onBlur: handleBlur,
2494
+ placeholder: "\u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435",
2495
+ className: "gantt-tl-name-input"
2496
+ }
2497
+ ) }),
2498
+ /* @__PURE__ */ jsx13("div", { className: "gantt-tl-cell" }),
2499
+ /* @__PURE__ */ jsx13("div", { className: "gantt-tl-cell" }),
2500
+ /* @__PURE__ */ jsx13("div", { className: "gantt-tl-cell" })
2501
+ ] });
2502
+ };
2503
+
2504
+ // src/components/TaskList/TaskList.tsx
2505
+ import { jsx as jsx14, jsxs as jsxs11 } from "react/jsx-runtime";
2300
2506
  var LINK_TYPE_ORDER = ["FS", "SS", "FF", "SF"];
2301
2507
  var TaskList = ({
2302
2508
  tasks,
2303
2509
  rowHeight,
2304
2510
  headerHeight,
2305
- taskListWidth = 520,
2511
+ taskListWidth = 472,
2306
2512
  onTaskChange,
2307
2513
  selectedTaskId,
2308
2514
  onTaskSelect,
@@ -2310,7 +2516,11 @@ var TaskList = ({
2310
2516
  disableTaskNameEditing = false,
2311
2517
  disableDependencyEditing = false,
2312
2518
  onScrollToTask,
2313
- onSelectedChipChange
2519
+ onSelectedChipChange,
2520
+ onAdd,
2521
+ onDelete,
2522
+ onInsertAfter,
2523
+ editingTaskId: propEditingTaskId
2314
2524
  }) => {
2315
2525
  const totalHeight = useMemo8(
2316
2526
  () => tasks.length * rowHeight,
@@ -2319,17 +2529,17 @@ var TaskList = ({
2319
2529
  const handleRowClick = useCallback5((taskId) => {
2320
2530
  onTaskSelect?.(taskId);
2321
2531
  }, [onTaskSelect]);
2322
- const [activeLinkType, setActiveLinkType] = useState5("FS");
2323
- const [selectingPredecessorFor, setSelectingPredecessorFor] = useState5(null);
2324
- const [typeMenuOpen, setTypeMenuOpen] = useState5(false);
2325
- const [cycleError, setCycleError] = useState5(false);
2326
- const overlayRef = useRef4(null);
2327
- const [selectedChip, setSelectedChip] = useState5(null);
2532
+ const [activeLinkType, setActiveLinkType] = useState6("FS");
2533
+ const [selectingPredecessorFor, setSelectingPredecessorFor] = useState6(null);
2534
+ const [typeMenuOpen, setTypeMenuOpen] = useState6(false);
2535
+ const [cycleError, setCycleError] = useState6(false);
2536
+ const overlayRef = useRef5(null);
2537
+ const [selectedChip, setSelectedChip] = useState6(null);
2328
2538
  const handleChipSelect = useCallback5((chip) => {
2329
2539
  setSelectedChip(chip);
2330
2540
  onSelectedChipChange?.(chip);
2331
2541
  }, [onSelectedChipChange]);
2332
- useEffect4(() => {
2542
+ useEffect5(() => {
2333
2543
  if (!selectingPredecessorFor && !selectedChip) return;
2334
2544
  const handleKeyDown = (e) => {
2335
2545
  if (e.key === "Escape") {
@@ -2410,21 +2620,44 @@ var TaskList = ({
2410
2620
  );
2411
2621
  onTaskChange?.({ ...task, dependencies: updatedDeps });
2412
2622
  }, [tasks, onTaskChange]);
2413
- return /* @__PURE__ */ jsx13(
2623
+ const [isCreating, setIsCreating] = useState6(false);
2624
+ const handleConfirmNewTask = useCallback5((name) => {
2625
+ const now = /* @__PURE__ */ new Date();
2626
+ const todayISO = new Date(Date.UTC(
2627
+ now.getUTCFullYear(),
2628
+ now.getUTCMonth(),
2629
+ now.getUTCDate()
2630
+ )).toISOString().split("T")[0];
2631
+ const endISO = new Date(Date.UTC(
2632
+ now.getUTCFullYear(),
2633
+ now.getUTCMonth(),
2634
+ now.getUTCDate() + 7
2635
+ )).toISOString().split("T")[0];
2636
+ const newTask = {
2637
+ id: crypto.randomUUID(),
2638
+ name,
2639
+ startDate: todayISO,
2640
+ endDate: endISO
2641
+ };
2642
+ onAdd?.(newTask);
2643
+ setIsCreating(false);
2644
+ }, [onAdd]);
2645
+ const handleCancelNewTask = useCallback5(() => setIsCreating(false), []);
2646
+ return /* @__PURE__ */ jsx14(
2414
2647
  "div",
2415
2648
  {
2416
2649
  ref: overlayRef,
2417
2650
  className: `gantt-tl-overlay${show ? "" : " gantt-tl-hidden"}`,
2418
2651
  style: { width: `${taskListWidth}px` },
2419
- children: /* @__PURE__ */ jsxs10("div", { className: "gantt-tl-table", children: [
2420
- /* @__PURE__ */ jsxs10("div", { className: "gantt-tl-header", style: { height: `${headerHeight + 0.5}px` }, children: [
2421
- /* @__PURE__ */ jsx13("div", { className: "gantt-tl-headerCell gantt-tl-cell-number", children: "\u2116" }),
2422
- /* @__PURE__ */ jsx13("div", { className: "gantt-tl-headerCell gantt-tl-cell-name", children: "\u0418\u043C\u044F" }),
2423
- /* @__PURE__ */ jsx13("div", { className: "gantt-tl-headerCell gantt-tl-cell-date", children: "\u041D\u0430\u0447\u0430\u043B\u043E" }),
2424
- /* @__PURE__ */ jsx13("div", { className: "gantt-tl-headerCell gantt-tl-cell-date", children: "\u041E\u043A\u043E\u043D\u0447\u0430\u043D\u0438\u0435" }),
2425
- /* @__PURE__ */ jsxs10("div", { className: "gantt-tl-headerCell gantt-tl-cell-deps", style: { position: "relative" }, children: [
2426
- /* @__PURE__ */ jsxs10(Popover, { open: typeMenuOpen, onOpenChange: setTypeMenuOpen, children: [
2427
- /* @__PURE__ */ jsx13(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs10(
2652
+ children: /* @__PURE__ */ jsxs11("div", { className: "gantt-tl-table", children: [
2653
+ /* @__PURE__ */ jsxs11("div", { className: "gantt-tl-header", style: { height: `${headerHeight + 0.5}px` }, children: [
2654
+ /* @__PURE__ */ jsx14("div", { className: "gantt-tl-headerCell gantt-tl-cell-number", children: "\u2116" }),
2655
+ /* @__PURE__ */ jsx14("div", { className: "gantt-tl-headerCell gantt-tl-cell-name", children: "\u0418\u043C\u044F" }),
2656
+ /* @__PURE__ */ jsx14("div", { className: "gantt-tl-headerCell gantt-tl-cell-date", children: "\u041D\u0430\u0447\u0430\u043B\u043E" }),
2657
+ /* @__PURE__ */ jsx14("div", { className: "gantt-tl-headerCell gantt-tl-cell-date", children: "\u041E\u043A\u043E\u043D\u0447\u0430\u043D\u0438\u0435" }),
2658
+ /* @__PURE__ */ jsxs11("div", { className: "gantt-tl-headerCell gantt-tl-cell-deps", style: { position: "relative" }, children: [
2659
+ /* @__PURE__ */ jsxs11(Popover, { open: typeMenuOpen, onOpenChange: setTypeMenuOpen, children: [
2660
+ /* @__PURE__ */ jsx14(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs11(
2428
2661
  "button",
2429
2662
  {
2430
2663
  className: "gantt-tl-dep-type-trigger",
@@ -2432,12 +2665,12 @@ var TaskList = ({
2432
2665
  onClick: (e) => e.stopPropagation(),
2433
2666
  children: [
2434
2667
  "\u0421\u0432\u044F\u0437\u0438 ",
2435
- React10.createElement(LINK_TYPE_ICONS[activeLinkType]),
2668
+ React11.createElement(LINK_TYPE_ICONS[activeLinkType]),
2436
2669
  " \u25BE"
2437
2670
  ]
2438
2671
  }
2439
2672
  ) }),
2440
- /* @__PURE__ */ jsx13(PopoverContent, { portal: true, align: "start", children: /* @__PURE__ */ jsx13("div", { className: "gantt-tl-dep-type-menu", children: LINK_TYPE_ORDER.map((lt) => /* @__PURE__ */ jsxs10(
2673
+ /* @__PURE__ */ jsx14(PopoverContent, { portal: true, align: "start", children: /* @__PURE__ */ jsx14("div", { className: "gantt-tl-dep-type-menu", children: LINK_TYPE_ORDER.map((lt) => /* @__PURE__ */ jsxs11(
2441
2674
  "button",
2442
2675
  {
2443
2676
  className: `gantt-tl-dep-type-option${activeLinkType === lt ? " active" : ""}`,
@@ -2446,17 +2679,17 @@ var TaskList = ({
2446
2679
  setTypeMenuOpen(false);
2447
2680
  },
2448
2681
  children: [
2449
- React10.createElement(LINK_TYPE_ICONS[lt]),
2450
- /* @__PURE__ */ jsx13("span", { children: LINK_TYPE_LABELS[lt] })
2682
+ React11.createElement(LINK_TYPE_ICONS[lt]),
2683
+ /* @__PURE__ */ jsx14("span", { children: LINK_TYPE_LABELS[lt] })
2451
2684
  ]
2452
2685
  },
2453
2686
  lt
2454
2687
  )) }) })
2455
2688
  ] }),
2456
- cycleError && /* @__PURE__ */ jsx13("div", { className: "gantt-tl-dep-error", children: "\u0426\u0438\u043A\u043B \u0437\u0430\u0432\u0438\u0441\u0438\u043C\u043E\u0441\u0442\u0435\u0439!" })
2689
+ cycleError && /* @__PURE__ */ jsx14("div", { className: "gantt-tl-dep-error", children: "\u0426\u0438\u043A\u043B \u0437\u0430\u0432\u0438\u0441\u0438\u043C\u043E\u0441\u0442\u0435\u0439!" })
2457
2690
  ] })
2458
2691
  ] }),
2459
- /* @__PURE__ */ jsx13("div", { className: "gantt-tl-body", style: { height: `${totalHeight}px` }, children: tasks.map((task, index) => /* @__PURE__ */ jsx13(
2692
+ /* @__PURE__ */ jsx14("div", { className: "gantt-tl-body", style: { height: `${totalHeight}px` }, children: tasks.map((task, index) => /* @__PURE__ */ jsx14(
2460
2693
  TaskListRow,
2461
2694
  {
2462
2695
  task,
@@ -2475,17 +2708,38 @@ var TaskList = ({
2475
2708
  onRemoveDependency: handleRemoveDependency,
2476
2709
  selectedChip,
2477
2710
  onChipSelect: handleChipSelect,
2478
- onScrollToTask
2711
+ onScrollToTask,
2712
+ onDelete,
2713
+ onAdd,
2714
+ onInsertAfter,
2715
+ editingTaskId: propEditingTaskId
2479
2716
  },
2480
2717
  task.id
2481
- )) })
2718
+ )) }),
2719
+ isCreating && /* @__PURE__ */ jsx14(
2720
+ NewTaskRow,
2721
+ {
2722
+ rowHeight,
2723
+ onConfirm: handleConfirmNewTask,
2724
+ onCancel: handleCancelNewTask
2725
+ }
2726
+ ),
2727
+ onAdd && !isCreating && /* @__PURE__ */ jsx14(
2728
+ "button",
2729
+ {
2730
+ className: "gantt-tl-add-btn",
2731
+ onClick: () => setIsCreating(true),
2732
+ type: "button",
2733
+ children: "+ \u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0437\u0430\u0434\u0430\u0447\u0443"
2734
+ }
2735
+ )
2482
2736
  ] })
2483
2737
  }
2484
2738
  );
2485
2739
  };
2486
2740
 
2487
2741
  // src/components/GanttChart/GanttChart.tsx
2488
- import { jsx as jsx14, jsxs as jsxs11 } from "react/jsx-runtime";
2742
+ import { jsx as jsx15, jsxs as jsxs12 } from "react/jsx-runtime";
2489
2743
  var GanttChart = forwardRef(({
2490
2744
  tasks,
2491
2745
  dayWidth = 40,
@@ -2501,14 +2755,18 @@ var GanttChart = forwardRef(({
2501
2755
  taskListWidth = 520,
2502
2756
  disableTaskNameEditing = false,
2503
2757
  disableDependencyEditing = false,
2504
- highlightExpiredTasks = false
2758
+ highlightExpiredTasks = false,
2759
+ onAdd,
2760
+ onDelete,
2761
+ onInsertAfter,
2762
+ editingTaskId
2505
2763
  }, ref) => {
2506
- const scrollContainerRef = useRef5(null);
2507
- const [selectedTaskId, setSelectedTaskId] = useState6(null);
2508
- const [selectedChip, setSelectedChip] = useState6(null);
2764
+ const scrollContainerRef = useRef6(null);
2765
+ const [selectedTaskId, setSelectedTaskId] = useState7(null);
2766
+ const [selectedChip, setSelectedChip] = useState7(null);
2509
2767
  const dateRange = useMemo9(() => getMultiMonthDays(tasks), [tasks]);
2510
- const [validationResult, setValidationResult] = useState6(null);
2511
- const [cascadeOverrides, setCascadeOverrides] = useState6(/* @__PURE__ */ new Map());
2768
+ const [validationResult, setValidationResult] = useState7(null);
2769
+ const [cascadeOverrides, setCascadeOverrides] = useState7(/* @__PURE__ */ new Map());
2512
2770
  const gridWidth = useMemo9(
2513
2771
  () => Math.round(dateRange.length * dayWidth),
2514
2772
  [dateRange.length, dayWidth]
@@ -2529,7 +2787,7 @@ var GanttChart = forwardRef(({
2529
2787
  const today = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()));
2530
2788
  return dateRange.some((day) => day.getTime() === today.getTime());
2531
2789
  }, [dateRange]);
2532
- useEffect5(() => {
2790
+ useEffect6(() => {
2533
2791
  const container = scrollContainerRef.current;
2534
2792
  if (!container || dateRange.length === 0) return;
2535
2793
  const now = /* @__PURE__ */ new Date();
@@ -2551,7 +2809,7 @@ var GanttChart = forwardRef(({
2551
2809
  const todayOffset = todayIndex * dayWidth;
2552
2810
  const containerWidth = container.clientWidth;
2553
2811
  const scrollLeft = Math.round(todayOffset - containerWidth / 2 + dayWidth / 2);
2554
- container.scrollLeft = Math.max(0, scrollLeft);
2812
+ container.scrollTo({ left: Math.max(0, scrollLeft), behavior: "smooth" });
2555
2813
  }, [dateRange, dayWidth]);
2556
2814
  const scrollToTask = useCallback6((taskId) => {
2557
2815
  const container = scrollContainerRef.current;
@@ -2568,7 +2826,7 @@ var GanttChart = forwardRef(({
2568
2826
  if (taskIndex === -1) return;
2569
2827
  const taskOffset = taskIndex * dayWidth;
2570
2828
  const scrollLeft = Math.round(taskOffset - dayWidth * 2);
2571
- container.scrollLeft = Math.max(0, scrollLeft);
2829
+ container.scrollTo({ left: Math.max(0, scrollLeft), behavior: "smooth" });
2572
2830
  }, [tasks, dateRange, dayWidth]);
2573
2831
  useImperativeHandle(
2574
2832
  ref,
@@ -2578,9 +2836,9 @@ var GanttChart = forwardRef(({
2578
2836
  }),
2579
2837
  [scrollToToday, scrollToTask]
2580
2838
  );
2581
- const [dragGuideLines, setDragGuideLines] = useState6(null);
2582
- const [draggedTaskOverride, setDraggedTaskOverride] = useState6(null);
2583
- useEffect5(() => {
2839
+ const [dragGuideLines, setDragGuideLines] = useState7(null);
2840
+ const [draggedTaskOverride, setDraggedTaskOverride] = useState7(null);
2841
+ useEffect6(() => {
2584
2842
  const result = validateDependencies(tasks);
2585
2843
  setValidationResult(result);
2586
2844
  onValidateDependencies?.(result);
@@ -2596,41 +2854,16 @@ var GanttChart = forwardRef(({
2596
2854
  const newStart = new Date(updatedTask.startDate);
2597
2855
  const newEnd = new Date(updatedTask.endDate);
2598
2856
  const datesChanged = origStart.getTime() !== newStart.getTime() || origEnd.getTime() !== newEnd.getTime();
2599
- const now = /* @__PURE__ */ new Date();
2600
- const today = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()));
2601
- const msPerDay = 1e3 * 60 * 60 * 24;
2602
- let tasksToProcess;
2603
- let cascadedTasksForCallback = [];
2604
2857
  if (!datesChanged) {
2605
2858
  onChange?.((currentTasks) => currentTasks.map((t) => t.id === updatedTask.id ? updatedTask : t));
2606
2859
  return;
2607
2860
  }
2861
+ let cascadedTasksForCallback;
2608
2862
  if (disableConstraints) {
2609
- tasksToProcess = [updatedTask];
2610
2863
  cascadedTasksForCallback = [updatedTask];
2611
2864
  } else {
2612
- const cascadedTask = updatedTask;
2613
2865
  const cascadedChain = cascadeByLinks(updatedTask.id, newStart, newEnd, tasks);
2614
- tasksToProcess = [cascadedTask, ...cascadedChain];
2615
- cascadedTasksForCallback = tasksToProcess;
2616
- }
2617
- console.log("[GanttChart handleTaskChange] IsExpired calculation:");
2618
- for (const t of tasksToProcess) {
2619
- const taskStart = new Date(t.startDate);
2620
- const taskEnd = new Date(t.endDate);
2621
- const actualProgress = t.progress ?? 0;
2622
- if (actualProgress >= 100) {
2623
- console.log(` [${t.id}] START=${t.startDate} END=${t.endDate} TODAY=${today.toISOString().split("T")[0]} PROGRESS=${actualProgress}% EXPECTED=N/A (completed) EXPIRED=NO`);
2624
- continue;
2625
- }
2626
- const duration = taskEnd.getTime() - taskStart.getTime() + msPerDay;
2627
- const elapsedFromToday = today.getTime() - taskStart.getTime();
2628
- const elapsed = Math.min(Math.max(0, elapsedFromToday), duration);
2629
- const expectedProgress = Math.min(100, Math.max(0, elapsed / duration * 100));
2630
- const isExpired = actualProgress < expectedProgress;
2631
- const durationDays = Math.round(duration / msPerDay);
2632
- const elapsedDays = Math.round(elapsed / msPerDay);
2633
- console.log(` [${t.id}] START=${t.startDate} END=${t.endDate} TODAY=${today.toISOString().split("T")[0]} PROGRESS=${actualProgress}% DURATION=${durationDays}d ELAPSED=${elapsedDays}d EXPECTED=${expectedProgress.toFixed(1)}% EXPIRED=${isExpired ? "YES" : "NO"}`);
2866
+ cascadedTasksForCallback = [updatedTask, ...cascadedChain];
2634
2867
  }
2635
2868
  if (disableConstraints) {
2636
2869
  onChange?.((currentTasks) => currentTasks.map((t) => t.id === updatedTask.id ? updatedTask : t));
@@ -2642,6 +2875,15 @@ var GanttChart = forwardRef(({
2642
2875
  onCascade?.(cascadedTasksForCallback);
2643
2876
  }
2644
2877
  }, [tasks, onChange, disableConstraints, onCascade]);
2878
+ const handleDelete = useCallback6((taskId) => {
2879
+ onChange?.(
2880
+ (currentTasks) => currentTasks.filter((t) => t.id !== taskId).map((t) => ({
2881
+ ...t,
2882
+ dependencies: (t.dependencies ?? []).filter((d) => d.taskId !== taskId)
2883
+ }))
2884
+ );
2885
+ onDelete?.(taskId);
2886
+ }, [onChange, onDelete]);
2645
2887
  const dependencyOverrides = useMemo9(() => {
2646
2888
  const map = new Map(cascadeOverrides);
2647
2889
  if (draggedTaskOverride) {
@@ -2665,7 +2907,7 @@ var GanttChart = forwardRef(({
2665
2907
  const handleTaskSelect = useCallback6((taskId) => {
2666
2908
  setSelectedTaskId(taskId);
2667
2909
  }, []);
2668
- const panStateRef = useRef5(null);
2910
+ const panStateRef = useRef6(null);
2669
2911
  const handlePanStart = useCallback6((e) => {
2670
2912
  if (e.button !== 0) return;
2671
2913
  const target = e.target;
@@ -2687,7 +2929,7 @@ var GanttChart = forwardRef(({
2687
2929
  container.style.cursor = "grabbing";
2688
2930
  e.preventDefault();
2689
2931
  }, []);
2690
- useEffect5(() => {
2932
+ useEffect6(() => {
2691
2933
  const handlePanMove = (e) => {
2692
2934
  const pan = panStateRef.current;
2693
2935
  if (!pan?.active) return;
@@ -2709,15 +2951,15 @@ var GanttChart = forwardRef(({
2709
2951
  window.removeEventListener("mouseup", handlePanEnd);
2710
2952
  };
2711
2953
  }, []);
2712
- return /* @__PURE__ */ jsx14("div", { className: "gantt-container", children: /* @__PURE__ */ jsx14(
2954
+ return /* @__PURE__ */ jsx15("div", { className: "gantt-container", children: /* @__PURE__ */ jsx15(
2713
2955
  "div",
2714
2956
  {
2715
2957
  ref: scrollContainerRef,
2716
2958
  className: "gantt-scrollContainer",
2717
2959
  style: { height: containerHeight ?? "auto", cursor: "grab" },
2718
2960
  onMouseDown: handlePanStart,
2719
- children: /* @__PURE__ */ jsxs11("div", { className: "gantt-scrollContent", children: [
2720
- /* @__PURE__ */ jsx14(
2961
+ children: /* @__PURE__ */ jsxs12("div", { className: "gantt-scrollContent", children: [
2962
+ /* @__PURE__ */ jsx15(
2721
2963
  TaskList,
2722
2964
  {
2723
2965
  tasks,
@@ -2731,11 +2973,15 @@ var GanttChart = forwardRef(({
2731
2973
  disableTaskNameEditing,
2732
2974
  disableDependencyEditing,
2733
2975
  onScrollToTask: scrollToTask,
2734
- onSelectedChipChange: setSelectedChip
2976
+ onSelectedChipChange: setSelectedChip,
2977
+ onAdd,
2978
+ onDelete: handleDelete,
2979
+ onInsertAfter,
2980
+ editingTaskId
2735
2981
  }
2736
2982
  ),
2737
- /* @__PURE__ */ jsxs11("div", { style: { minWidth: `${gridWidth}px`, flex: 1 }, children: [
2738
- /* @__PURE__ */ jsx14("div", { className: "gantt-stickyHeader", style: { width: `${gridWidth}px` }, children: /* @__PURE__ */ jsx14(
2983
+ /* @__PURE__ */ jsxs12("div", { style: { minWidth: `${gridWidth}px`, flex: 1 }, children: [
2984
+ /* @__PURE__ */ jsx15("div", { className: "gantt-stickyHeader", style: { width: `${gridWidth}px` }, children: /* @__PURE__ */ jsx15(
2739
2985
  TimeScaleHeader_default,
2740
2986
  {
2741
2987
  days: dateRange,
@@ -2743,7 +2989,7 @@ var GanttChart = forwardRef(({
2743
2989
  headerHeight
2744
2990
  }
2745
2991
  ) }),
2746
- /* @__PURE__ */ jsxs11(
2992
+ /* @__PURE__ */ jsxs12(
2747
2993
  "div",
2748
2994
  {
2749
2995
  className: "gantt-taskArea",
@@ -2752,7 +2998,7 @@ var GanttChart = forwardRef(({
2752
2998
  width: `${gridWidth}px`
2753
2999
  },
2754
3000
  children: [
2755
- /* @__PURE__ */ jsx14(
3001
+ /* @__PURE__ */ jsx15(
2756
3002
  GridBackground_default,
2757
3003
  {
2758
3004
  dateRange,
@@ -2760,8 +3006,8 @@ var GanttChart = forwardRef(({
2760
3006
  totalHeight: totalGridHeight
2761
3007
  }
2762
3008
  ),
2763
- todayInRange && /* @__PURE__ */ jsx14(TodayIndicator_default, { monthStart, dayWidth }),
2764
- /* @__PURE__ */ jsx14(
3009
+ todayInRange && /* @__PURE__ */ jsx15(TodayIndicator_default, { monthStart, dayWidth }),
3010
+ /* @__PURE__ */ jsx15(
2765
3011
  DependencyLines_default,
2766
3012
  {
2767
3013
  tasks,
@@ -2773,7 +3019,7 @@ var GanttChart = forwardRef(({
2773
3019
  selectedDep: selectedChip
2774
3020
  }
2775
3021
  ),
2776
- dragGuideLines && /* @__PURE__ */ jsx14(
3022
+ dragGuideLines && /* @__PURE__ */ jsx15(
2777
3023
  DragGuideLines_default,
2778
3024
  {
2779
3025
  isDragging: dragGuideLines.isDragging,
@@ -2783,7 +3029,7 @@ var GanttChart = forwardRef(({
2783
3029
  totalHeight: totalGridHeight
2784
3030
  }
2785
3031
  ),
2786
- tasks.map((task, index) => /* @__PURE__ */ jsx14(
3032
+ tasks.map((task, index) => /* @__PURE__ */ jsx15(
2787
3033
  TaskRow_default,
2788
3034
  {
2789
3035
  task,
@@ -2822,9 +3068,9 @@ var GanttChart = forwardRef(({
2822
3068
  GanttChart.displayName = "GanttChart";
2823
3069
 
2824
3070
  // src/components/ui/Button.tsx
2825
- import React12 from "react";
2826
- import { jsx as jsx15 } from "react/jsx-runtime";
2827
- var Button = React12.forwardRef(
3071
+ import React13 from "react";
3072
+ import { jsx as jsx16 } from "react/jsx-runtime";
3073
+ var Button = React13.forwardRef(
2828
3074
  ({ className, variant = "default", size = "default", children, ...props }, ref) => {
2829
3075
  const classes = [
2830
3076
  "gantt-btn",
@@ -2832,7 +3078,7 @@ var Button = React12.forwardRef(
2832
3078
  size !== "default" ? `gantt-btn-${size}` : "",
2833
3079
  className || ""
2834
3080
  ].filter(Boolean).join(" ");
2835
- return /* @__PURE__ */ jsx15("button", { ref, className: classes, ...props, children });
3081
+ return /* @__PURE__ */ jsx16("button", { ref, className: classes, ...props, children });
2836
3082
  }
2837
3083
  );
2838
3084
  Button.displayName = "Button";