gantt-lib 0.17.2 → 0.18.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.js +941 -444
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +948 -445
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +0 -40
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
1
3
|
"use client";
|
|
2
4
|
var __defProp = Object.defineProperty;
|
|
3
5
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -2391,7 +2393,13 @@ var PopoverContent = ({
|
|
|
2391
2393
|
|
|
2392
2394
|
// src/components/TaskList/TaskListRow.tsx
|
|
2393
2395
|
init_dateUtils();
|
|
2394
|
-
import React9, {
|
|
2396
|
+
import React9, {
|
|
2397
|
+
useState as useState4,
|
|
2398
|
+
useRef as useRef4,
|
|
2399
|
+
useEffect as useEffect4,
|
|
2400
|
+
useCallback as useCallback4,
|
|
2401
|
+
useMemo as useMemo7
|
|
2402
|
+
} from "react";
|
|
2395
2403
|
|
|
2396
2404
|
// src/components/ui/Input.tsx
|
|
2397
2405
|
import React6 from "react";
|
|
@@ -2828,18 +2836,49 @@ var DAY_MS2 = 24 * 60 * 60 * 1e3;
|
|
|
2828
2836
|
var getInclusiveDurationDays = (startDate, endDate) => {
|
|
2829
2837
|
const start = parseUTCDate(startDate);
|
|
2830
2838
|
const end = parseUTCDate(endDate);
|
|
2831
|
-
return Math.max(
|
|
2839
|
+
return Math.max(
|
|
2840
|
+
1,
|
|
2841
|
+
Math.round((end.getTime() - start.getTime()) / DAY_MS2) + 1
|
|
2842
|
+
);
|
|
2832
2843
|
};
|
|
2833
2844
|
var getEndDateFromDuration = (startDate, durationDays) => {
|
|
2834
2845
|
const start = parseUTCDate(startDate);
|
|
2835
2846
|
return new Date(start.getTime() + (durationDays - 1) * DAY_MS2).toISOString().split("T")[0];
|
|
2836
2847
|
};
|
|
2837
|
-
var TrashIcon = () => /* @__PURE__ */ jsxs9(
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
2848
|
+
var TrashIcon = () => /* @__PURE__ */ jsxs9(
|
|
2849
|
+
"svg",
|
|
2850
|
+
{
|
|
2851
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2852
|
+
width: "12",
|
|
2853
|
+
height: "12",
|
|
2854
|
+
viewBox: "0 0 24 24",
|
|
2855
|
+
fill: "none",
|
|
2856
|
+
stroke: "currentColor",
|
|
2857
|
+
strokeWidth: "2",
|
|
2858
|
+
strokeLinecap: "round",
|
|
2859
|
+
strokeLinejoin: "round",
|
|
2860
|
+
children: [
|
|
2861
|
+
/* @__PURE__ */ jsx12("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6" }),
|
|
2862
|
+
/* @__PURE__ */ jsx12("path", { d: "M3 6h18" }),
|
|
2863
|
+
/* @__PURE__ */ jsx12("path", { d: "M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" })
|
|
2864
|
+
]
|
|
2865
|
+
}
|
|
2866
|
+
);
|
|
2867
|
+
var PlusIcon = () => /* @__PURE__ */ jsx12(
|
|
2868
|
+
"svg",
|
|
2869
|
+
{
|
|
2870
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2871
|
+
width: "14",
|
|
2872
|
+
height: "14",
|
|
2873
|
+
viewBox: "0 0 24 24",
|
|
2874
|
+
fill: "none",
|
|
2875
|
+
stroke: "currentColor",
|
|
2876
|
+
strokeWidth: "2",
|
|
2877
|
+
strokeLinecap: "round",
|
|
2878
|
+
strokeLinejoin: "round",
|
|
2879
|
+
children: /* @__PURE__ */ jsx12("path", { d: "M12 5v14M5 12h14" })
|
|
2880
|
+
}
|
|
2881
|
+
);
|
|
2843
2882
|
var DragHandleIcon = () => /* @__PURE__ */ jsxs9("svg", { width: "10", height: "14", viewBox: "0 0 10 14", fill: "currentColor", children: [
|
|
2844
2883
|
/* @__PURE__ */ jsx12("circle", { cx: "2", cy: "2", r: "1.5" }),
|
|
2845
2884
|
/* @__PURE__ */ jsx12("circle", { cx: "8", cy: "2", r: "1.5" }),
|
|
@@ -2848,51 +2887,94 @@ var DragHandleIcon = () => /* @__PURE__ */ jsxs9("svg", { width: "10", height: "
|
|
|
2848
2887
|
/* @__PURE__ */ jsx12("circle", { cx: "2", cy: "12", r: "1.5" }),
|
|
2849
2888
|
/* @__PURE__ */ jsx12("circle", { cx: "8", cy: "12", r: "1.5" })
|
|
2850
2889
|
] });
|
|
2851
|
-
var ChevronRightIcon = () => /* @__PURE__ */ jsx12(
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2890
|
+
var ChevronRightIcon = () => /* @__PURE__ */ jsx12(
|
|
2891
|
+
"svg",
|
|
2892
|
+
{
|
|
2893
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2894
|
+
width: "14",
|
|
2895
|
+
height: "14",
|
|
2896
|
+
viewBox: "0 0 24 24",
|
|
2897
|
+
fill: "none",
|
|
2898
|
+
stroke: "currentColor",
|
|
2899
|
+
strokeWidth: "2",
|
|
2900
|
+
strokeLinecap: "round",
|
|
2901
|
+
strokeLinejoin: "round",
|
|
2902
|
+
children: /* @__PURE__ */ jsx12("path", { d: "m9 18 6-6-6-6" })
|
|
2903
|
+
}
|
|
2904
|
+
);
|
|
2905
|
+
var ArrowLeft = () => /* @__PURE__ */ jsxs9(
|
|
2906
|
+
"svg",
|
|
2907
|
+
{
|
|
2908
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2909
|
+
width: "16",
|
|
2910
|
+
height: "16",
|
|
2911
|
+
viewBox: "0 0 24 24",
|
|
2912
|
+
fill: "none",
|
|
2913
|
+
stroke: "currentColor",
|
|
2914
|
+
strokeWidth: "2",
|
|
2915
|
+
strokeLinecap: "round",
|
|
2916
|
+
strokeLinejoin: "round",
|
|
2917
|
+
children: [
|
|
2918
|
+
/* @__PURE__ */ jsx12("path", { d: "m12 19-7-7 7-7" }),
|
|
2919
|
+
/* @__PURE__ */ jsx12("path", { d: "M19 12H5" })
|
|
2920
|
+
]
|
|
2921
|
+
}
|
|
2922
|
+
);
|
|
2923
|
+
var ArrowRight = () => /* @__PURE__ */ jsxs9(
|
|
2924
|
+
"svg",
|
|
2925
|
+
{
|
|
2926
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2927
|
+
width: "16",
|
|
2928
|
+
height: "16",
|
|
2929
|
+
viewBox: "0 0 24 24",
|
|
2930
|
+
fill: "none",
|
|
2931
|
+
stroke: "currentColor",
|
|
2932
|
+
strokeWidth: "2",
|
|
2933
|
+
strokeLinecap: "round",
|
|
2934
|
+
strokeLinejoin: "round",
|
|
2935
|
+
children: [
|
|
2936
|
+
/* @__PURE__ */ jsx12("path", { d: "M5 12h14" }),
|
|
2937
|
+
/* @__PURE__ */ jsx12("path", { d: "m12 5 7 7-7 7" })
|
|
2938
|
+
]
|
|
2939
|
+
}
|
|
2940
|
+
);
|
|
2857
2941
|
var HierarchyButton = ({
|
|
2858
2942
|
isChild,
|
|
2859
|
-
|
|
2860
|
-
rowIndex,
|
|
2943
|
+
rowIndex: _rowIndex,
|
|
2861
2944
|
onPromote,
|
|
2862
2945
|
onDemote
|
|
2863
2946
|
}) => {
|
|
2864
2947
|
const canPromote = isChild && onPromote;
|
|
2865
|
-
const canDemote =
|
|
2866
|
-
if (!canPromote && !canDemote)
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2948
|
+
const canDemote = !!onDemote;
|
|
2949
|
+
if (!canPromote && !canDemote) return null;
|
|
2950
|
+
return /* @__PURE__ */ jsxs9(Fragment2, { children: [
|
|
2951
|
+
canPromote && /* @__PURE__ */ jsx12(
|
|
2952
|
+
"button",
|
|
2953
|
+
{
|
|
2954
|
+
type: "button",
|
|
2955
|
+
className: "gantt-tl-name-action-btn gantt-tl-action-hierarchy",
|
|
2956
|
+
onClick: (e) => {
|
|
2957
|
+
e.stopPropagation();
|
|
2958
|
+
onPromote(e);
|
|
2959
|
+
},
|
|
2960
|
+
title: "\u041F\u043E\u0432\u044B\u0441\u0438\u0442\u044C \u0443\u0440\u043E\u0432\u0435\u043D\u044C",
|
|
2961
|
+
children: /* @__PURE__ */ jsx12(ArrowLeft, {})
|
|
2962
|
+
}
|
|
2963
|
+
),
|
|
2964
|
+
canDemote && /* @__PURE__ */ jsx12(
|
|
2965
|
+
"button",
|
|
2966
|
+
{
|
|
2967
|
+
type: "button",
|
|
2968
|
+
className: "gantt-tl-name-action-btn gantt-tl-action-hierarchy",
|
|
2969
|
+
onClick: (e) => {
|
|
2970
|
+
e.stopPropagation();
|
|
2971
|
+
onDemote(e);
|
|
2972
|
+
},
|
|
2973
|
+
title: "\u041F\u043E\u043D\u0438\u0437\u0438\u0442\u044C \u0443\u0440\u043E\u0432\u0435\u043D\u044C",
|
|
2974
|
+
children: /* @__PURE__ */ jsx12(ArrowRight, {})
|
|
2975
|
+
}
|
|
2976
|
+
)
|
|
2885
2977
|
] });
|
|
2886
|
-
return /* @__PURE__ */ jsx12(
|
|
2887
|
-
"button",
|
|
2888
|
-
{
|
|
2889
|
-
type: "button",
|
|
2890
|
-
className: "gantt-tl-name-action-btn gantt-tl-action-hierarchy",
|
|
2891
|
-
onClick: handleClick,
|
|
2892
|
-
title,
|
|
2893
|
-
children: canPromote ? /* @__PURE__ */ jsx12(ArrowLeft, {}) : /* @__PURE__ */ jsx12(ArrowRight, {})
|
|
2894
|
-
}
|
|
2895
|
-
);
|
|
2896
2978
|
};
|
|
2897
2979
|
var DepChip = ({
|
|
2898
2980
|
lag,
|
|
@@ -2924,71 +3006,91 @@ var DepChip = ({
|
|
|
2924
3006
|
const nextOpen = !popoverOpen;
|
|
2925
3007
|
setPopoverOpen(nextOpen);
|
|
2926
3008
|
if (nextOpen) {
|
|
2927
|
-
onChipSelect?.({
|
|
3009
|
+
onChipSelect?.({
|
|
3010
|
+
successorId: taskId,
|
|
3011
|
+
predecessorId: dep.taskId,
|
|
3012
|
+
linkType: dep.type
|
|
3013
|
+
});
|
|
2928
3014
|
onScrollToTask?.(dep.taskId);
|
|
2929
3015
|
} else {
|
|
2930
3016
|
onChipSelect?.(null);
|
|
2931
3017
|
}
|
|
2932
3018
|
};
|
|
2933
|
-
const handleOpenChange = useCallback4(
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
3019
|
+
const handleOpenChange = useCallback4(
|
|
3020
|
+
(open) => {
|
|
3021
|
+
setPopoverOpen(open);
|
|
3022
|
+
if (!open) {
|
|
3023
|
+
onChipSelect?.(null);
|
|
3024
|
+
}
|
|
3025
|
+
},
|
|
3026
|
+
[onChipSelect]
|
|
3027
|
+
);
|
|
2939
3028
|
const handleTrashClick = (e) => {
|
|
2940
3029
|
e.stopPropagation();
|
|
2941
3030
|
onRemoveDependency?.(taskId, dep.taskId, dep.type);
|
|
2942
3031
|
onChipSelectClear();
|
|
2943
3032
|
setPopoverOpen(false);
|
|
2944
3033
|
};
|
|
2945
|
-
const handleLagChange = useCallback4(
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
newStart
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
3034
|
+
const handleLagChange = useCallback4(
|
|
3035
|
+
(newLag) => {
|
|
3036
|
+
if (!onTasksChange || !allTasks) return;
|
|
3037
|
+
const taskById = new Map(allTasks.map((t) => [t.id, t]));
|
|
3038
|
+
const predecessor = taskById.get(dep.taskId);
|
|
3039
|
+
if (!predecessor) return;
|
|
3040
|
+
const predStart = parseUTCDate(predecessor.startDate);
|
|
3041
|
+
const predEnd = parseUTCDate(predecessor.endDate);
|
|
3042
|
+
const origStart = parseUTCDate(task.startDate);
|
|
3043
|
+
const origEnd = parseUTCDate(task.endDate);
|
|
3044
|
+
const durationMs = origEnd.getTime() - origStart.getTime();
|
|
3045
|
+
const constraintDate = calculateSuccessorDate(
|
|
3046
|
+
predStart,
|
|
3047
|
+
predEnd,
|
|
3048
|
+
dep.type,
|
|
3049
|
+
newLag
|
|
3050
|
+
);
|
|
3051
|
+
let newStart, newEnd;
|
|
3052
|
+
if (dep.type === "FS" || dep.type === "SS") {
|
|
3053
|
+
newStart = constraintDate;
|
|
3054
|
+
newEnd = new Date(constraintDate.getTime() + durationMs);
|
|
3055
|
+
} else {
|
|
3056
|
+
newEnd = constraintDate;
|
|
3057
|
+
newStart = new Date(constraintDate.getTime() - durationMs);
|
|
3058
|
+
}
|
|
3059
|
+
onTasksChange([
|
|
3060
|
+
{
|
|
3061
|
+
...task,
|
|
3062
|
+
startDate: newStart.toISOString().split("T")[0],
|
|
3063
|
+
endDate: newEnd.toISOString().split("T")[0]
|
|
3064
|
+
}
|
|
3065
|
+
]);
|
|
3066
|
+
},
|
|
3067
|
+
[dep, task, allTasks, onTasksChange]
|
|
3068
|
+
);
|
|
3069
|
+
const handleInputCommit = useCallback4(
|
|
3070
|
+
(raw) => {
|
|
3071
|
+
if (raw === "") {
|
|
3072
|
+
handleLagChange(0);
|
|
3073
|
+
return;
|
|
3074
|
+
}
|
|
3075
|
+
const parsed = parseInt(raw, 10);
|
|
3076
|
+
const effectiveLag2 = lag ?? 0;
|
|
3077
|
+
if (isNaN(parsed)) {
|
|
3078
|
+
const abs = Math.abs(effectiveLag2);
|
|
3079
|
+
setInputAbs(abs === 0 ? "" : String(abs));
|
|
3080
|
+
return;
|
|
3081
|
+
}
|
|
3082
|
+
let newLag;
|
|
3083
|
+
if (parsed === 0) {
|
|
3084
|
+
newLag = 0;
|
|
3085
|
+
} else if (dep.type === "SF") {
|
|
3086
|
+
newLag = -Math.abs(parsed);
|
|
3087
|
+
} else {
|
|
3088
|
+
newLag = parsed;
|
|
3089
|
+
}
|
|
3090
|
+
if (newLag !== effectiveLag2) handleLagChange(newLag);
|
|
3091
|
+
},
|
|
3092
|
+
[lag, dep.type, handleLagChange]
|
|
3093
|
+
);
|
|
2992
3094
|
const Icon = LINK_TYPE_ICONS[dep.type];
|
|
2993
3095
|
const depName = predecessorName ?? dep.taskId;
|
|
2994
3096
|
const effectiveLag = lag ?? 0;
|
|
@@ -3027,67 +3129,92 @@ var DepChip = ({
|
|
|
3027
3129
|
]
|
|
3028
3130
|
}
|
|
3029
3131
|
) }),
|
|
3030
|
-
/* @__PURE__ */ jsx12(
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3082
|
-
|
|
3132
|
+
/* @__PURE__ */ jsx12(
|
|
3133
|
+
PopoverContent,
|
|
3134
|
+
{
|
|
3135
|
+
className: "gantt-tl-dep-edit-popover",
|
|
3136
|
+
portal: true,
|
|
3137
|
+
align: "start",
|
|
3138
|
+
children: /* @__PURE__ */ jsxs9("div", { onClick: (e) => e.stopPropagation(), children: [
|
|
3139
|
+
/* @__PURE__ */ jsx12("div", { className: "gantt-tl-dep-edit-task", children: task.name }),
|
|
3140
|
+
/* @__PURE__ */ jsxs9("div", { className: "gantt-tl-dep-edit-row", children: [
|
|
3141
|
+
/* @__PURE__ */ jsxs9("span", { className: "gantt-tl-dep-edit-label", children: [
|
|
3142
|
+
actionVerb,
|
|
3143
|
+
preWord ? ` ${preWord}` : ""
|
|
3144
|
+
] }),
|
|
3145
|
+
/* @__PURE__ */ jsx12(
|
|
3146
|
+
"button",
|
|
3147
|
+
{
|
|
3148
|
+
type: "button",
|
|
3149
|
+
className: "gantt-tl-dep-edit-btn",
|
|
3150
|
+
onClick: () => handleLagChange(effectiveLag - 1),
|
|
3151
|
+
children: "\u2212"
|
|
3152
|
+
}
|
|
3153
|
+
),
|
|
3154
|
+
/* @__PURE__ */ jsx12(
|
|
3155
|
+
"input",
|
|
3156
|
+
{
|
|
3157
|
+
type: "number",
|
|
3158
|
+
className: "gantt-tl-dep-edit-input",
|
|
3159
|
+
value: inputAbs,
|
|
3160
|
+
placeholder: zeroPlaceholder,
|
|
3161
|
+
min: "0",
|
|
3162
|
+
onChange: (e) => setInputAbs(e.target.value),
|
|
3163
|
+
onFocus: (e) => e.target.select(),
|
|
3164
|
+
onBlur: (e) => handleInputCommit(e.target.value),
|
|
3165
|
+
onKeyDown: (e) => {
|
|
3166
|
+
if (e.key === "Enter") handleInputCommit(inputAbs);
|
|
3167
|
+
}
|
|
3168
|
+
}
|
|
3169
|
+
),
|
|
3170
|
+
!(dep.type === "SF" && effectiveLag === 0) && /* @__PURE__ */ jsx12(
|
|
3171
|
+
"button",
|
|
3172
|
+
{
|
|
3173
|
+
type: "button",
|
|
3174
|
+
className: "gantt-tl-dep-edit-btn",
|
|
3175
|
+
onClick: () => handleLagChange(effectiveLag + 1),
|
|
3176
|
+
children: "+"
|
|
3177
|
+
}
|
|
3178
|
+
),
|
|
3179
|
+
effectiveLag !== 0 && /* @__PURE__ */ jsx12("span", { children: "\u0434." }),
|
|
3180
|
+
/* @__PURE__ */ jsx12("span", { children: afterWhat })
|
|
3181
|
+
] }),
|
|
3182
|
+
/* @__PURE__ */ jsx12("div", { className: "gantt-tl-dep-edit-pred", children: depName }),
|
|
3183
|
+
!disableDependencyEditing && /* @__PURE__ */ jsxs9(Fragment2, { children: [
|
|
3184
|
+
/* @__PURE__ */ jsx12("hr", { className: "gantt-tl-dep-edit-divider" }),
|
|
3185
|
+
/* @__PURE__ */ jsxs9("div", { className: "gantt-tl-dep-edit-actions", children: [
|
|
3186
|
+
/* @__PURE__ */ jsx12(
|
|
3187
|
+
"button",
|
|
3188
|
+
{
|
|
3189
|
+
type: "button",
|
|
3190
|
+
className: "gantt-tl-dep-edit-close",
|
|
3191
|
+
onClick: () => {
|
|
3192
|
+
setPopoverOpen(false);
|
|
3193
|
+
onChipSelectClear();
|
|
3194
|
+
},
|
|
3195
|
+
children: "\u0417\u0430\u043A\u0440\u044B\u0442\u044C"
|
|
3196
|
+
}
|
|
3197
|
+
),
|
|
3198
|
+
/* @__PURE__ */ jsx12(
|
|
3199
|
+
"button",
|
|
3200
|
+
{
|
|
3201
|
+
type: "button",
|
|
3202
|
+
className: "gantt-tl-dep-edit-delete",
|
|
3203
|
+
onClick: handleTrashClick,
|
|
3204
|
+
children: "\u0423\u0434\u0430\u043B\u0438\u0442\u044C \u0441\u0432\u044F\u0437\u044C"
|
|
3205
|
+
}
|
|
3206
|
+
)
|
|
3207
|
+
] })
|
|
3208
|
+
] })
|
|
3083
3209
|
] })
|
|
3084
|
-
|
|
3085
|
-
|
|
3210
|
+
}
|
|
3211
|
+
)
|
|
3086
3212
|
] });
|
|
3087
3213
|
};
|
|
3088
3214
|
var toISODate = (value) => {
|
|
3089
3215
|
if (value instanceof Date) return value.toISOString().split("T")[0];
|
|
3090
|
-
if (typeof value === "string" && value.includes("T"))
|
|
3216
|
+
if (typeof value === "string" && value.includes("T"))
|
|
3217
|
+
return value.split("T")[0];
|
|
3091
3218
|
return value;
|
|
3092
3219
|
};
|
|
3093
3220
|
var TaskListRow = React9.memo(
|
|
@@ -3124,13 +3251,17 @@ var TaskListRow = React9.memo(
|
|
|
3124
3251
|
onToggleCollapse,
|
|
3125
3252
|
onPromoteTask,
|
|
3126
3253
|
onDemoteTask,
|
|
3127
|
-
isLastChild = true
|
|
3254
|
+
isLastChild = true,
|
|
3255
|
+
nestingDepth = 0,
|
|
3256
|
+
ancestorContinues = []
|
|
3128
3257
|
}) => {
|
|
3129
3258
|
const [editingName, setEditingName] = useState4(false);
|
|
3130
3259
|
const [nameValue, setNameValue] = useState4("");
|
|
3131
3260
|
const nameInputRef = useRef4(null);
|
|
3132
3261
|
const [editingDuration, setEditingDuration] = useState4(false);
|
|
3133
|
-
const [durationValue, setDurationValue] = useState4(
|
|
3262
|
+
const [durationValue, setDurationValue] = useState4(
|
|
3263
|
+
getInclusiveDurationDays(task.startDate, task.endDate)
|
|
3264
|
+
);
|
|
3134
3265
|
const durationInputRef = useRef4(null);
|
|
3135
3266
|
const [editingProgress, setEditingProgress] = useState4(false);
|
|
3136
3267
|
const [progressValue, setProgressValue] = useState4(0);
|
|
@@ -3140,11 +3271,16 @@ var TaskListRow = React9.memo(
|
|
|
3140
3271
|
const durationConfirmedRef = useRef4(false);
|
|
3141
3272
|
const progressConfirmedRef = useRef4(false);
|
|
3142
3273
|
const autoEditedForRef = useRef4(null);
|
|
3143
|
-
const editTriggerRef = useRef4(
|
|
3274
|
+
const editTriggerRef = useRef4(
|
|
3275
|
+
"doubleclick"
|
|
3276
|
+
);
|
|
3144
3277
|
const [deletePending, setDeletePending] = useState4(false);
|
|
3145
3278
|
const deleteButtonRef = useRef4(null);
|
|
3146
3279
|
const isSelected = selectedTaskId === task.id;
|
|
3147
|
-
const isParent = useMemo7(
|
|
3280
|
+
const isParent = useMemo7(
|
|
3281
|
+
() => isTaskParent(task.id, allTasks),
|
|
3282
|
+
[task.id, allTasks]
|
|
3283
|
+
);
|
|
3148
3284
|
const isChild = task.parentId !== void 0;
|
|
3149
3285
|
const isCollapsed = collapsedParentIds.has(task.id);
|
|
3150
3286
|
const isPicking = selectingPredecessorFor != null;
|
|
@@ -3199,31 +3335,40 @@ var TaskListRow = React9.memo(
|
|
|
3199
3335
|
setEditingName(true);
|
|
3200
3336
|
}
|
|
3201
3337
|
}, [editingTaskId, task.id, disableTaskNameEditing]);
|
|
3202
|
-
const handleNameClick = useCallback4(
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
}, [task.name, disableTaskNameEditing]);
|
|
3216
|
-
const handleRowKeyDown = useCallback4((e) => {
|
|
3217
|
-
if (editingProgress) return;
|
|
3218
|
-
if (!editingName && !disableTaskNameEditing && e.key === "F2") {
|
|
3219
|
-
e.preventDefault();
|
|
3338
|
+
const handleNameClick = useCallback4(
|
|
3339
|
+
(e) => {
|
|
3340
|
+
if (disableTaskNameEditing) return;
|
|
3341
|
+
e.stopPropagation();
|
|
3342
|
+
onRowClick?.(task.id);
|
|
3343
|
+
onScrollToTask?.(task.id);
|
|
3344
|
+
},
|
|
3345
|
+
[task.id, disableTaskNameEditing, onRowClick, onScrollToTask]
|
|
3346
|
+
);
|
|
3347
|
+
const handleNameDoubleClick = useCallback4(
|
|
3348
|
+
(e) => {
|
|
3349
|
+
if (disableTaskNameEditing) return;
|
|
3350
|
+
e.stopPropagation();
|
|
3220
3351
|
nameConfirmedRef.current = false;
|
|
3221
|
-
editTriggerRef.current = "
|
|
3352
|
+
editTriggerRef.current = "doubleclick";
|
|
3222
3353
|
setNameValue(task.name);
|
|
3223
3354
|
setEditingName(true);
|
|
3224
|
-
|
|
3225
|
-
|
|
3226
|
-
|
|
3355
|
+
},
|
|
3356
|
+
[task.name, disableTaskNameEditing]
|
|
3357
|
+
);
|
|
3358
|
+
const handleRowKeyDown = useCallback4(
|
|
3359
|
+
(e) => {
|
|
3360
|
+
if (editingProgress) return;
|
|
3361
|
+
if (!editingName && !disableTaskNameEditing && e.key === "F2") {
|
|
3362
|
+
e.preventDefault();
|
|
3363
|
+
nameConfirmedRef.current = false;
|
|
3364
|
+
editTriggerRef.current = "keypress";
|
|
3365
|
+
setNameValue(task.name);
|
|
3366
|
+
setEditingName(true);
|
|
3367
|
+
return;
|
|
3368
|
+
}
|
|
3369
|
+
},
|
|
3370
|
+
[editingName, disableTaskNameEditing, task.name]
|
|
3371
|
+
);
|
|
3227
3372
|
const handleNameSave = useCallback4(() => {
|
|
3228
3373
|
if (nameConfirmedRef.current) {
|
|
3229
3374
|
nameConfirmedRef.current = false;
|
|
@@ -3237,24 +3382,32 @@ var TaskListRow = React9.memo(
|
|
|
3237
3382
|
const handleNameCancel = useCallback4(() => {
|
|
3238
3383
|
setEditingName(false);
|
|
3239
3384
|
}, []);
|
|
3240
|
-
const handleNameKeyDown = useCallback4(
|
|
3241
|
-
|
|
3242
|
-
|
|
3243
|
-
|
|
3244
|
-
|
|
3385
|
+
const handleNameKeyDown = useCallback4(
|
|
3386
|
+
(e) => {
|
|
3387
|
+
if (e.key === "Enter") {
|
|
3388
|
+
nameConfirmedRef.current = true;
|
|
3389
|
+
if (nameValue.trim()) {
|
|
3390
|
+
onTasksChange?.([{ ...task, name: nameValue.trim() }]);
|
|
3391
|
+
}
|
|
3392
|
+
setEditingName(false);
|
|
3393
|
+
} else if (e.key === "Escape") {
|
|
3394
|
+
handleNameCancel();
|
|
3245
3395
|
}
|
|
3246
|
-
|
|
3247
|
-
|
|
3248
|
-
|
|
3249
|
-
|
|
3250
|
-
|
|
3251
|
-
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
|
|
3255
|
-
|
|
3256
|
-
|
|
3257
|
-
|
|
3396
|
+
},
|
|
3397
|
+
[nameValue, task, onTasksChange, handleNameCancel]
|
|
3398
|
+
);
|
|
3399
|
+
const handleDurationClick = useCallback4(
|
|
3400
|
+
(e) => {
|
|
3401
|
+
if (task.locked) return;
|
|
3402
|
+
e.stopPropagation();
|
|
3403
|
+
durationConfirmedRef.current = false;
|
|
3404
|
+
setDurationValue(
|
|
3405
|
+
getInclusiveDurationDays(task.startDate, task.endDate)
|
|
3406
|
+
);
|
|
3407
|
+
setEditingDuration(true);
|
|
3408
|
+
},
|
|
3409
|
+
[task.locked, task.startDate, task.endDate]
|
|
3410
|
+
);
|
|
3258
3411
|
const applyDurationChange = useCallback4((nextDuration) => {
|
|
3259
3412
|
const normalizedDuration = Math.max(1, Math.round(nextDuration) || 1);
|
|
3260
3413
|
setDurationValue(normalizedDuration);
|
|
@@ -3265,34 +3418,59 @@ var TaskListRow = React9.memo(
|
|
|
3265
3418
|
return;
|
|
3266
3419
|
}
|
|
3267
3420
|
const normalizedDuration = Math.max(1, Math.round(durationValue) || 1);
|
|
3268
|
-
onTasksChange?.([
|
|
3421
|
+
onTasksChange?.([
|
|
3422
|
+
{
|
|
3423
|
+
...task,
|
|
3424
|
+
endDate: getEndDateFromDuration(task.startDate, normalizedDuration)
|
|
3425
|
+
}
|
|
3426
|
+
]);
|
|
3269
3427
|
setEditingDuration(false);
|
|
3270
3428
|
}, [durationValue, task, onTasksChange]);
|
|
3271
3429
|
const handleDurationCancel = useCallback4(() => {
|
|
3272
3430
|
setDurationValue(getInclusiveDurationDays(task.startDate, task.endDate));
|
|
3273
3431
|
setEditingDuration(false);
|
|
3274
3432
|
}, [task.startDate, task.endDate]);
|
|
3275
|
-
const handleDurationAdjust = useCallback4(
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
|
|
3281
|
-
|
|
3282
|
-
|
|
3283
|
-
|
|
3284
|
-
|
|
3285
|
-
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
|
|
3289
|
-
|
|
3290
|
-
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
|
|
3294
|
-
|
|
3295
|
-
|
|
3433
|
+
const handleDurationAdjust = useCallback4(
|
|
3434
|
+
(delta) => {
|
|
3435
|
+
applyDurationChange(durationValue + delta);
|
|
3436
|
+
},
|
|
3437
|
+
[applyDurationChange, durationValue]
|
|
3438
|
+
);
|
|
3439
|
+
const handleDurationKeyDown = useCallback4(
|
|
3440
|
+
(e) => {
|
|
3441
|
+
e.stopPropagation();
|
|
3442
|
+
if (e.key === "Enter") {
|
|
3443
|
+
durationConfirmedRef.current = true;
|
|
3444
|
+
const normalizedDuration = Math.max(
|
|
3445
|
+
1,
|
|
3446
|
+
Math.round(durationValue) || 1
|
|
3447
|
+
);
|
|
3448
|
+
onTasksChange?.([
|
|
3449
|
+
{
|
|
3450
|
+
...task,
|
|
3451
|
+
endDate: getEndDateFromDuration(
|
|
3452
|
+
task.startDate,
|
|
3453
|
+
normalizedDuration
|
|
3454
|
+
)
|
|
3455
|
+
}
|
|
3456
|
+
]);
|
|
3457
|
+
setEditingDuration(false);
|
|
3458
|
+
} else if (e.key === "Escape") {
|
|
3459
|
+
handleDurationCancel();
|
|
3460
|
+
}
|
|
3461
|
+
},
|
|
3462
|
+
[durationValue, task, onTasksChange, handleDurationCancel]
|
|
3463
|
+
);
|
|
3464
|
+
const handleProgressClick = useCallback4(
|
|
3465
|
+
(e) => {
|
|
3466
|
+
if (task.locked) return;
|
|
3467
|
+
e.stopPropagation();
|
|
3468
|
+
progressConfirmedRef.current = false;
|
|
3469
|
+
setProgressValue(task.progress ?? 0);
|
|
3470
|
+
setEditingProgress(true);
|
|
3471
|
+
},
|
|
3472
|
+
[task.progress, task.locked]
|
|
3473
|
+
);
|
|
3296
3474
|
const handleProgressSave = useCallback4(() => {
|
|
3297
3475
|
if (progressConfirmedRef.current) {
|
|
3298
3476
|
progressConfirmedRef.current = false;
|
|
@@ -3315,28 +3493,36 @@ var TaskListRow = React9.memo(
|
|
|
3315
3493
|
setEditingProgress(false);
|
|
3316
3494
|
}, []);
|
|
3317
3495
|
const handleProgressAdjust = useCallback4((delta) => {
|
|
3318
|
-
setProgressValue(
|
|
3496
|
+
setProgressValue(
|
|
3497
|
+
(current) => Math.max(0, Math.min(100, current + delta))
|
|
3498
|
+
);
|
|
3319
3499
|
}, []);
|
|
3320
|
-
const handleProgressKeyDown = useCallback4(
|
|
3321
|
-
e
|
|
3322
|
-
|
|
3323
|
-
|
|
3324
|
-
|
|
3325
|
-
|
|
3326
|
-
|
|
3327
|
-
|
|
3328
|
-
|
|
3329
|
-
|
|
3330
|
-
|
|
3331
|
-
|
|
3332
|
-
|
|
3333
|
-
|
|
3500
|
+
const handleProgressKeyDown = useCallback4(
|
|
3501
|
+
(e) => {
|
|
3502
|
+
e.stopPropagation();
|
|
3503
|
+
if (e.key === "Enter") {
|
|
3504
|
+
progressConfirmedRef.current = true;
|
|
3505
|
+
const clampedValue = Math.max(0, Math.min(100, progressValue));
|
|
3506
|
+
if ((clampedValue === 100 || clampedValue === 0) && isTaskParent(task.id, allTasks)) {
|
|
3507
|
+
const children = getChildren(task.id, allTasks);
|
|
3508
|
+
const updatedTasks = [
|
|
3509
|
+
{ ...task, progress: clampedValue },
|
|
3510
|
+
...children.map((child) => ({
|
|
3511
|
+
...child,
|
|
3512
|
+
progress: clampedValue
|
|
3513
|
+
}))
|
|
3514
|
+
];
|
|
3515
|
+
onTasksChange?.(updatedTasks);
|
|
3516
|
+
} else {
|
|
3517
|
+
onTasksChange?.([{ ...task, progress: clampedValue }]);
|
|
3518
|
+
}
|
|
3519
|
+
setEditingProgress(false);
|
|
3520
|
+
} else if (e.key === "Escape") {
|
|
3521
|
+
handleProgressCancel();
|
|
3334
3522
|
}
|
|
3335
|
-
|
|
3336
|
-
|
|
3337
|
-
|
|
3338
|
-
}
|
|
3339
|
-
}, [progressValue, task, onTasksChange, handleProgressCancel, allTasks]);
|
|
3523
|
+
},
|
|
3524
|
+
[progressValue, task, onTasksChange, handleProgressCancel, allTasks]
|
|
3525
|
+
);
|
|
3340
3526
|
useEffect4(() => {
|
|
3341
3527
|
if (editingProgress && progressInputRef.current) {
|
|
3342
3528
|
progressInputRef.current.focus();
|
|
@@ -3352,77 +3538,111 @@ var TaskListRow = React9.memo(
|
|
|
3352
3538
|
durationInputRef.current.select();
|
|
3353
3539
|
}
|
|
3354
3540
|
}, [editingDuration]);
|
|
3355
|
-
const handleStartDateChange = useCallback4(
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
|
|
3359
|
-
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
|
|
3363
|
-
newDateISO,
|
|
3364
|
-
|
|
3365
|
-
|
|
3366
|
-
|
|
3367
|
-
|
|
3368
|
-
|
|
3369
|
-
|
|
3370
|
-
|
|
3371
|
-
|
|
3372
|
-
|
|
3373
|
-
|
|
3374
|
-
|
|
3375
|
-
|
|
3376
|
-
|
|
3377
|
-
|
|
3378
|
-
|
|
3379
|
-
|
|
3380
|
-
|
|
3541
|
+
const handleStartDateChange = useCallback4(
|
|
3542
|
+
(newDateISO) => {
|
|
3543
|
+
if (!newDateISO) return;
|
|
3544
|
+
const origStart = parseUTCDate(task.startDate);
|
|
3545
|
+
const origEnd = parseUTCDate(task.endDate);
|
|
3546
|
+
const durationMs = origEnd.getTime() - origStart.getTime();
|
|
3547
|
+
const newStart = /* @__PURE__ */ new Date(newDateISO + "T00:00:00Z");
|
|
3548
|
+
const newEnd = new Date(newStart.getTime() + durationMs);
|
|
3549
|
+
const { startDate: normalizedStart, endDate: normalizedEnd } = normalizeTaskDates(newDateISO, newEnd.toISOString().split("T")[0]);
|
|
3550
|
+
onTasksChange?.([
|
|
3551
|
+
{ ...task, startDate: normalizedStart, endDate: normalizedEnd }
|
|
3552
|
+
]);
|
|
3553
|
+
},
|
|
3554
|
+
[task, onTasksChange]
|
|
3555
|
+
);
|
|
3556
|
+
const handleEndDateChange = useCallback4(
|
|
3557
|
+
(newDateISO) => {
|
|
3558
|
+
if (!newDateISO) return;
|
|
3559
|
+
const origStart = parseUTCDate(task.startDate);
|
|
3560
|
+
const origEnd = parseUTCDate(task.endDate);
|
|
3561
|
+
const durationMs = origEnd.getTime() - origStart.getTime();
|
|
3562
|
+
const newEnd = /* @__PURE__ */ new Date(newDateISO + "T00:00:00Z");
|
|
3563
|
+
const newStart = new Date(newEnd.getTime() - durationMs);
|
|
3564
|
+
const { startDate: normalizedStart, endDate: normalizedEnd } = normalizeTaskDates(newStart.toISOString().split("T")[0], newDateISO);
|
|
3565
|
+
onTasksChange?.([
|
|
3566
|
+
{ ...task, startDate: normalizedStart, endDate: normalizedEnd }
|
|
3567
|
+
]);
|
|
3568
|
+
},
|
|
3569
|
+
[task, onTasksChange]
|
|
3570
|
+
);
|
|
3381
3571
|
const handleRowClickInternal = useCallback4(() => {
|
|
3382
3572
|
onRowClick?.(task.id);
|
|
3383
3573
|
}, [task.id, onRowClick]);
|
|
3384
|
-
const handleNumberClick = useCallback4(
|
|
3385
|
-
e
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
|
|
3392
|
-
|
|
3393
|
-
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
|
|
3400
|
-
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
const
|
|
3406
|
-
e
|
|
3407
|
-
|
|
3408
|
-
|
|
3409
|
-
|
|
3410
|
-
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
|
|
3416
|
-
|
|
3417
|
-
onSetSelectingPredecessorFor
|
|
3418
|
-
|
|
3574
|
+
const handleNumberClick = useCallback4(
|
|
3575
|
+
(e) => {
|
|
3576
|
+
e.stopPropagation();
|
|
3577
|
+
onRowClick?.(task.id);
|
|
3578
|
+
},
|
|
3579
|
+
[task.id, onRowClick]
|
|
3580
|
+
);
|
|
3581
|
+
const handleToggleCollapse = useCallback4(
|
|
3582
|
+
(e) => {
|
|
3583
|
+
e.stopPropagation();
|
|
3584
|
+
onToggleCollapse?.(task.id);
|
|
3585
|
+
},
|
|
3586
|
+
[task.id, onToggleCollapse]
|
|
3587
|
+
);
|
|
3588
|
+
const handlePromote = useCallback4(
|
|
3589
|
+
(e) => {
|
|
3590
|
+
e.stopPropagation();
|
|
3591
|
+
onPromoteTask?.(task.id);
|
|
3592
|
+
},
|
|
3593
|
+
[task.id, onPromoteTask]
|
|
3594
|
+
);
|
|
3595
|
+
const handleDemote = useCallback4(
|
|
3596
|
+
(e) => {
|
|
3597
|
+
e.stopPropagation();
|
|
3598
|
+
onDemoteTask?.(task.id, "");
|
|
3599
|
+
},
|
|
3600
|
+
[task.id, onDemoteTask]
|
|
3601
|
+
);
|
|
3602
|
+
const handleAddClick = useCallback4(
|
|
3603
|
+
(e) => {
|
|
3604
|
+
e.stopPropagation();
|
|
3605
|
+
onSetSelectingPredecessorFor?.(task.id);
|
|
3606
|
+
},
|
|
3607
|
+
[task.id, onSetSelectingPredecessorFor]
|
|
3608
|
+
);
|
|
3609
|
+
const handlePredecessorPick = useCallback4(
|
|
3610
|
+
(e) => {
|
|
3611
|
+
e.stopPropagation();
|
|
3612
|
+
if (!isPicking || isSourceRow) return;
|
|
3613
|
+
if (!selectingPredecessorFor || !activeLinkType) return;
|
|
3614
|
+
onAddDependency?.(task.id, selectingPredecessorFor, activeLinkType);
|
|
3615
|
+
},
|
|
3616
|
+
[
|
|
3617
|
+
isPicking,
|
|
3618
|
+
isSourceRow,
|
|
3619
|
+
selectingPredecessorFor,
|
|
3620
|
+
task.id,
|
|
3621
|
+
activeLinkType,
|
|
3622
|
+
onAddDependency
|
|
3623
|
+
]
|
|
3624
|
+
);
|
|
3625
|
+
const handleCancelPicking = useCallback4(
|
|
3626
|
+
(e) => {
|
|
3627
|
+
e.stopPropagation();
|
|
3628
|
+
onSetSelectingPredecessorFor?.(null);
|
|
3629
|
+
},
|
|
3630
|
+
[onSetSelectingPredecessorFor]
|
|
3631
|
+
);
|
|
3419
3632
|
const isSelectedPredecessor = selectedChip != null && selectedChip.predecessorId === task.id;
|
|
3420
|
-
const handleDeleteSelected = useCallback4(
|
|
3421
|
-
e
|
|
3422
|
-
|
|
3423
|
-
|
|
3424
|
-
|
|
3425
|
-
|
|
3633
|
+
const handleDeleteSelected = useCallback4(
|
|
3634
|
+
(e) => {
|
|
3635
|
+
e.stopPropagation();
|
|
3636
|
+
if (!selectedChip) return;
|
|
3637
|
+
onRemoveDependency?.(
|
|
3638
|
+
selectedChip.successorId,
|
|
3639
|
+
selectedChip.predecessorId,
|
|
3640
|
+
selectedChip.linkType
|
|
3641
|
+
);
|
|
3642
|
+
onChipSelect?.(null);
|
|
3643
|
+
},
|
|
3644
|
+
[selectedChip, onRemoveDependency, onChipSelect]
|
|
3645
|
+
);
|
|
3426
3646
|
const startDateISO = toISODate(task.startDate);
|
|
3427
3647
|
const endDateISO = editingDuration ? getEndDateFromDuration(task.startDate, durationValue) : toISODate(task.endDate);
|
|
3428
3648
|
return /* @__PURE__ */ jsxs9(
|
|
@@ -3475,13 +3695,78 @@ var TaskListRow = React9.memo(
|
|
|
3475
3695
|
}
|
|
3476
3696
|
),
|
|
3477
3697
|
/* @__PURE__ */ jsxs9("div", { className: "gantt-tl-cell gantt-tl-cell-name", children: [
|
|
3478
|
-
isChild && !editingName && /* @__PURE__ */
|
|
3698
|
+
isChild && !editingName && /* @__PURE__ */ jsxs9(Fragment2, { children: [
|
|
3699
|
+
ancestorContinues.map(
|
|
3700
|
+
(continues, idx) => continues ? /* @__PURE__ */ jsx12(
|
|
3701
|
+
"span",
|
|
3702
|
+
{
|
|
3703
|
+
style: {
|
|
3704
|
+
position: "absolute",
|
|
3705
|
+
left: `${idx * 20 + 9}px`,
|
|
3706
|
+
top: 0,
|
|
3707
|
+
height: `${rowHeight}px`,
|
|
3708
|
+
width: "1.5px",
|
|
3709
|
+
background: "#d4bceb",
|
|
3710
|
+
borderRadius: "1px",
|
|
3711
|
+
pointerEvents: "none"
|
|
3712
|
+
}
|
|
3713
|
+
},
|
|
3714
|
+
idx
|
|
3715
|
+
) : null
|
|
3716
|
+
),
|
|
3717
|
+
/* @__PURE__ */ jsx12(
|
|
3718
|
+
"span",
|
|
3719
|
+
{
|
|
3720
|
+
style: {
|
|
3721
|
+
position: "absolute",
|
|
3722
|
+
left: `${(nestingDepth - 1) * 20 + 9}px`,
|
|
3723
|
+
top: 0,
|
|
3724
|
+
height: isLastChild ? `${rowHeight / 2}px` : `${rowHeight}px`,
|
|
3725
|
+
width: "1.5px",
|
|
3726
|
+
background: "#d4bceb",
|
|
3727
|
+
borderRadius: "1px",
|
|
3728
|
+
pointerEvents: "none"
|
|
3729
|
+
}
|
|
3730
|
+
}
|
|
3731
|
+
),
|
|
3732
|
+
/* @__PURE__ */ jsx12(
|
|
3733
|
+
"span",
|
|
3734
|
+
{
|
|
3735
|
+
style: {
|
|
3736
|
+
position: "absolute",
|
|
3737
|
+
left: `${(nestingDepth - 1) * 20 + 9}px`,
|
|
3738
|
+
top: `${rowHeight / 2 - 0.75}px`,
|
|
3739
|
+
width: "8px",
|
|
3740
|
+
height: "1.5px",
|
|
3741
|
+
background: "#d4bceb",
|
|
3742
|
+
borderRadius: "1px",
|
|
3743
|
+
pointerEvents: "none"
|
|
3744
|
+
}
|
|
3745
|
+
}
|
|
3746
|
+
),
|
|
3747
|
+
/* @__PURE__ */ jsx12(
|
|
3748
|
+
"span",
|
|
3749
|
+
{
|
|
3750
|
+
style: {
|
|
3751
|
+
position: "absolute",
|
|
3752
|
+
left: `${(nestingDepth - 1) * 20 + 15}px`,
|
|
3753
|
+
top: `${rowHeight / 2 - 2}px`,
|
|
3754
|
+
width: "4px",
|
|
3755
|
+
height: "4px",
|
|
3756
|
+
borderRadius: "50%",
|
|
3757
|
+
background: "#d4bceb",
|
|
3758
|
+
pointerEvents: "none"
|
|
3759
|
+
}
|
|
3760
|
+
}
|
|
3761
|
+
)
|
|
3762
|
+
] }),
|
|
3479
3763
|
isParent && !editingName && /* @__PURE__ */ jsx12(
|
|
3480
3764
|
"button",
|
|
3481
3765
|
{
|
|
3482
3766
|
type: "button",
|
|
3483
3767
|
className: `gantt-tl-collapse-btn ${isCollapsed ? "gantt-tl-collapse-btn-collapsed" : ""}`,
|
|
3484
3768
|
onClick: handleToggleCollapse,
|
|
3769
|
+
style: { left: `${nestingDepth * 20 + 4}px` },
|
|
3485
3770
|
"aria-label": isCollapsed ? "Expand children" : "Collapse children",
|
|
3486
3771
|
children: /* @__PURE__ */ jsx12(ChevronRightIcon, {})
|
|
3487
3772
|
}
|
|
@@ -3495,7 +3780,10 @@ var TaskListRow = React9.memo(
|
|
|
3495
3780
|
onChange: (e) => setNameValue(e.target.value),
|
|
3496
3781
|
onBlur: handleNameSave,
|
|
3497
3782
|
onKeyDown: handleNameKeyDown,
|
|
3498
|
-
className:
|
|
3783
|
+
className: "gantt-tl-name-input",
|
|
3784
|
+
style: {
|
|
3785
|
+
paddingLeft: nestingDepth > 0 ? `${nestingDepth * 20 + 24}px` : void 0
|
|
3786
|
+
},
|
|
3499
3787
|
onClick: (e) => e.stopPropagation()
|
|
3500
3788
|
}
|
|
3501
3789
|
),
|
|
@@ -3505,14 +3793,15 @@ var TaskListRow = React9.memo(
|
|
|
3505
3793
|
type: "button",
|
|
3506
3794
|
className: [
|
|
3507
3795
|
"gantt-tl-name-trigger",
|
|
3508
|
-
disableTaskNameEditing ? "gantt-tl-name-locked" : ""
|
|
3509
|
-
isParent ? "gantt-tl-name-trigger-parent" : "",
|
|
3510
|
-
isChild ? "gantt-tl-name-trigger-child" : ""
|
|
3796
|
+
disableTaskNameEditing ? "gantt-tl-name-locked" : ""
|
|
3511
3797
|
].filter(Boolean).join(" "),
|
|
3512
3798
|
title: task.name,
|
|
3513
3799
|
onClick: handleNameClick,
|
|
3514
3800
|
onDoubleClick: handleNameDoubleClick,
|
|
3515
|
-
style:
|
|
3801
|
+
style: {
|
|
3802
|
+
paddingLeft: nestingDepth > 0 ? `${nestingDepth * 20 + (isParent ? 26 : 8)}px` : isParent ? "26px" : void 0,
|
|
3803
|
+
...editingName ? { visibility: "hidden", pointerEvents: "none" } : void 0
|
|
3804
|
+
},
|
|
3516
3805
|
children: task.name
|
|
3517
3806
|
}
|
|
3518
3807
|
),
|
|
@@ -3525,16 +3814,20 @@ var TaskListRow = React9.memo(
|
|
|
3525
3814
|
onClick: (e) => {
|
|
3526
3815
|
e.stopPropagation();
|
|
3527
3816
|
const now = /* @__PURE__ */ new Date();
|
|
3528
|
-
const todayISO = new Date(
|
|
3529
|
-
|
|
3530
|
-
|
|
3531
|
-
|
|
3532
|
-
|
|
3533
|
-
|
|
3534
|
-
|
|
3535
|
-
|
|
3536
|
-
|
|
3537
|
-
|
|
3817
|
+
const todayISO = new Date(
|
|
3818
|
+
Date.UTC(
|
|
3819
|
+
now.getUTCFullYear(),
|
|
3820
|
+
now.getUTCMonth(),
|
|
3821
|
+
now.getUTCDate()
|
|
3822
|
+
)
|
|
3823
|
+
).toISOString().split("T")[0];
|
|
3824
|
+
const endISO = new Date(
|
|
3825
|
+
Date.UTC(
|
|
3826
|
+
now.getUTCFullYear(),
|
|
3827
|
+
now.getUTCMonth(),
|
|
3828
|
+
now.getUTCDate() + 7
|
|
3829
|
+
)
|
|
3830
|
+
).toISOString().split("T")[0];
|
|
3538
3831
|
const newTask = {
|
|
3539
3832
|
id: crypto.randomUUID(),
|
|
3540
3833
|
name: "\u041D\u043E\u0432\u0430\u044F \u0437\u0430\u0434\u0430\u0447\u0430",
|
|
@@ -3570,7 +3863,6 @@ var TaskListRow = React9.memo(
|
|
|
3570
3863
|
HierarchyButton,
|
|
3571
3864
|
{
|
|
3572
3865
|
isChild,
|
|
3573
|
-
isParent,
|
|
3574
3866
|
rowIndex,
|
|
3575
3867
|
onPromote: onPromoteTask ? handlePromote : void 0,
|
|
3576
3868
|
onDemote: onDemoteTask ? handleDemote : void 0
|
|
@@ -3578,113 +3870,228 @@ var TaskListRow = React9.memo(
|
|
|
3578
3870
|
)
|
|
3579
3871
|
] })
|
|
3580
3872
|
] }),
|
|
3581
|
-
/* @__PURE__ */ jsx12(
|
|
3582
|
-
|
|
3873
|
+
/* @__PURE__ */ jsx12(
|
|
3874
|
+
"div",
|
|
3583
3875
|
{
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
|
|
3876
|
+
className: "gantt-tl-cell gantt-tl-cell-date",
|
|
3877
|
+
onClick: (e) => e.stopPropagation(),
|
|
3878
|
+
children: /* @__PURE__ */ jsx12(
|
|
3879
|
+
DatePicker,
|
|
3880
|
+
{
|
|
3881
|
+
value: startDateISO,
|
|
3882
|
+
onChange: handleStartDateChange,
|
|
3883
|
+
format: "dd.MM.yy",
|
|
3884
|
+
portal: true,
|
|
3885
|
+
disabled: task.locked
|
|
3886
|
+
}
|
|
3887
|
+
)
|
|
3589
3888
|
}
|
|
3590
|
-
)
|
|
3591
|
-
/* @__PURE__ */ jsx12(
|
|
3592
|
-
|
|
3889
|
+
),
|
|
3890
|
+
/* @__PURE__ */ jsx12(
|
|
3891
|
+
"div",
|
|
3593
3892
|
{
|
|
3594
|
-
|
|
3595
|
-
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
disabled: task.locked
|
|
3599
|
-
}
|
|
3600
|
-
) }),
|
|
3601
|
-
/* @__PURE__ */ jsxs9("div", { className: "gantt-tl-cell gantt-tl-cell-duration", onClick: handleDurationClick, children: [
|
|
3602
|
-
editingDuration && /* @__PURE__ */ jsxs9("div", { className: "gantt-tl-number-editor", onClick: (e) => e.stopPropagation(), children: [
|
|
3603
|
-
/* @__PURE__ */ jsx12(
|
|
3604
|
-
Input,
|
|
3893
|
+
className: "gantt-tl-cell gantt-tl-cell-date",
|
|
3894
|
+
onClick: (e) => e.stopPropagation(),
|
|
3895
|
+
children: /* @__PURE__ */ jsx12(
|
|
3896
|
+
DatePicker,
|
|
3605
3897
|
{
|
|
3606
|
-
|
|
3607
|
-
|
|
3608
|
-
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
onChange: (e) => applyDurationChange(parseInt(e.target.value, 10) || 1),
|
|
3612
|
-
onBlur: handleDurationSave,
|
|
3613
|
-
onKeyDown: handleDurationKeyDown,
|
|
3614
|
-
className: "gantt-tl-number-input"
|
|
3898
|
+
value: endDateISO,
|
|
3899
|
+
onChange: handleEndDateChange,
|
|
3900
|
+
format: "dd.MM.yy",
|
|
3901
|
+
portal: true,
|
|
3902
|
+
disabled: task.locked
|
|
3615
3903
|
}
|
|
3616
|
-
)
|
|
3617
|
-
|
|
3618
|
-
|
|
3619
|
-
|
|
3904
|
+
)
|
|
3905
|
+
}
|
|
3906
|
+
),
|
|
3907
|
+
/* @__PURE__ */ jsxs9(
|
|
3908
|
+
"div",
|
|
3909
|
+
{
|
|
3910
|
+
className: "gantt-tl-cell gantt-tl-cell-duration",
|
|
3911
|
+
onClick: handleDurationClick,
|
|
3912
|
+
children: [
|
|
3913
|
+
editingDuration && /* @__PURE__ */ jsxs9(
|
|
3914
|
+
"div",
|
|
3620
3915
|
{
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3916
|
+
className: "gantt-tl-number-editor",
|
|
3917
|
+
onClick: (e) => e.stopPropagation(),
|
|
3918
|
+
children: [
|
|
3919
|
+
/* @__PURE__ */ jsx12(
|
|
3920
|
+
Input,
|
|
3921
|
+
{
|
|
3922
|
+
ref: durationInputRef,
|
|
3923
|
+
type: "number",
|
|
3924
|
+
min: 1,
|
|
3925
|
+
step: 1,
|
|
3926
|
+
value: durationValue,
|
|
3927
|
+
onChange: (e) => applyDurationChange(parseInt(e.target.value, 10) || 1),
|
|
3928
|
+
onBlur: handleDurationSave,
|
|
3929
|
+
onKeyDown: handleDurationKeyDown,
|
|
3930
|
+
className: "gantt-tl-number-input"
|
|
3931
|
+
}
|
|
3932
|
+
),
|
|
3933
|
+
/* @__PURE__ */ jsxs9("div", { className: "gantt-tl-number-steppers", "aria-hidden": "true", children: [
|
|
3934
|
+
/* @__PURE__ */ jsx12(
|
|
3935
|
+
"button",
|
|
3936
|
+
{
|
|
3937
|
+
type: "button",
|
|
3938
|
+
className: "gantt-tl-number-stepper",
|
|
3939
|
+
tabIndex: -1,
|
|
3940
|
+
onMouseDown: (e) => e.preventDefault(),
|
|
3941
|
+
onClick: () => handleDurationAdjust(1),
|
|
3942
|
+
children: /* @__PURE__ */ jsx12(
|
|
3943
|
+
"svg",
|
|
3944
|
+
{
|
|
3945
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
3946
|
+
width: "10",
|
|
3947
|
+
height: "10",
|
|
3948
|
+
viewBox: "0 0 24 24",
|
|
3949
|
+
fill: "none",
|
|
3950
|
+
stroke: "currentColor",
|
|
3951
|
+
strokeWidth: "2",
|
|
3952
|
+
strokeLinecap: "round",
|
|
3953
|
+
strokeLinejoin: "round",
|
|
3954
|
+
children: /* @__PURE__ */ jsx12("path", { d: "m18 15-6-6-6 6" })
|
|
3955
|
+
}
|
|
3956
|
+
)
|
|
3957
|
+
}
|
|
3958
|
+
),
|
|
3959
|
+
/* @__PURE__ */ jsx12(
|
|
3960
|
+
"button",
|
|
3961
|
+
{
|
|
3962
|
+
type: "button",
|
|
3963
|
+
className: "gantt-tl-number-stepper",
|
|
3964
|
+
tabIndex: -1,
|
|
3965
|
+
onMouseDown: (e) => e.preventDefault(),
|
|
3966
|
+
onClick: () => handleDurationAdjust(-1),
|
|
3967
|
+
children: /* @__PURE__ */ jsx12(
|
|
3968
|
+
"svg",
|
|
3969
|
+
{
|
|
3970
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
3971
|
+
width: "10",
|
|
3972
|
+
height: "10",
|
|
3973
|
+
viewBox: "0 0 24 24",
|
|
3974
|
+
fill: "none",
|
|
3975
|
+
stroke: "currentColor",
|
|
3976
|
+
strokeWidth: "2",
|
|
3977
|
+
strokeLinecap: "round",
|
|
3978
|
+
strokeLinejoin: "round",
|
|
3979
|
+
children: /* @__PURE__ */ jsx12("path", { d: "m6 9 6 6 6-6" })
|
|
3980
|
+
}
|
|
3981
|
+
)
|
|
3982
|
+
}
|
|
3983
|
+
)
|
|
3984
|
+
] })
|
|
3985
|
+
]
|
|
3627
3986
|
}
|
|
3628
3987
|
),
|
|
3629
3988
|
/* @__PURE__ */ jsx12(
|
|
3630
|
-
"
|
|
3989
|
+
"span",
|
|
3631
3990
|
{
|
|
3632
|
-
|
|
3633
|
-
|
|
3634
|
-
tabIndex: -1,
|
|
3635
|
-
onMouseDown: (e) => e.preventDefault(),
|
|
3636
|
-
onClick: () => handleDurationAdjust(-1),
|
|
3637
|
-
children: /* @__PURE__ */ jsx12("svg", { xmlns: "http://www.w3.org/2000/svg", width: "10", height: "10", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx12("path", { d: "m6 9 6 6 6-6" }) })
|
|
3991
|
+
style: editingDuration ? { visibility: "hidden", pointerEvents: "none" } : void 0,
|
|
3992
|
+
children: getInclusiveDurationDays(task.startDate, task.endDate)
|
|
3638
3993
|
}
|
|
3639
3994
|
)
|
|
3640
|
-
]
|
|
3641
|
-
|
|
3642
|
-
|
|
3643
|
-
|
|
3644
|
-
|
|
3645
|
-
|
|
3646
|
-
|
|
3647
|
-
|
|
3648
|
-
|
|
3649
|
-
|
|
3650
|
-
|
|
3651
|
-
min: 0,
|
|
3652
|
-
max: 100,
|
|
3653
|
-
step: 1,
|
|
3654
|
-
value: progressValue,
|
|
3655
|
-
onChange: (e) => setProgressValue(parseInt(e.target.value, 10) || 0),
|
|
3656
|
-
onBlur: handleProgressSave,
|
|
3657
|
-
onKeyDown: handleProgressKeyDown,
|
|
3658
|
-
className: "gantt-tl-number-input"
|
|
3659
|
-
}
|
|
3660
|
-
),
|
|
3661
|
-
/* @__PURE__ */ jsxs9("div", { className: "gantt-tl-number-steppers", "aria-hidden": "true", children: [
|
|
3662
|
-
/* @__PURE__ */ jsx12(
|
|
3663
|
-
"button",
|
|
3995
|
+
]
|
|
3996
|
+
}
|
|
3997
|
+
),
|
|
3998
|
+
/* @__PURE__ */ jsxs9(
|
|
3999
|
+
"div",
|
|
4000
|
+
{
|
|
4001
|
+
className: "gantt-tl-cell gantt-tl-cell-progress",
|
|
4002
|
+
onClick: handleProgressClick,
|
|
4003
|
+
children: [
|
|
4004
|
+
editingProgress && /* @__PURE__ */ jsxs9(
|
|
4005
|
+
"div",
|
|
3664
4006
|
{
|
|
3665
|
-
|
|
3666
|
-
|
|
3667
|
-
|
|
3668
|
-
|
|
3669
|
-
|
|
3670
|
-
|
|
4007
|
+
className: "gantt-tl-number-editor",
|
|
4008
|
+
onClick: (e) => e.stopPropagation(),
|
|
4009
|
+
children: [
|
|
4010
|
+
/* @__PURE__ */ jsx12(
|
|
4011
|
+
Input,
|
|
4012
|
+
{
|
|
4013
|
+
ref: progressInputRef,
|
|
4014
|
+
type: "number",
|
|
4015
|
+
min: 0,
|
|
4016
|
+
max: 100,
|
|
4017
|
+
step: 1,
|
|
4018
|
+
value: progressValue,
|
|
4019
|
+
onChange: (e) => setProgressValue(parseInt(e.target.value, 10) || 0),
|
|
4020
|
+
onBlur: handleProgressSave,
|
|
4021
|
+
onKeyDown: handleProgressKeyDown,
|
|
4022
|
+
className: "gantt-tl-number-input"
|
|
4023
|
+
}
|
|
4024
|
+
),
|
|
4025
|
+
/* @__PURE__ */ jsxs9("div", { className: "gantt-tl-number-steppers", "aria-hidden": "true", children: [
|
|
4026
|
+
/* @__PURE__ */ jsx12(
|
|
4027
|
+
"button",
|
|
4028
|
+
{
|
|
4029
|
+
type: "button",
|
|
4030
|
+
className: "gantt-tl-number-stepper",
|
|
4031
|
+
tabIndex: -1,
|
|
4032
|
+
onMouseDown: (e) => e.preventDefault(),
|
|
4033
|
+
onClick: () => handleProgressAdjust(1),
|
|
4034
|
+
children: /* @__PURE__ */ jsx12(
|
|
4035
|
+
"svg",
|
|
4036
|
+
{
|
|
4037
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
4038
|
+
width: "10",
|
|
4039
|
+
height: "10",
|
|
4040
|
+
viewBox: "0 0 24 24",
|
|
4041
|
+
fill: "none",
|
|
4042
|
+
stroke: "currentColor",
|
|
4043
|
+
strokeWidth: "2",
|
|
4044
|
+
strokeLinecap: "round",
|
|
4045
|
+
strokeLinejoin: "round",
|
|
4046
|
+
children: /* @__PURE__ */ jsx12("path", { d: "m18 15-6-6-6 6" })
|
|
4047
|
+
}
|
|
4048
|
+
)
|
|
4049
|
+
}
|
|
4050
|
+
),
|
|
4051
|
+
/* @__PURE__ */ jsx12(
|
|
4052
|
+
"button",
|
|
4053
|
+
{
|
|
4054
|
+
type: "button",
|
|
4055
|
+
className: "gantt-tl-number-stepper",
|
|
4056
|
+
tabIndex: -1,
|
|
4057
|
+
onMouseDown: (e) => e.preventDefault(),
|
|
4058
|
+
onClick: () => handleProgressAdjust(-1),
|
|
4059
|
+
children: /* @__PURE__ */ jsx12(
|
|
4060
|
+
"svg",
|
|
4061
|
+
{
|
|
4062
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
4063
|
+
width: "10",
|
|
4064
|
+
height: "10",
|
|
4065
|
+
viewBox: "0 0 24 24",
|
|
4066
|
+
fill: "none",
|
|
4067
|
+
stroke: "currentColor",
|
|
4068
|
+
strokeWidth: "2",
|
|
4069
|
+
strokeLinecap: "round",
|
|
4070
|
+
strokeLinejoin: "round",
|
|
4071
|
+
children: /* @__PURE__ */ jsx12("path", { d: "m6 9 6 6 6-6" })
|
|
4072
|
+
}
|
|
4073
|
+
)
|
|
4074
|
+
}
|
|
4075
|
+
)
|
|
4076
|
+
] })
|
|
4077
|
+
]
|
|
3671
4078
|
}
|
|
3672
4079
|
),
|
|
3673
4080
|
/* @__PURE__ */ jsx12(
|
|
3674
|
-
"
|
|
4081
|
+
"span",
|
|
3675
4082
|
{
|
|
3676
|
-
|
|
3677
|
-
|
|
3678
|
-
|
|
3679
|
-
|
|
3680
|
-
|
|
3681
|
-
|
|
4083
|
+
style: editingProgress ? { visibility: "hidden", pointerEvents: "none" } : task.progress === 100 ? {
|
|
4084
|
+
backgroundColor: "#17c864",
|
|
4085
|
+
borderRadius: "4px",
|
|
4086
|
+
padding: "2px 4px",
|
|
4087
|
+
color: "#ffffff"
|
|
4088
|
+
} : void 0,
|
|
4089
|
+
children: task.progress ? Math.round(task.progress) === 100 ? "100" : `${Math.round(task.progress)}%` : "0%"
|
|
3682
4090
|
}
|
|
3683
4091
|
)
|
|
3684
|
-
]
|
|
3685
|
-
|
|
3686
|
-
|
|
3687
|
-
] }),
|
|
4092
|
+
]
|
|
4093
|
+
}
|
|
4094
|
+
),
|
|
3688
4095
|
/* @__PURE__ */ jsx12(
|
|
3689
4096
|
"div",
|
|
3690
4097
|
{
|
|
@@ -3725,26 +4132,33 @@ var TaskListRow = React9.memo(
|
|
|
3725
4132
|
]
|
|
3726
4133
|
}
|
|
3727
4134
|
) }),
|
|
3728
|
-
/* @__PURE__ */ jsx12(PopoverContent, { portal: true, align: "start", children: /* @__PURE__ */ jsx12(
|
|
3729
|
-
|
|
4135
|
+
/* @__PURE__ */ jsx12(PopoverContent, { portal: true, align: "start", children: /* @__PURE__ */ jsx12(
|
|
4136
|
+
"div",
|
|
3730
4137
|
{
|
|
3731
|
-
|
|
3732
|
-
|
|
3733
|
-
|
|
3734
|
-
|
|
3735
|
-
|
|
3736
|
-
|
|
3737
|
-
|
|
3738
|
-
|
|
3739
|
-
|
|
3740
|
-
|
|
3741
|
-
|
|
3742
|
-
|
|
3743
|
-
|
|
3744
|
-
|
|
3745
|
-
|
|
3746
|
-
|
|
3747
|
-
|
|
4138
|
+
className: "gantt-tl-dep-overflow-list",
|
|
4139
|
+
onClick: (e) => e.stopPropagation(),
|
|
4140
|
+
children: chips.map(({ dep, lag, predecessorName }) => /* @__PURE__ */ jsx12(
|
|
4141
|
+
DepChip,
|
|
4142
|
+
{
|
|
4143
|
+
lag,
|
|
4144
|
+
dep,
|
|
4145
|
+
taskId: task.id,
|
|
4146
|
+
predecessorName,
|
|
4147
|
+
selectedChip,
|
|
4148
|
+
disableDependencyEditing,
|
|
4149
|
+
onChipSelect,
|
|
4150
|
+
onRowClick,
|
|
4151
|
+
onScrollToTask,
|
|
4152
|
+
onRemoveDependency,
|
|
4153
|
+
onChipSelectClear: () => onChipSelect?.(null),
|
|
4154
|
+
task,
|
|
4155
|
+
allTasks,
|
|
4156
|
+
onTasksChange
|
|
4157
|
+
},
|
|
4158
|
+
`${dep.taskId}-${dep.type}`
|
|
4159
|
+
))
|
|
4160
|
+
}
|
|
4161
|
+
) })
|
|
3748
4162
|
] })
|
|
3749
4163
|
) : chips.length === 1 ? (
|
|
3750
4164
|
/* Single chip — unified DepChip */
|
|
@@ -3943,6 +4357,25 @@ var TaskList = ({
|
|
|
3943
4357
|
() => visibleTasks.length * rowHeight,
|
|
3944
4358
|
[visibleTasks.length, rowHeight]
|
|
3945
4359
|
);
|
|
4360
|
+
const nestingDepthMap = useMemo8(() => {
|
|
4361
|
+
const depthMap = /* @__PURE__ */ new Map();
|
|
4362
|
+
const taskById = new Map(tasks.map((t) => [t.id, t]));
|
|
4363
|
+
function getDepth(taskId) {
|
|
4364
|
+
if (depthMap.has(taskId)) return depthMap.get(taskId);
|
|
4365
|
+
const task = taskById.get(taskId);
|
|
4366
|
+
if (!task || !task.parentId || !taskById.has(task.parentId)) {
|
|
4367
|
+
depthMap.set(taskId, 0);
|
|
4368
|
+
return 0;
|
|
4369
|
+
}
|
|
4370
|
+
const depth = getDepth(task.parentId) + 1;
|
|
4371
|
+
depthMap.set(taskId, depth);
|
|
4372
|
+
return depth;
|
|
4373
|
+
}
|
|
4374
|
+
for (const task of tasks) {
|
|
4375
|
+
getDepth(task.id);
|
|
4376
|
+
}
|
|
4377
|
+
return depthMap;
|
|
4378
|
+
}, [tasks]);
|
|
3946
4379
|
const lastChildIds = useMemo8(() => {
|
|
3947
4380
|
const last = /* @__PURE__ */ new Set();
|
|
3948
4381
|
const seenParents = /* @__PURE__ */ new Set();
|
|
@@ -3955,6 +4388,20 @@ var TaskList = ({
|
|
|
3955
4388
|
}
|
|
3956
4389
|
return last;
|
|
3957
4390
|
}, [visibleTasks]);
|
|
4391
|
+
const ancestorContinuesMap = useMemo8(() => {
|
|
4392
|
+
const taskById = new Map(tasks.map((t) => [t.id, t]));
|
|
4393
|
+
const map = /* @__PURE__ */ new Map();
|
|
4394
|
+
for (const task of visibleTasks) {
|
|
4395
|
+
const continues = [];
|
|
4396
|
+
let current = taskById.get(task.id);
|
|
4397
|
+
while (current?.parentId && taskById.has(current.parentId)) {
|
|
4398
|
+
continues.unshift(!lastChildIds.has(current.id));
|
|
4399
|
+
current = taskById.get(current.parentId);
|
|
4400
|
+
}
|
|
4401
|
+
map.set(task.id, continues.slice(0, -1));
|
|
4402
|
+
}
|
|
4403
|
+
return map;
|
|
4404
|
+
}, [tasks, visibleTasks, lastChildIds]);
|
|
3958
4405
|
const handleRowClick = useCallback5((taskId) => {
|
|
3959
4406
|
onTaskSelect?.(taskId);
|
|
3960
4407
|
}, [onTaskSelect]);
|
|
@@ -4065,9 +4512,6 @@ var TaskList = ({
|
|
|
4065
4512
|
if (dropTarget.parentId === draggedTaskId) {
|
|
4066
4513
|
return false;
|
|
4067
4514
|
}
|
|
4068
|
-
if (dropTarget.parentId) {
|
|
4069
|
-
return false;
|
|
4070
|
-
}
|
|
4071
4515
|
const draggedTask = orderedTasks.find((t) => t.id === draggedTaskId);
|
|
4072
4516
|
if (!draggedTask) return true;
|
|
4073
4517
|
const descendants = getAllDescendants(draggedTaskId, orderedTasks);
|
|
@@ -4213,6 +4657,52 @@ var TaskList = ({
|
|
|
4213
4657
|
setIsCreating(false);
|
|
4214
4658
|
}, [onAdd]);
|
|
4215
4659
|
const handleCancelNewTask = useCallback5(() => setIsCreating(false), []);
|
|
4660
|
+
function getTaskDepth(task, tasks2) {
|
|
4661
|
+
if (!task) return 0;
|
|
4662
|
+
let depth = 0;
|
|
4663
|
+
let current = task;
|
|
4664
|
+
while (current) {
|
|
4665
|
+
if (!current.parentId) break;
|
|
4666
|
+
depth++;
|
|
4667
|
+
const parentId = current.parentId;
|
|
4668
|
+
current = tasks2.find((t) => t.id === parentId);
|
|
4669
|
+
}
|
|
4670
|
+
return depth;
|
|
4671
|
+
}
|
|
4672
|
+
const handleDemoteWrapper = useCallback5((taskId, _newParentId) => {
|
|
4673
|
+
const taskIndex = visibleTasks.findIndex((t) => t.id === taskId);
|
|
4674
|
+
const currentTask = visibleTasks[taskIndex];
|
|
4675
|
+
const currentDepth = getTaskDepth(currentTask, orderedTasks);
|
|
4676
|
+
if (taskIndex > 0) {
|
|
4677
|
+
for (let i = taskIndex - 1; i >= 0; i--) {
|
|
4678
|
+
const previousTask = visibleTasks[i];
|
|
4679
|
+
const previousDepth = getTaskDepth(previousTask, orderedTasks);
|
|
4680
|
+
if (previousDepth === currentDepth) {
|
|
4681
|
+
onDemoteTask?.(taskId, previousTask.id);
|
|
4682
|
+
return;
|
|
4683
|
+
}
|
|
4684
|
+
if (previousDepth < currentDepth) {
|
|
4685
|
+
break;
|
|
4686
|
+
}
|
|
4687
|
+
}
|
|
4688
|
+
return;
|
|
4689
|
+
}
|
|
4690
|
+
const demotedTask = orderedTasks.find((t) => t.id === taskId);
|
|
4691
|
+
if (!demotedTask) return;
|
|
4692
|
+
const newSectionTask = {
|
|
4693
|
+
id: crypto.randomUUID(),
|
|
4694
|
+
name: "\u041D\u043E\u0432\u044B\u0439 \u0440\u0430\u0437\u0434\u0435\u043B",
|
|
4695
|
+
startDate: demotedTask.startDate,
|
|
4696
|
+
endDate: demotedTask.endDate
|
|
4697
|
+
};
|
|
4698
|
+
const updatedTasks = [
|
|
4699
|
+
newSectionTask,
|
|
4700
|
+
...orderedTasks.map(
|
|
4701
|
+
(t) => t.id === taskId ? { ...t, parentId: newSectionTask.id } : t
|
|
4702
|
+
)
|
|
4703
|
+
];
|
|
4704
|
+
onReorder?.(updatedTasks, taskId, newSectionTask.id);
|
|
4705
|
+
}, [visibleTasks, orderedTasks, onDemoteTask, onReorder]);
|
|
4216
4706
|
const effectiveTaskListWidth = Math.max(taskListWidth, MIN_TASK_LIST_WIDTH);
|
|
4217
4707
|
return /* @__PURE__ */ jsx14(
|
|
4218
4708
|
"div",
|
|
@@ -4296,8 +4786,10 @@ var TaskList = ({
|
|
|
4296
4786
|
collapsedParentIds,
|
|
4297
4787
|
onToggleCollapse: handleToggleCollapse,
|
|
4298
4788
|
onPromoteTask,
|
|
4299
|
-
onDemoteTask,
|
|
4300
|
-
isLastChild: lastChildIds.has(task.id)
|
|
4789
|
+
onDemoteTask: onDemoteTask ? handleDemoteWrapper : void 0,
|
|
4790
|
+
isLastChild: lastChildIds.has(task.id),
|
|
4791
|
+
nestingDepth: nestingDepthMap.get(task.id) ?? 0,
|
|
4792
|
+
ancestorContinues: ancestorContinuesMap.get(task.id) ?? []
|
|
4301
4793
|
},
|
|
4302
4794
|
task.id
|
|
4303
4795
|
)) }),
|
|
@@ -4606,6 +5098,17 @@ var GanttChart = forwardRef(({
|
|
|
4606
5098
|
}),
|
|
4607
5099
|
[scrollToToday, scrollToTask, handleCollapseAll, handleExpandAll]
|
|
4608
5100
|
);
|
|
5101
|
+
function getTaskDepth(taskId, tasks2) {
|
|
5102
|
+
let depth = 0;
|
|
5103
|
+
let current = tasks2.find((t) => t.id === taskId);
|
|
5104
|
+
while (current) {
|
|
5105
|
+
if (!current.parentId) break;
|
|
5106
|
+
depth++;
|
|
5107
|
+
const parentId = current.parentId;
|
|
5108
|
+
current = tasks2.find((t) => t.id === parentId);
|
|
5109
|
+
}
|
|
5110
|
+
return depth;
|
|
5111
|
+
}
|
|
4609
5112
|
const handlePromoteTask = useCallback6((taskId) => {
|
|
4610
5113
|
if (onPromoteTask) {
|
|
4611
5114
|
onPromoteTask(taskId);
|
|
@@ -4615,20 +5118,20 @@ var GanttChart = forwardRef(({
|
|
|
4615
5118
|
if (!taskToPromote || !taskToPromote.parentId) {
|
|
4616
5119
|
return;
|
|
4617
5120
|
}
|
|
4618
|
-
const
|
|
4619
|
-
const
|
|
5121
|
+
const depth = getTaskDepth(taskId, tasks);
|
|
5122
|
+
const grandparentId = depth > 1 ? tasks.find((t) => t.id === taskToPromote.parentId)?.parentId : void 0;
|
|
5123
|
+
const currentParentId = taskToPromote.parentId;
|
|
5124
|
+
const siblings = tasks.filter((t) => t.parentId === currentParentId);
|
|
5125
|
+
const promotedTask = { ...taskToPromote, parentId: grandparentId };
|
|
4620
5126
|
if (siblings.length <= 1) {
|
|
4621
|
-
|
|
4622
|
-
onTasksChange?.([promotedTask2]);
|
|
5127
|
+
onTasksChange?.([promotedTask]);
|
|
4623
5128
|
return;
|
|
4624
5129
|
}
|
|
4625
|
-
const lastSiblingIndex = tasks.map((t, i) => ({ task: t, index: i })).filter(({ task }) => task.parentId ===
|
|
5130
|
+
const lastSiblingIndex = tasks.map((t, i) => ({ task: t, index: i })).filter(({ task }) => task.parentId === currentParentId).sort((a, b) => b.index - a.index)[0];
|
|
4626
5131
|
if (!lastSiblingIndex) {
|
|
4627
|
-
|
|
4628
|
-
onTasksChange?.([promotedTask2]);
|
|
5132
|
+
onTasksChange?.([promotedTask]);
|
|
4629
5133
|
return;
|
|
4630
5134
|
}
|
|
4631
|
-
const promotedTask = { ...taskToPromote, parentId: void 0 };
|
|
4632
5135
|
const reorderedTasks = normalizeHierarchyTasks([
|
|
4633
5136
|
...tasks.filter((t) => t.id !== taskId).slice(0, lastSiblingIndex.index + 1),
|
|
4634
5137
|
promotedTask,
|