gantt-lib 0.86.1 → 0.88.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 +236 -29
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +236 -29
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +14 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -303,7 +303,7 @@ declare const progressInRange: (min: number, max: number) => TaskPredicate;
|
|
|
303
303
|
*/
|
|
304
304
|
declare const nameContains: (substring: string, caseSensitive?: boolean) => TaskPredicate;
|
|
305
305
|
|
|
306
|
-
type BuiltInTaskListColumnId = 'number' | 'name' | 'startDate' | 'endDate' | 'duration' | 'progress' | 'dependencies' | 'actions';
|
|
306
|
+
type BuiltInTaskListColumnId = 'selection' | 'number' | 'name' | 'startDate' | 'endDate' | 'duration' | 'progress' | 'dependencies' | 'actions';
|
|
307
307
|
type TaskListColumnId = BuiltInTaskListColumnId | (string & {});
|
|
308
308
|
type TaskListColumnAnchor = {
|
|
309
309
|
after: BuiltInTaskListColumnId | string;
|
|
@@ -495,6 +495,12 @@ interface GanttModeProps<TTask extends Task = Task> {
|
|
|
495
495
|
onToggleCollapse?: (parentId: string) => void;
|
|
496
496
|
/** Task IDs to highlight in the task list (for search results) */
|
|
497
497
|
highlightedTaskIds?: Set<string>;
|
|
498
|
+
/** Enable a leading checkbox column for multi-selecting task rows (default: false) */
|
|
499
|
+
enableTaskMultiSelect?: boolean;
|
|
500
|
+
/** Controlled selected task IDs for multi-select mode */
|
|
501
|
+
selectedTaskIds?: Set<string>;
|
|
502
|
+
/** Callback when multi-selected task IDs change */
|
|
503
|
+
onSelectedTaskIdsChange?: (taskIds: Set<string>) => void;
|
|
498
504
|
/** Disable task drag and resize on the calendar grid (default: false) */
|
|
499
505
|
disableTaskDrag?: boolean;
|
|
500
506
|
/** Show calendar chart area (default: true) */
|
|
@@ -611,6 +617,8 @@ interface TaskRowProps {
|
|
|
611
617
|
isWeekend?: (date: Date) => boolean;
|
|
612
618
|
/** Disable task drag and resize (overrides task.locked) */
|
|
613
619
|
disableTaskDrag?: boolean;
|
|
620
|
+
/** Active chart view mode */
|
|
621
|
+
viewMode?: 'day' | 'week' | 'month';
|
|
614
622
|
}
|
|
615
623
|
/**
|
|
616
624
|
* TaskRow component - renders a single task row with a task bar
|
|
@@ -766,6 +774,12 @@ interface TaskListProps {
|
|
|
766
774
|
businessDays?: boolean;
|
|
767
775
|
/** Task IDs highlighted by the active filter */
|
|
768
776
|
highlightedTaskIds?: Set<string>;
|
|
777
|
+
/** Enable a leading checkbox column for multi-selecting task rows (default: false) */
|
|
778
|
+
enableTaskMultiSelect?: boolean;
|
|
779
|
+
/** Controlled selected task IDs for multi-select mode */
|
|
780
|
+
selectedTaskIds?: Set<string>;
|
|
781
|
+
/** Callback when multi-selected task IDs change */
|
|
782
|
+
onSelectedTaskIdsChange?: (taskIds: Set<string>) => void;
|
|
769
783
|
/** Filter mode: 'highlight' shows yellow highlight on matches, 'hide' hides non-matching tasks */
|
|
770
784
|
filterMode?: 'highlight' | 'hide';
|
|
771
785
|
/** Task IDs that match the filter (used for hide mode). When undefined, no filtering is applied */
|
|
@@ -937,6 +951,8 @@ interface UseTaskDragOptions {
|
|
|
937
951
|
businessDays?: boolean;
|
|
938
952
|
/** Function that returns true for weekends (for businessDays mode) */
|
|
939
953
|
weekendPredicate?: (date: Date) => boolean;
|
|
954
|
+
/** Active chart view mode */
|
|
955
|
+
viewMode?: 'day' | 'week' | 'month';
|
|
940
956
|
}
|
|
941
957
|
/**
|
|
942
958
|
* Return value from useTaskDrag hook
|
|
@@ -953,6 +969,8 @@ interface UseTaskDragReturn {
|
|
|
953
969
|
/** Props to spread on the drag handle element */
|
|
954
970
|
dragHandleProps: {
|
|
955
971
|
onMouseDown: (e: React.MouseEvent) => void;
|
|
972
|
+
onMouseMove: (e: React.MouseEvent) => void;
|
|
973
|
+
onMouseLeave: () => void;
|
|
956
974
|
style: React.CSSProperties;
|
|
957
975
|
};
|
|
958
976
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -303,7 +303,7 @@ declare const progressInRange: (min: number, max: number) => TaskPredicate;
|
|
|
303
303
|
*/
|
|
304
304
|
declare const nameContains: (substring: string, caseSensitive?: boolean) => TaskPredicate;
|
|
305
305
|
|
|
306
|
-
type BuiltInTaskListColumnId = 'number' | 'name' | 'startDate' | 'endDate' | 'duration' | 'progress' | 'dependencies' | 'actions';
|
|
306
|
+
type BuiltInTaskListColumnId = 'selection' | 'number' | 'name' | 'startDate' | 'endDate' | 'duration' | 'progress' | 'dependencies' | 'actions';
|
|
307
307
|
type TaskListColumnId = BuiltInTaskListColumnId | (string & {});
|
|
308
308
|
type TaskListColumnAnchor = {
|
|
309
309
|
after: BuiltInTaskListColumnId | string;
|
|
@@ -495,6 +495,12 @@ interface GanttModeProps<TTask extends Task = Task> {
|
|
|
495
495
|
onToggleCollapse?: (parentId: string) => void;
|
|
496
496
|
/** Task IDs to highlight in the task list (for search results) */
|
|
497
497
|
highlightedTaskIds?: Set<string>;
|
|
498
|
+
/** Enable a leading checkbox column for multi-selecting task rows (default: false) */
|
|
499
|
+
enableTaskMultiSelect?: boolean;
|
|
500
|
+
/** Controlled selected task IDs for multi-select mode */
|
|
501
|
+
selectedTaskIds?: Set<string>;
|
|
502
|
+
/** Callback when multi-selected task IDs change */
|
|
503
|
+
onSelectedTaskIdsChange?: (taskIds: Set<string>) => void;
|
|
498
504
|
/** Disable task drag and resize on the calendar grid (default: false) */
|
|
499
505
|
disableTaskDrag?: boolean;
|
|
500
506
|
/** Show calendar chart area (default: true) */
|
|
@@ -611,6 +617,8 @@ interface TaskRowProps {
|
|
|
611
617
|
isWeekend?: (date: Date) => boolean;
|
|
612
618
|
/** Disable task drag and resize (overrides task.locked) */
|
|
613
619
|
disableTaskDrag?: boolean;
|
|
620
|
+
/** Active chart view mode */
|
|
621
|
+
viewMode?: 'day' | 'week' | 'month';
|
|
614
622
|
}
|
|
615
623
|
/**
|
|
616
624
|
* TaskRow component - renders a single task row with a task bar
|
|
@@ -766,6 +774,12 @@ interface TaskListProps {
|
|
|
766
774
|
businessDays?: boolean;
|
|
767
775
|
/** Task IDs highlighted by the active filter */
|
|
768
776
|
highlightedTaskIds?: Set<string>;
|
|
777
|
+
/** Enable a leading checkbox column for multi-selecting task rows (default: false) */
|
|
778
|
+
enableTaskMultiSelect?: boolean;
|
|
779
|
+
/** Controlled selected task IDs for multi-select mode */
|
|
780
|
+
selectedTaskIds?: Set<string>;
|
|
781
|
+
/** Callback when multi-selected task IDs change */
|
|
782
|
+
onSelectedTaskIdsChange?: (taskIds: Set<string>) => void;
|
|
769
783
|
/** Filter mode: 'highlight' shows yellow highlight on matches, 'hide' hides non-matching tasks */
|
|
770
784
|
filterMode?: 'highlight' | 'hide';
|
|
771
785
|
/** Task IDs that match the filter (used for hide mode). When undefined, no filtering is applied */
|
|
@@ -937,6 +951,8 @@ interface UseTaskDragOptions {
|
|
|
937
951
|
businessDays?: boolean;
|
|
938
952
|
/** Function that returns true for weekends (for businessDays mode) */
|
|
939
953
|
weekendPredicate?: (date: Date) => boolean;
|
|
954
|
+
/** Active chart view mode */
|
|
955
|
+
viewMode?: 'day' | 'week' | 'month';
|
|
940
956
|
}
|
|
941
957
|
/**
|
|
942
958
|
* Return value from useTaskDrag hook
|
|
@@ -953,6 +969,8 @@ interface UseTaskDragReturn {
|
|
|
953
969
|
/** Props to spread on the drag handle element */
|
|
954
970
|
dragHandleProps: {
|
|
955
971
|
onMouseDown: (e: React.MouseEvent) => void;
|
|
972
|
+
onMouseMove: (e: React.MouseEvent) => void;
|
|
973
|
+
onMouseLeave: () => void;
|
|
956
974
|
style: React.CSSProperties;
|
|
957
975
|
};
|
|
958
976
|
}
|
package/dist/index.js
CHANGED
|
@@ -2291,6 +2291,46 @@ function clampDateRangeForIncomingFS(task, range, allTasks, mode, businessDays,
|
|
|
2291
2291
|
// src/hooks/useTaskDrag.ts
|
|
2292
2292
|
var globalActiveDrag = null;
|
|
2293
2293
|
var globalRafId = null;
|
|
2294
|
+
var globalLockedCursor = null;
|
|
2295
|
+
var GLOBAL_CURSOR_STYLE_ID = "gantt-global-drag-cursor-style";
|
|
2296
|
+
function ensureGlobalCursorStyle() {
|
|
2297
|
+
if (typeof document === "undefined") return;
|
|
2298
|
+
if (document.getElementById(GLOBAL_CURSOR_STYLE_ID)) return;
|
|
2299
|
+
const style = document.createElement("style");
|
|
2300
|
+
style.id = GLOBAL_CURSOR_STYLE_ID;
|
|
2301
|
+
style.textContent = `
|
|
2302
|
+
html.gantt-global-cursor-grabbing,
|
|
2303
|
+
html.gantt-global-cursor-grabbing *,
|
|
2304
|
+
html.gantt-global-cursor-grabbing *::before,
|
|
2305
|
+
html.gantt-global-cursor-grabbing *::after {
|
|
2306
|
+
cursor: grabbing !important;
|
|
2307
|
+
}
|
|
2308
|
+
|
|
2309
|
+
html.gantt-global-cursor-resize,
|
|
2310
|
+
html.gantt-global-cursor-resize *,
|
|
2311
|
+
html.gantt-global-cursor-resize *::before,
|
|
2312
|
+
html.gantt-global-cursor-resize *::after {
|
|
2313
|
+
cursor: ew-resize !important;
|
|
2314
|
+
}
|
|
2315
|
+
`;
|
|
2316
|
+
document.head.appendChild(style);
|
|
2317
|
+
}
|
|
2318
|
+
function applyGlobalCursor(cursor) {
|
|
2319
|
+
if (typeof document === "undefined") return;
|
|
2320
|
+
ensureGlobalCursorStyle();
|
|
2321
|
+
globalLockedCursor = cursor;
|
|
2322
|
+
document.documentElement.classList.remove("gantt-global-cursor-grabbing", "gantt-global-cursor-resize");
|
|
2323
|
+
document.documentElement.classList.add(cursor === "grabbing" ? "gantt-global-cursor-grabbing" : "gantt-global-cursor-resize");
|
|
2324
|
+
document.body.style.cursor = cursor;
|
|
2325
|
+
document.documentElement.style.cursor = cursor;
|
|
2326
|
+
}
|
|
2327
|
+
function clearGlobalCursor() {
|
|
2328
|
+
if (typeof document === "undefined") return;
|
|
2329
|
+
globalLockedCursor = null;
|
|
2330
|
+
document.documentElement.classList.remove("gantt-global-cursor-grabbing", "gantt-global-cursor-resize");
|
|
2331
|
+
document.body.style.cursor = "";
|
|
2332
|
+
document.documentElement.style.cursor = "";
|
|
2333
|
+
}
|
|
2294
2334
|
function getDayOffsetFromMonthStart(date, monthStart) {
|
|
2295
2335
|
return Math.round(
|
|
2296
2336
|
(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()) - Date.UTC(monthStart.getUTCFullYear(), monthStart.getUTCMonth(), monthStart.getUTCDate())) / (24 * 60 * 60 * 1e3)
|
|
@@ -2301,6 +2341,7 @@ function completeDrag() {
|
|
|
2301
2341
|
cancelAnimationFrame(globalRafId);
|
|
2302
2342
|
globalRafId = null;
|
|
2303
2343
|
}
|
|
2344
|
+
clearGlobalCursor();
|
|
2304
2345
|
if (globalActiveDrag) {
|
|
2305
2346
|
globalActiveDrag.onCascadeProgress?.(/* @__PURE__ */ new Map(), []);
|
|
2306
2347
|
const { onComplete, currentLeft, currentWidth, mode } = globalActiveDrag;
|
|
@@ -2313,6 +2354,7 @@ function cancelDrag() {
|
|
|
2313
2354
|
cancelAnimationFrame(globalRafId);
|
|
2314
2355
|
globalRafId = null;
|
|
2315
2356
|
}
|
|
2357
|
+
clearGlobalCursor();
|
|
2316
2358
|
if (globalActiveDrag) {
|
|
2317
2359
|
const { onCancel } = globalActiveDrag;
|
|
2318
2360
|
globalActiveDrag = null;
|
|
@@ -2522,7 +2564,8 @@ var useTaskDrag = (options) => {
|
|
|
2522
2564
|
locked = false,
|
|
2523
2565
|
disableTaskDrag = false,
|
|
2524
2566
|
businessDays = true,
|
|
2525
|
-
weekendPredicate
|
|
2567
|
+
weekendPredicate,
|
|
2568
|
+
viewMode = "day"
|
|
2526
2569
|
} = options;
|
|
2527
2570
|
const rawHookTask = allTasks.find((t) => t.id === taskId);
|
|
2528
2571
|
const hookTask = rawHookTask ? normalizeTaskDatesForType(rawHookTask) : void 0;
|
|
@@ -2533,6 +2576,7 @@ var useTaskDrag = (options) => {
|
|
|
2533
2576
|
const [dragMode, setDragMode] = (0, import_react2.useState)(null);
|
|
2534
2577
|
const [currentLeft, setCurrentLeft] = (0, import_react2.useState)(0);
|
|
2535
2578
|
const [currentWidth, setCurrentWidth] = (0, import_react2.useState)(0);
|
|
2579
|
+
const [hoverCursor, setHoverCursor] = (0, import_react2.useState)("grab");
|
|
2536
2580
|
const getInitialPosition = (0, import_react2.useCallback)(() => {
|
|
2537
2581
|
const getUTCDayDifference2 = (date1, date2) => {
|
|
2538
2582
|
const ms1 = Date.UTC(
|
|
@@ -2711,28 +2755,33 @@ var useTaskDrag = (options) => {
|
|
|
2711
2755
|
}
|
|
2712
2756
|
};
|
|
2713
2757
|
}, []);
|
|
2714
|
-
const
|
|
2758
|
+
const startDrag = (0, import_react2.useCallback)((e) => {
|
|
2715
2759
|
if (effectiveLocked) return;
|
|
2716
2760
|
const target = e.currentTarget;
|
|
2717
|
-
const
|
|
2761
|
+
const currentTask = allTasks.find((t) => t.id === taskId);
|
|
2762
|
+
const isSingleDayTask = !!currentTask && !isMilestoneTask(currentTask) && !isTaskParent(taskId, allTasks) && currentWidth <= dayWidth && viewMode === "day";
|
|
2718
2763
|
let mode = null;
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
|
|
2764
|
+
if (isSingleDayTask) {
|
|
2765
|
+
mode = "move";
|
|
2766
|
+
} else {
|
|
2767
|
+
const edgeZone = detectEdgeZone(e.clientX, target, edgeZoneWidth);
|
|
2768
|
+
switch (edgeZone) {
|
|
2769
|
+
case "left":
|
|
2770
|
+
mode = "resize-left";
|
|
2771
|
+
break;
|
|
2772
|
+
case "right":
|
|
2773
|
+
mode = "resize-right";
|
|
2774
|
+
break;
|
|
2775
|
+
case "move":
|
|
2776
|
+
mode = "move";
|
|
2777
|
+
break;
|
|
2778
|
+
}
|
|
2729
2779
|
}
|
|
2730
2780
|
if (mode === "resize-left" || mode === "resize-right") {
|
|
2731
|
-
|
|
2732
|
-
if (currentTask2 && isTaskParent(taskId, allTasks)) {
|
|
2781
|
+
if (currentTask && isTaskParent(taskId, allTasks)) {
|
|
2733
2782
|
mode = "move";
|
|
2734
2783
|
}
|
|
2735
|
-
if (
|
|
2784
|
+
if (currentTask && isMilestoneTask(currentTask)) {
|
|
2736
2785
|
mode = "move";
|
|
2737
2786
|
}
|
|
2738
2787
|
}
|
|
@@ -2744,6 +2793,7 @@ var useTaskDrag = (options) => {
|
|
|
2744
2793
|
isOwnerRef.current = true;
|
|
2745
2794
|
setIsDragging(true);
|
|
2746
2795
|
setDragMode(mode);
|
|
2796
|
+
applyGlobalCursor(mode === "move" ? "grabbing" : "ew-resize");
|
|
2747
2797
|
if (onDragStateChange) {
|
|
2748
2798
|
onDragStateChange({
|
|
2749
2799
|
isDragging: true,
|
|
@@ -2753,10 +2803,10 @@ var useTaskDrag = (options) => {
|
|
|
2753
2803
|
});
|
|
2754
2804
|
}
|
|
2755
2805
|
ensureGlobalListeners();
|
|
2756
|
-
const
|
|
2806
|
+
const dragTask = allTasks.find((t) => t.id === taskId);
|
|
2757
2807
|
let hierarchyChain = [];
|
|
2758
|
-
if (
|
|
2759
|
-
const taskParentId =
|
|
2808
|
+
if (dragTask) {
|
|
2809
|
+
const taskParentId = dragTask.parentId;
|
|
2760
2810
|
if (taskParentId) {
|
|
2761
2811
|
const parentTask = allTasks.find((t) => t.id === taskParentId);
|
|
2762
2812
|
if (parentTask) {
|
|
@@ -2793,15 +2843,44 @@ var useTaskDrag = (options) => {
|
|
|
2793
2843
|
businessDays,
|
|
2794
2844
|
weekendPredicate
|
|
2795
2845
|
};
|
|
2796
|
-
}, [edgeZoneWidth, currentLeft, currentWidth, dayWidth, monthStart, taskId, onDragStateChange, handleProgress, handleComplete, handleCancel, allTasks, disableConstraints, onCascadeProgress, onCascade, effectiveLocked]);
|
|
2846
|
+
}, [edgeZoneWidth, currentLeft, currentWidth, dayWidth, monthStart, taskId, onDragStateChange, handleProgress, handleComplete, handleCancel, allTasks, disableConstraints, onCascadeProgress, onCascade, effectiveLocked, viewMode]);
|
|
2847
|
+
const handleMouseDown = (0, import_react2.useCallback)((e) => {
|
|
2848
|
+
startDrag(e);
|
|
2849
|
+
}, [startDrag]);
|
|
2850
|
+
const handleMouseMove = (0, import_react2.useCallback)((e) => {
|
|
2851
|
+
if (disableTaskDrag) {
|
|
2852
|
+
setHoverCursor("grab");
|
|
2853
|
+
return;
|
|
2854
|
+
}
|
|
2855
|
+
if (locked) {
|
|
2856
|
+
setHoverCursor("not-allowed");
|
|
2857
|
+
return;
|
|
2858
|
+
}
|
|
2859
|
+
if (isDragging) {
|
|
2860
|
+
setHoverCursor("grabbing");
|
|
2861
|
+
return;
|
|
2862
|
+
}
|
|
2863
|
+
const target = e.currentTarget;
|
|
2864
|
+
const currentTask = allTasks.find((t) => t.id === taskId);
|
|
2865
|
+
const isSingleDayTask = !!currentTask && !isMilestoneTask(currentTask) && !isTaskParent(taskId, allTasks) && currentWidth <= dayWidth && viewMode === "day";
|
|
2866
|
+
if (isSingleDayTask || currentTask && (isTaskParent(taskId, allTasks) || isMilestoneTask(currentTask))) {
|
|
2867
|
+
setHoverCursor("grab");
|
|
2868
|
+
return;
|
|
2869
|
+
}
|
|
2870
|
+
const edgeZone = detectEdgeZone(e.clientX, target, edgeZoneWidth);
|
|
2871
|
+
setHoverCursor(edgeZone === "move" ? "grab" : "ew-resize");
|
|
2872
|
+
}, [disableTaskDrag, locked, isDragging, allTasks, taskId, currentWidth, dayWidth, viewMode, edgeZoneWidth]);
|
|
2873
|
+
const handleMouseLeave = (0, import_react2.useCallback)(() => {
|
|
2874
|
+
setHoverCursor(disableTaskDrag ? "grab" : locked ? "not-allowed" : isDragging ? "grabbing" : "grab");
|
|
2875
|
+
}, [disableTaskDrag, locked, isDragging]);
|
|
2797
2876
|
const getCursorStyle = (0, import_react2.useCallback)(() => {
|
|
2798
2877
|
if (disableTaskDrag) return "grab";
|
|
2799
2878
|
if (locked) return "not-allowed";
|
|
2800
2879
|
if (isDragging) {
|
|
2801
|
-
return "grabbing";
|
|
2880
|
+
return dragMode === "move" ? "grabbing" : "ew-resize";
|
|
2802
2881
|
}
|
|
2803
|
-
return
|
|
2804
|
-
}, [disableTaskDrag, locked, isDragging]);
|
|
2882
|
+
return hoverCursor;
|
|
2883
|
+
}, [disableTaskDrag, locked, isDragging, dragMode, hoverCursor]);
|
|
2805
2884
|
return {
|
|
2806
2885
|
isDragging,
|
|
2807
2886
|
dragMode,
|
|
@@ -2809,6 +2888,8 @@ var useTaskDrag = (options) => {
|
|
|
2809
2888
|
currentWidth,
|
|
2810
2889
|
dragHandleProps: {
|
|
2811
2890
|
onMouseDown: handleMouseDown,
|
|
2891
|
+
onMouseMove: handleMouseMove,
|
|
2892
|
+
onMouseLeave: handleMouseLeave,
|
|
2812
2893
|
style: {
|
|
2813
2894
|
cursor: getCursorStyle(),
|
|
2814
2895
|
userSelect: "none"
|
|
@@ -2820,10 +2901,10 @@ var useTaskDrag = (options) => {
|
|
|
2820
2901
|
// src/components/TaskRow/TaskRow.tsx
|
|
2821
2902
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
2822
2903
|
var arePropsEqual = (prevProps, nextProps) => {
|
|
2823
|
-
return prevProps.task.id === nextProps.task.id && prevProps.task.name === nextProps.task.name && prevProps.task.startDate === nextProps.task.startDate && prevProps.task.endDate === nextProps.task.endDate && prevProps.task.baselineStartDate === nextProps.task.baselineStartDate && prevProps.task.baselineEndDate === nextProps.task.baselineEndDate && prevProps.task.type === nextProps.task.type && prevProps.task.color === nextProps.task.color && prevProps.task.progress === nextProps.task.progress && prevProps.task.accepted === nextProps.task.accepted && prevProps.monthStart.getTime() === nextProps.monthStart.getTime() && prevProps.dayWidth === nextProps.dayWidth && prevProps.rowHeight === nextProps.rowHeight && prevProps.overridePosition?.left === nextProps.overridePosition?.left && prevProps.overridePosition?.width === nextProps.overridePosition?.width && prevProps.allTasks === nextProps.allTasks && prevProps.disableConstraints === nextProps.disableConstraints && prevProps.task.locked === nextProps.task.locked && prevProps.task.divider === nextProps.task.divider && prevProps.highlightExpiredTasks === nextProps.highlightExpiredTasks && prevProps.showBaseline === nextProps.showBaseline && prevProps.isFilterMatch === nextProps.isFilterMatch && prevProps.businessDays === nextProps.businessDays && prevProps.customDays === nextProps.customDays && prevProps.isWeekend === nextProps.isWeekend && prevProps.disableTaskDrag === nextProps.disableTaskDrag;
|
|
2904
|
+
return prevProps.task.id === nextProps.task.id && prevProps.task.name === nextProps.task.name && prevProps.task.startDate === nextProps.task.startDate && prevProps.task.endDate === nextProps.task.endDate && prevProps.task.baselineStartDate === nextProps.task.baselineStartDate && prevProps.task.baselineEndDate === nextProps.task.baselineEndDate && prevProps.task.type === nextProps.task.type && prevProps.task.color === nextProps.task.color && prevProps.task.progress === nextProps.task.progress && prevProps.task.accepted === nextProps.task.accepted && prevProps.monthStart.getTime() === nextProps.monthStart.getTime() && prevProps.dayWidth === nextProps.dayWidth && prevProps.rowHeight === nextProps.rowHeight && prevProps.overridePosition?.left === nextProps.overridePosition?.left && prevProps.overridePosition?.width === nextProps.overridePosition?.width && prevProps.allTasks === nextProps.allTasks && prevProps.disableConstraints === nextProps.disableConstraints && prevProps.task.locked === nextProps.task.locked && prevProps.task.divider === nextProps.task.divider && prevProps.highlightExpiredTasks === nextProps.highlightExpiredTasks && prevProps.showBaseline === nextProps.showBaseline && prevProps.isFilterMatch === nextProps.isFilterMatch && prevProps.businessDays === nextProps.businessDays && prevProps.customDays === nextProps.customDays && prevProps.isWeekend === nextProps.isWeekend && prevProps.disableTaskDrag === nextProps.disableTaskDrag && prevProps.viewMode === nextProps.viewMode;
|
|
2824
2905
|
};
|
|
2825
2906
|
var TaskRow = import_react3.default.memo(
|
|
2826
|
-
({ task, monthStart, dayWidth, rowHeight, onTasksChange, onDragStateChange, rowIndex, allTasks, enableAutoSchedule, disableConstraints, overridePosition, onCascadeProgress, onCascade, divider, highlightExpiredTasks, showBaseline = false, isFilterMatch = false, businessDays, customDays, isWeekend: isWeekend3, disableTaskDrag = false }) => {
|
|
2907
|
+
({ task, monthStart, dayWidth, rowHeight, onTasksChange, onDragStateChange, rowIndex, allTasks, enableAutoSchedule, disableConstraints, overridePosition, onCascadeProgress, onCascade, divider, highlightExpiredTasks, showBaseline = false, isFilterMatch = false, businessDays, customDays, isWeekend: isWeekend3, disableTaskDrag = false, viewMode = "day" }) => {
|
|
2827
2908
|
const defaultParentBarColor = "#782FC4";
|
|
2828
2909
|
const { divider: taskDivider } = task;
|
|
2829
2910
|
const normalizedTask = (0, import_react3.useMemo)(() => normalizeTaskDatesForType(task), [task]);
|
|
@@ -2936,7 +3017,8 @@ var TaskRow = import_react3.default.memo(
|
|
|
2936
3017
|
onCascadeProgress,
|
|
2937
3018
|
onCascade,
|
|
2938
3019
|
businessDays,
|
|
2939
|
-
weekendPredicate
|
|
3020
|
+
weekendPredicate,
|
|
3021
|
+
viewMode
|
|
2940
3022
|
});
|
|
2941
3023
|
const displayLeft = overridePosition?.left ?? (isDragging ? currentLeft : left);
|
|
2942
3024
|
const displayWidth = overridePosition?.width ?? (isDragging ? currentWidth : width);
|
|
@@ -3012,6 +3094,8 @@ var TaskRow = import_react3.default.memo(
|
|
|
3012
3094
|
userSelect: dragHandleProps.style.userSelect
|
|
3013
3095
|
},
|
|
3014
3096
|
onMouseDown: dragHandleProps.onMouseDown,
|
|
3097
|
+
onMouseMove: dragHandleProps.onMouseMove,
|
|
3098
|
+
onMouseLeave: dragHandleProps.onMouseLeave,
|
|
3015
3099
|
children: [
|
|
3016
3100
|
!milestone && progressWidth > 0 && progressWidth < 100 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
3017
3101
|
"div",
|
|
@@ -4757,6 +4841,8 @@ var TaskListRow = import_react10.default.memo(
|
|
|
4757
4841
|
isFilterMatch = false,
|
|
4758
4842
|
isFilterHideMode = false,
|
|
4759
4843
|
resolvedColumns,
|
|
4844
|
+
isTaskSelected = false,
|
|
4845
|
+
onTaskSelectionChange,
|
|
4760
4846
|
taskListMenuCommands = []
|
|
4761
4847
|
}) => {
|
|
4762
4848
|
const [editingColumnId, setEditingColumnId] = (0, import_react10.useState)(null);
|
|
@@ -5550,6 +5636,23 @@ var TaskListRow = import_react10.default.memo(
|
|
|
5550
5636
|
const isSelectedDependencyOwner = selectedChip != null && selectedChip.successorId === task.id;
|
|
5551
5637
|
const startDateISO = toISODate2(normalizedTask.startDate);
|
|
5552
5638
|
const endDateISO = editingDuration ? getEndDate(normalizedTask.startDate, durationValue) : toISODate2(normalizedTask.endDate);
|
|
5639
|
+
const selectionCell = /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
5640
|
+
"div",
|
|
5641
|
+
{
|
|
5642
|
+
className: "gantt-tl-cell gantt-tl-cell-selection",
|
|
5643
|
+
onClick: (e) => e.stopPropagation(),
|
|
5644
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
5645
|
+
"input",
|
|
5646
|
+
{
|
|
5647
|
+
type: "checkbox",
|
|
5648
|
+
className: "gantt-tl-selection-checkbox",
|
|
5649
|
+
"aria-label": `\u0412\u044B\u0431\u0440\u0430\u0442\u044C \u0437\u0430\u0434\u0430\u0447\u0443 ${taskNumber ? `${taskNumber}. ` : ""}${task.name}`,
|
|
5650
|
+
checked: isTaskSelected,
|
|
5651
|
+
onChange: (event) => onTaskSelectionChange?.(task.id, event.target.checked)
|
|
5652
|
+
}
|
|
5653
|
+
)
|
|
5654
|
+
}
|
|
5655
|
+
);
|
|
5553
5656
|
const numberCell = /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
5554
5657
|
"div",
|
|
5555
5658
|
{
|
|
@@ -6267,6 +6370,7 @@ var TaskListRow = import_react10.default.memo(
|
|
|
6267
6370
|
}
|
|
6268
6371
|
);
|
|
6269
6372
|
const builtInCells = {
|
|
6373
|
+
selection: selectionCell,
|
|
6270
6374
|
number: numberCell,
|
|
6271
6375
|
name: nameCell,
|
|
6272
6376
|
startDate: startDateCell,
|
|
@@ -6419,6 +6523,7 @@ var NewTaskRow = ({
|
|
|
6419
6523
|
|
|
6420
6524
|
// src/components/TaskList/columns/createBuiltInColumns.tsx
|
|
6421
6525
|
var BUILT_IN_COLUMN_WIDTHS = {
|
|
6526
|
+
selection: 36,
|
|
6422
6527
|
number: 40,
|
|
6423
6528
|
name: 200,
|
|
6424
6529
|
startDate: 90,
|
|
@@ -6429,7 +6534,7 @@ var BUILT_IN_COLUMN_WIDTHS = {
|
|
|
6429
6534
|
actions: 80
|
|
6430
6535
|
};
|
|
6431
6536
|
function createBuiltInColumns(opts) {
|
|
6432
|
-
|
|
6537
|
+
const columns = [
|
|
6433
6538
|
{ id: "number", header: "\u2116", width: BUILT_IN_COLUMN_WIDTHS.number, renderCell: () => null },
|
|
6434
6539
|
{ id: "name", header: "\u0418\u043C\u044F", width: BUILT_IN_COLUMN_WIDTHS.name, renderCell: () => null },
|
|
6435
6540
|
{ id: "startDate", header: "\u041D\u0430\u0447\u0430\u043B\u043E", width: BUILT_IN_COLUMN_WIDTHS.startDate, renderCell: () => null },
|
|
@@ -6438,6 +6543,15 @@ function createBuiltInColumns(opts) {
|
|
|
6438
6543
|
{ id: "progress", header: "%", width: BUILT_IN_COLUMN_WIDTHS.progress, renderCell: () => null },
|
|
6439
6544
|
{ id: "dependencies", header: null, width: BUILT_IN_COLUMN_WIDTHS.dependencies, renderCell: () => null }
|
|
6440
6545
|
];
|
|
6546
|
+
if (opts?.enableTaskMultiSelect) {
|
|
6547
|
+
columns.unshift({
|
|
6548
|
+
id: "selection",
|
|
6549
|
+
header: null,
|
|
6550
|
+
width: BUILT_IN_COLUMN_WIDTHS.selection,
|
|
6551
|
+
renderCell: () => null
|
|
6552
|
+
});
|
|
6553
|
+
}
|
|
6554
|
+
return columns;
|
|
6441
6555
|
}
|
|
6442
6556
|
|
|
6443
6557
|
// src/components/TaskList/columns/resolveTaskListColumns.ts
|
|
@@ -6498,6 +6612,7 @@ var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
|
6498
6612
|
var LINK_TYPE_ORDER2 = ["FS", "SS", "FF", "SF"];
|
|
6499
6613
|
var MIN_TASK_LIST_WIDTH = 530;
|
|
6500
6614
|
var BUILT_IN_CSS_CLASSES = {
|
|
6615
|
+
selection: "gantt-tl-cell-selection",
|
|
6501
6616
|
number: "gantt-tl-cell-number",
|
|
6502
6617
|
name: "gantt-tl-cell-name",
|
|
6503
6618
|
startDate: "gantt-tl-cell-date",
|
|
@@ -6573,6 +6688,30 @@ function getTaskNumber(tasks, taskIndex) {
|
|
|
6573
6688
|
}
|
|
6574
6689
|
return `${parentNumber}.${siblingIndex + 1}`;
|
|
6575
6690
|
}
|
|
6691
|
+
var SelectAllCheckbox = ({
|
|
6692
|
+
checked,
|
|
6693
|
+
indeterminate,
|
|
6694
|
+
onChange
|
|
6695
|
+
}) => {
|
|
6696
|
+
const ref = (0, import_react12.useRef)(null);
|
|
6697
|
+
(0, import_react12.useEffect)(() => {
|
|
6698
|
+
if (ref.current) {
|
|
6699
|
+
ref.current.indeterminate = indeterminate;
|
|
6700
|
+
}
|
|
6701
|
+
}, [indeterminate]);
|
|
6702
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
6703
|
+
"input",
|
|
6704
|
+
{
|
|
6705
|
+
ref,
|
|
6706
|
+
type: "checkbox",
|
|
6707
|
+
className: "gantt-tl-selection-checkbox",
|
|
6708
|
+
"aria-label": "\u0412\u044B\u0431\u0440\u0430\u0442\u044C \u0432\u0441\u0435 \u0432\u0438\u0434\u0438\u043C\u044B\u0435 \u0437\u0430\u0434\u0430\u0447\u0438",
|
|
6709
|
+
checked,
|
|
6710
|
+
onChange: (event) => onChange(event.target.checked),
|
|
6711
|
+
onClick: (event) => event.stopPropagation()
|
|
6712
|
+
}
|
|
6713
|
+
);
|
|
6714
|
+
};
|
|
6576
6715
|
var TaskList = ({
|
|
6577
6716
|
tasks,
|
|
6578
6717
|
rowHeight,
|
|
@@ -6603,6 +6742,9 @@ var TaskList = ({
|
|
|
6603
6742
|
isWeekend: isWeekend3,
|
|
6604
6743
|
businessDays,
|
|
6605
6744
|
highlightedTaskIds = /* @__PURE__ */ new Set(),
|
|
6745
|
+
enableTaskMultiSelect = false,
|
|
6746
|
+
selectedTaskIds,
|
|
6747
|
+
onSelectedTaskIdsChange,
|
|
6606
6748
|
filterMode = "highlight",
|
|
6607
6749
|
filteredTaskIds = /* @__PURE__ */ new Set(),
|
|
6608
6750
|
isFilterActive = false,
|
|
@@ -6610,6 +6752,14 @@ var TaskList = ({
|
|
|
6610
6752
|
hiddenTaskListColumns,
|
|
6611
6753
|
taskListMenuCommands
|
|
6612
6754
|
}) => {
|
|
6755
|
+
const [internalSelectedTaskIds, setInternalSelectedTaskIds] = (0, import_react12.useState)(/* @__PURE__ */ new Set());
|
|
6756
|
+
const effectiveSelectedTaskIds = selectedTaskIds ?? internalSelectedTaskIds;
|
|
6757
|
+
const emitSelectedTaskIdsChange = (0, import_react12.useCallback)((nextSelectedTaskIds) => {
|
|
6758
|
+
if (!selectedTaskIds) {
|
|
6759
|
+
setInternalSelectedTaskIds(nextSelectedTaskIds);
|
|
6760
|
+
}
|
|
6761
|
+
onSelectedTaskIdsChange?.(nextSelectedTaskIds);
|
|
6762
|
+
}, [onSelectedTaskIdsChange, selectedTaskIds]);
|
|
6613
6763
|
const [internalCollapsedParentIds, setInternalCollapsedParentIds] = (0, import_react12.useState)(/* @__PURE__ */ new Set());
|
|
6614
6764
|
const collapsedParentIds = externalCollapsedParentIds ?? internalCollapsedParentIds;
|
|
6615
6765
|
const handleToggleCollapse = externalOnToggleCollapse ?? (0, import_react12.useCallback)((parentId) => {
|
|
@@ -6656,6 +6806,33 @@ var TaskList = ({
|
|
|
6656
6806
|
),
|
|
6657
6807
|
[visibleTasks]
|
|
6658
6808
|
);
|
|
6809
|
+
const visibleTaskIds = (0, import_react12.useMemo)(() => visibleTasks.map((task) => task.id), [visibleTasks]);
|
|
6810
|
+
const selectedVisibleTaskCount = (0, import_react12.useMemo)(
|
|
6811
|
+
() => visibleTaskIds.filter((taskId) => effectiveSelectedTaskIds.has(taskId)).length,
|
|
6812
|
+
[effectiveSelectedTaskIds, visibleTaskIds]
|
|
6813
|
+
);
|
|
6814
|
+
const areAllVisibleTasksSelected = visibleTaskIds.length > 0 && selectedVisibleTaskCount === visibleTaskIds.length;
|
|
6815
|
+
const areSomeVisibleTasksSelected = selectedVisibleTaskCount > 0 && !areAllVisibleTasksSelected;
|
|
6816
|
+
const handleToggleTaskSelection = (0, import_react12.useCallback)((taskId, checked) => {
|
|
6817
|
+
const nextSelectedTaskIds = new Set(effectiveSelectedTaskIds);
|
|
6818
|
+
if (checked) {
|
|
6819
|
+
nextSelectedTaskIds.add(taskId);
|
|
6820
|
+
} else {
|
|
6821
|
+
nextSelectedTaskIds.delete(taskId);
|
|
6822
|
+
}
|
|
6823
|
+
emitSelectedTaskIdsChange(nextSelectedTaskIds);
|
|
6824
|
+
}, [effectiveSelectedTaskIds, emitSelectedTaskIdsChange]);
|
|
6825
|
+
const handleToggleAllVisibleTaskSelection = (0, import_react12.useCallback)((checked) => {
|
|
6826
|
+
const nextSelectedTaskIds = new Set(effectiveSelectedTaskIds);
|
|
6827
|
+
for (const taskId of visibleTaskIds) {
|
|
6828
|
+
if (checked) {
|
|
6829
|
+
nextSelectedTaskIds.add(taskId);
|
|
6830
|
+
} else {
|
|
6831
|
+
nextSelectedTaskIds.delete(taskId);
|
|
6832
|
+
}
|
|
6833
|
+
}
|
|
6834
|
+
emitSelectedTaskIdsChange(nextSelectedTaskIds);
|
|
6835
|
+
}, [effectiveSelectedTaskIds, emitSelectedTaskIdsChange, visibleTaskIds]);
|
|
6659
6836
|
const originalTaskNumberMap = (0, import_react12.useMemo)(
|
|
6660
6837
|
() => {
|
|
6661
6838
|
const numberMap = /* @__PURE__ */ new Map();
|
|
@@ -7137,7 +7314,10 @@ var TaskList = ({
|
|
|
7137
7314
|
const duplicatedTasks = duplicateTaskSubtree(taskId, orderedTasks);
|
|
7138
7315
|
onReorder?.(duplicatedTasks);
|
|
7139
7316
|
}, [orderedTasks, onReorder]);
|
|
7140
|
-
const builtInColumns = (0, import_react12.useMemo)(
|
|
7317
|
+
const builtInColumns = (0, import_react12.useMemo)(
|
|
7318
|
+
() => createBuiltInColumns({ businessDays, enableTaskMultiSelect }),
|
|
7319
|
+
[businessDays, enableTaskMultiSelect]
|
|
7320
|
+
);
|
|
7141
7321
|
const resolvedColumns = (0, import_react12.useMemo)(
|
|
7142
7322
|
() => resolveTaskListColumns(
|
|
7143
7323
|
builtInColumns,
|
|
@@ -7161,6 +7341,24 @@ var TaskList = ({
|
|
|
7161
7341
|
style: { "--tasklist-width": `${effectiveTaskListWidth}px` },
|
|
7162
7342
|
children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "gantt-tl-table", children: [
|
|
7163
7343
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "gantt-tl-header", style: { height: `${tableHeaderHeight}px` }, children: resolvedColumns.map((col) => {
|
|
7344
|
+
if (col.id === "selection") {
|
|
7345
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
7346
|
+
"div",
|
|
7347
|
+
{
|
|
7348
|
+
className: "gantt-tl-headerCell gantt-tl-cell-selection",
|
|
7349
|
+
"data-column-id": "selection",
|
|
7350
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
7351
|
+
SelectAllCheckbox,
|
|
7352
|
+
{
|
|
7353
|
+
checked: areAllVisibleTasksSelected,
|
|
7354
|
+
indeterminate: areSomeVisibleTasksSelected,
|
|
7355
|
+
onChange: handleToggleAllVisibleTaskSelection
|
|
7356
|
+
}
|
|
7357
|
+
)
|
|
7358
|
+
},
|
|
7359
|
+
col.id
|
|
7360
|
+
);
|
|
7361
|
+
}
|
|
7164
7362
|
if (col.id === "dependencies") {
|
|
7165
7363
|
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
7166
7364
|
"div",
|
|
@@ -7286,6 +7484,8 @@ var TaskList = ({
|
|
|
7286
7484
|
isFilterMatch: filterMode === "highlight" ? highlightedTaskIds.has(task.id) : false,
|
|
7287
7485
|
isFilterHideMode: filterMode === "hide" && isFilterActive,
|
|
7288
7486
|
resolvedColumns,
|
|
7487
|
+
isTaskSelected: effectiveSelectedTaskIds.has(task.id),
|
|
7488
|
+
onTaskSelectionChange: handleToggleTaskSelection,
|
|
7289
7489
|
taskListMenuCommands
|
|
7290
7490
|
}
|
|
7291
7491
|
),
|
|
@@ -9366,6 +9566,9 @@ function TaskGanttChartInner(props, ref) {
|
|
|
9366
9566
|
collapsedParentIds: externalCollapsedParentIds,
|
|
9367
9567
|
onToggleCollapse: externalOnToggleCollapse,
|
|
9368
9568
|
highlightedTaskIds,
|
|
9569
|
+
enableTaskMultiSelect = false,
|
|
9570
|
+
selectedTaskIds,
|
|
9571
|
+
onSelectedTaskIdsChange,
|
|
9369
9572
|
disableTaskDrag = false,
|
|
9370
9573
|
showChart = true,
|
|
9371
9574
|
additionalColumns,
|
|
@@ -9936,6 +10139,9 @@ function TaskGanttChartInner(props, ref) {
|
|
|
9936
10139
|
onDemoteTask: onDemoteTask ?? handleDemoteTask,
|
|
9937
10140
|
onUngroupTask: onUngroupTask ?? handleUngroupTask,
|
|
9938
10141
|
highlightedTaskIds: taskListHighlightedTaskIds,
|
|
10142
|
+
enableTaskMultiSelect,
|
|
10143
|
+
selectedTaskIds,
|
|
10144
|
+
onSelectedTaskIdsChange,
|
|
9939
10145
|
customDays,
|
|
9940
10146
|
isWeekend: isWeekend3,
|
|
9941
10147
|
businessDays,
|
|
@@ -10046,7 +10252,8 @@ function TaskGanttChartInner(props, ref) {
|
|
|
10046
10252
|
businessDays,
|
|
10047
10253
|
customDays,
|
|
10048
10254
|
isWeekend: isWeekend3,
|
|
10049
|
-
disableTaskDrag
|
|
10255
|
+
disableTaskDrag,
|
|
10256
|
+
viewMode
|
|
10050
10257
|
},
|
|
10051
10258
|
task.id
|
|
10052
10259
|
))
|