gantt-lib 0.3.4 → 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.css.map +1 -1
- package/dist/index.d.mts +19 -1
- package/dist/index.d.ts +19 -1
- package/dist/index.js +422 -152
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +403 -132
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +106 -23
- package/package.json +1 -1
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
|
|
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.
|
|
46
|
-
now.
|
|
47
|
-
now.
|
|
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.
|
|
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;
|
|
@@ -1609,7 +1609,7 @@ DependencyLines.displayName = "DependencyLines";
|
|
|
1609
1609
|
var DependencyLines_default = DependencyLines;
|
|
1610
1610
|
|
|
1611
1611
|
// src/components/TaskList/TaskList.tsx
|
|
1612
|
-
import
|
|
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
|
-
|
|
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
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
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(
|
|
1963
|
-
|
|
1964
|
-
|
|
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
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
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")
|
|
2081
|
-
|
|
2082
|
-
|
|
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
|
-
|
|
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__ */
|
|
2254
|
+
/* @__PURE__ */ jsx12(
|
|
2141
2255
|
"div",
|
|
2142
2256
|
{
|
|
2143
2257
|
className: "gantt-tl-cell gantt-tl-cell-number",
|
|
2144
2258
|
onClick: handleNumberClick,
|
|
2145
|
-
|
|
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:
|
|
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/
|
|
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 =
|
|
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] =
|
|
2323
|
-
const [selectingPredecessorFor, setSelectingPredecessorFor] =
|
|
2324
|
-
const [typeMenuOpen, setTypeMenuOpen] =
|
|
2325
|
-
const [cycleError, setCycleError] =
|
|
2326
|
-
const overlayRef =
|
|
2327
|
-
const [selectedChip, setSelectedChip] =
|
|
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
|
-
|
|
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
|
-
|
|
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__ */
|
|
2420
|
-
/* @__PURE__ */
|
|
2421
|
-
/* @__PURE__ */
|
|
2422
|
-
/* @__PURE__ */
|
|
2423
|
-
/* @__PURE__ */
|
|
2424
|
-
/* @__PURE__ */
|
|
2425
|
-
/* @__PURE__ */
|
|
2426
|
-
/* @__PURE__ */
|
|
2427
|
-
/* @__PURE__ */
|
|
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
|
-
|
|
2668
|
+
React11.createElement(LINK_TYPE_ICONS[activeLinkType]),
|
|
2436
2669
|
" \u25BE"
|
|
2437
2670
|
]
|
|
2438
2671
|
}
|
|
2439
2672
|
) }),
|
|
2440
|
-
/* @__PURE__ */
|
|
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
|
-
|
|
2450
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
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
|
|
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 =
|
|
2507
|
-
const [selectedTaskId, setSelectedTaskId] =
|
|
2508
|
-
const [selectedChip, setSelectedChip] =
|
|
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] =
|
|
2511
|
-
const [cascadeOverrides, setCascadeOverrides] =
|
|
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
|
-
|
|
2790
|
+
useEffect6(() => {
|
|
2533
2791
|
const container = scrollContainerRef.current;
|
|
2534
2792
|
if (!container || dateRange.length === 0) return;
|
|
2535
2793
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -2578,9 +2836,9 @@ var GanttChart = forwardRef(({
|
|
|
2578
2836
|
}),
|
|
2579
2837
|
[scrollToToday, scrollToTask]
|
|
2580
2838
|
);
|
|
2581
|
-
const [dragGuideLines, setDragGuideLines] =
|
|
2582
|
-
const [draggedTaskOverride, setDraggedTaskOverride] =
|
|
2583
|
-
|
|
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);
|
|
@@ -2617,6 +2875,15 @@ var GanttChart = forwardRef(({
|
|
|
2617
2875
|
onCascade?.(cascadedTasksForCallback);
|
|
2618
2876
|
}
|
|
2619
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]);
|
|
2620
2887
|
const dependencyOverrides = useMemo9(() => {
|
|
2621
2888
|
const map = new Map(cascadeOverrides);
|
|
2622
2889
|
if (draggedTaskOverride) {
|
|
@@ -2640,7 +2907,7 @@ var GanttChart = forwardRef(({
|
|
|
2640
2907
|
const handleTaskSelect = useCallback6((taskId) => {
|
|
2641
2908
|
setSelectedTaskId(taskId);
|
|
2642
2909
|
}, []);
|
|
2643
|
-
const panStateRef =
|
|
2910
|
+
const panStateRef = useRef6(null);
|
|
2644
2911
|
const handlePanStart = useCallback6((e) => {
|
|
2645
2912
|
if (e.button !== 0) return;
|
|
2646
2913
|
const target = e.target;
|
|
@@ -2662,7 +2929,7 @@ var GanttChart = forwardRef(({
|
|
|
2662
2929
|
container.style.cursor = "grabbing";
|
|
2663
2930
|
e.preventDefault();
|
|
2664
2931
|
}, []);
|
|
2665
|
-
|
|
2932
|
+
useEffect6(() => {
|
|
2666
2933
|
const handlePanMove = (e) => {
|
|
2667
2934
|
const pan = panStateRef.current;
|
|
2668
2935
|
if (!pan?.active) return;
|
|
@@ -2684,15 +2951,15 @@ var GanttChart = forwardRef(({
|
|
|
2684
2951
|
window.removeEventListener("mouseup", handlePanEnd);
|
|
2685
2952
|
};
|
|
2686
2953
|
}, []);
|
|
2687
|
-
return /* @__PURE__ */
|
|
2954
|
+
return /* @__PURE__ */ jsx15("div", { className: "gantt-container", children: /* @__PURE__ */ jsx15(
|
|
2688
2955
|
"div",
|
|
2689
2956
|
{
|
|
2690
2957
|
ref: scrollContainerRef,
|
|
2691
2958
|
className: "gantt-scrollContainer",
|
|
2692
2959
|
style: { height: containerHeight ?? "auto", cursor: "grab" },
|
|
2693
2960
|
onMouseDown: handlePanStart,
|
|
2694
|
-
children: /* @__PURE__ */
|
|
2695
|
-
/* @__PURE__ */
|
|
2961
|
+
children: /* @__PURE__ */ jsxs12("div", { className: "gantt-scrollContent", children: [
|
|
2962
|
+
/* @__PURE__ */ jsx15(
|
|
2696
2963
|
TaskList,
|
|
2697
2964
|
{
|
|
2698
2965
|
tasks,
|
|
@@ -2706,11 +2973,15 @@ var GanttChart = forwardRef(({
|
|
|
2706
2973
|
disableTaskNameEditing,
|
|
2707
2974
|
disableDependencyEditing,
|
|
2708
2975
|
onScrollToTask: scrollToTask,
|
|
2709
|
-
onSelectedChipChange: setSelectedChip
|
|
2976
|
+
onSelectedChipChange: setSelectedChip,
|
|
2977
|
+
onAdd,
|
|
2978
|
+
onDelete: handleDelete,
|
|
2979
|
+
onInsertAfter,
|
|
2980
|
+
editingTaskId
|
|
2710
2981
|
}
|
|
2711
2982
|
),
|
|
2712
|
-
/* @__PURE__ */
|
|
2713
|
-
/* @__PURE__ */
|
|
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(
|
|
2714
2985
|
TimeScaleHeader_default,
|
|
2715
2986
|
{
|
|
2716
2987
|
days: dateRange,
|
|
@@ -2718,7 +2989,7 @@ var GanttChart = forwardRef(({
|
|
|
2718
2989
|
headerHeight
|
|
2719
2990
|
}
|
|
2720
2991
|
) }),
|
|
2721
|
-
/* @__PURE__ */
|
|
2992
|
+
/* @__PURE__ */ jsxs12(
|
|
2722
2993
|
"div",
|
|
2723
2994
|
{
|
|
2724
2995
|
className: "gantt-taskArea",
|
|
@@ -2727,7 +2998,7 @@ var GanttChart = forwardRef(({
|
|
|
2727
2998
|
width: `${gridWidth}px`
|
|
2728
2999
|
},
|
|
2729
3000
|
children: [
|
|
2730
|
-
/* @__PURE__ */
|
|
3001
|
+
/* @__PURE__ */ jsx15(
|
|
2731
3002
|
GridBackground_default,
|
|
2732
3003
|
{
|
|
2733
3004
|
dateRange,
|
|
@@ -2735,8 +3006,8 @@ var GanttChart = forwardRef(({
|
|
|
2735
3006
|
totalHeight: totalGridHeight
|
|
2736
3007
|
}
|
|
2737
3008
|
),
|
|
2738
|
-
todayInRange && /* @__PURE__ */
|
|
2739
|
-
/* @__PURE__ */
|
|
3009
|
+
todayInRange && /* @__PURE__ */ jsx15(TodayIndicator_default, { monthStart, dayWidth }),
|
|
3010
|
+
/* @__PURE__ */ jsx15(
|
|
2740
3011
|
DependencyLines_default,
|
|
2741
3012
|
{
|
|
2742
3013
|
tasks,
|
|
@@ -2748,7 +3019,7 @@ var GanttChart = forwardRef(({
|
|
|
2748
3019
|
selectedDep: selectedChip
|
|
2749
3020
|
}
|
|
2750
3021
|
),
|
|
2751
|
-
dragGuideLines && /* @__PURE__ */
|
|
3022
|
+
dragGuideLines && /* @__PURE__ */ jsx15(
|
|
2752
3023
|
DragGuideLines_default,
|
|
2753
3024
|
{
|
|
2754
3025
|
isDragging: dragGuideLines.isDragging,
|
|
@@ -2758,7 +3029,7 @@ var GanttChart = forwardRef(({
|
|
|
2758
3029
|
totalHeight: totalGridHeight
|
|
2759
3030
|
}
|
|
2760
3031
|
),
|
|
2761
|
-
tasks.map((task, index) => /* @__PURE__ */
|
|
3032
|
+
tasks.map((task, index) => /* @__PURE__ */ jsx15(
|
|
2762
3033
|
TaskRow_default,
|
|
2763
3034
|
{
|
|
2764
3035
|
task,
|
|
@@ -2797,9 +3068,9 @@ var GanttChart = forwardRef(({
|
|
|
2797
3068
|
GanttChart.displayName = "GanttChart";
|
|
2798
3069
|
|
|
2799
3070
|
// src/components/ui/Button.tsx
|
|
2800
|
-
import
|
|
2801
|
-
import { jsx as
|
|
2802
|
-
var Button =
|
|
3071
|
+
import React13 from "react";
|
|
3072
|
+
import { jsx as jsx16 } from "react/jsx-runtime";
|
|
3073
|
+
var Button = React13.forwardRef(
|
|
2803
3074
|
({ className, variant = "default", size = "default", children, ...props }, ref) => {
|
|
2804
3075
|
const classes = [
|
|
2805
3076
|
"gantt-btn",
|
|
@@ -2807,7 +3078,7 @@ var Button = React12.forwardRef(
|
|
|
2807
3078
|
size !== "default" ? `gantt-btn-${size}` : "",
|
|
2808
3079
|
className || ""
|
|
2809
3080
|
].filter(Boolean).join(" ");
|
|
2810
|
-
return /* @__PURE__ */
|
|
3081
|
+
return /* @__PURE__ */ jsx16("button", { ref, className: classes, ...props, children });
|
|
2811
3082
|
}
|
|
2812
3083
|
);
|
|
2813
3084
|
Button.displayName = "Button";
|