gantt-lib 0.85.0 → 0.85.1

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.
@@ -93,7 +93,7 @@ interface TaskDependency {
93
93
  taskId: string;
94
94
  /** Type of link: FS (finish-to-start), SS, FF, SF */
95
95
  type: LinkType;
96
- /** Lag in days (positive or negative integer) */
96
+ /** Lag in days. FS lag is clamped to zero. */
97
97
  lag: number;
98
98
  }
99
99
  /**
@@ -350,7 +350,11 @@ declare function normalizePredecessorDates(predecessor: Pick<Task, 'startDate' |
350
350
  */
351
351
  declare function getDependencyLag(dep: Pick<TaskDependency, 'lag'>): number;
352
352
  /**
353
- * Normalize lag for FS links clamp to >= -predecessorDuration.
353
+ * Return a copy of a task with impossible dependency lag values reset.
354
+ */
355
+ declare function normalizeTaskDependencyLags<TTask extends Pick<Task, 'dependencies'>>(task: TTask): TTask;
356
+ /**
357
+ * Normalize lag for links whose domain rules restrict negative offsets.
354
358
  */
355
359
  declare function normalizeDependencyLag(linkType: LinkType, lag: number, predecessorStart: Date, predecessorEnd: Date, businessDays?: boolean, weekendPredicate?: (date: Date) => boolean): number;
356
360
  /**
@@ -566,4 +570,4 @@ declare function isAncestorTask(ancestorId: string, taskId: string, tasks: Task[
566
570
  */
567
571
  declare function areTasksHierarchicallyRelated(taskId1: string, taskId2: string, tasks: Task[]): boolean;
568
572
 
569
- export { universalCascade as $, getDependencyLag as A, getSuccessorChain as B, getTaskDuration as C, DAY_MS as D, getTransitiveCascadeChain as E, isAncestorTask as F, type GanttChartMode as G, isTaskParent as H, moveTaskRange as I, moveTaskWithCascade as J, normalizeDependencyLag as K, type LinkType as L, type MonthSpan as M, normalizePredecessorDates as N, normalizeUTCDate as O, parseDateOnly as P, recalculateIncomingLags as Q, type ResourceTimelineItem as R, recalculateProjectSchedule as S, type Task as T, recalculateTaskFromDependencies as U, type ValidationResult as V, type WeekendBlock as W, reflowTasksOnModeSwitch as X, removeDependenciesBetweenTasks as Y, resizeTaskWithCascade as Z, shiftBusinessDayOffset as _, type ResourcePlannerChartProps as a, validateDependencies as a0, type ScheduleCommandOptions as a1, type ScheduleCommandResult as a2, type ScheduleDependency as a3, type ScheduleTask as a4, type ScheduleTaskUpdate as a5, type TaskDependency as a6, addBusinessDays as a7, getBusinessDaysCount as a8, subtractBusinessDays as a9, type ResourceTimelineResource as b, type DependencyError as c, type GanttDateRange as d, type GridConfig as e, type GridLine as f, type ResourceTimelineMove as g, type ResourceTimelineResourceMenuCommand as h, type TaskBarGeometry as i, alignToWorkingDay as j, areTasksHierarchicallyRelated as k, buildAdjacencyList as l, buildTaskRangeFromEnd as m, buildTaskRangeFromStart as n, calculateSuccessorDate as o, cascadeByLinks as p, clampTaskRangeForIncomingFS as q, computeLagFromDates as r, computeParentDates as s, computeParentProgress as t, detectCycles as u, findParentId as v, getAllDependencyEdges as w, getAllDescendants as x, getBusinessDayOffset as y, getChildren as z };
573
+ export { shiftBusinessDayOffset as $, getDependencyLag as A, getSuccessorChain as B, getTaskDuration as C, DAY_MS as D, getTransitiveCascadeChain as E, isAncestorTask as F, type GanttChartMode as G, isTaskParent as H, moveTaskRange as I, moveTaskWithCascade as J, normalizeDependencyLag as K, type LinkType as L, type MonthSpan as M, normalizePredecessorDates as N, normalizeTaskDependencyLags as O, normalizeUTCDate as P, parseDateOnly as Q, type ResourceTimelineItem as R, recalculateIncomingLags as S, type Task as T, recalculateProjectSchedule as U, type ValidationResult as V, type WeekendBlock as W, recalculateTaskFromDependencies as X, reflowTasksOnModeSwitch as Y, removeDependenciesBetweenTasks as Z, resizeTaskWithCascade as _, type ResourcePlannerChartProps as a, universalCascade as a0, validateDependencies as a1, type ScheduleCommandOptions as a2, type ScheduleCommandResult as a3, type ScheduleDependency as a4, type ScheduleTask as a5, type ScheduleTaskUpdate as a6, type TaskDependency as a7, addBusinessDays as a8, getBusinessDaysCount as a9, subtractBusinessDays as aa, type ResourceTimelineResource as b, type DependencyError as c, type GanttDateRange as d, type GridConfig as e, type GridLine as f, type ResourceTimelineMove as g, type ResourceTimelineResourceMenuCommand as h, type TaskBarGeometry as i, alignToWorkingDay as j, areTasksHierarchicallyRelated as k, buildAdjacencyList as l, buildTaskRangeFromEnd as m, buildTaskRangeFromStart as n, calculateSuccessorDate as o, cascadeByLinks as p, clampTaskRangeForIncomingFS as q, computeLagFromDates as r, computeParentDates as s, computeParentProgress as t, detectCycles as u, findParentId as v, getAllDependencyEdges as w, getAllDescendants as x, getBusinessDayOffset as y, getChildren as z };
package/dist/index.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import React$1, { ReactNode } from 'react';
2
- import { T as Task$1, R as ResourceTimelineItem, V as ValidationResult, a as ResourcePlannerChartProps, b as ResourceTimelineResource } from './index-DGOZyXZt.mjs';
3
- export { D as DAY_MS, c as DependencyError, G as GanttChartMode, d as GanttDateRange, e as GridConfig, f as GridLine, L as LinkType, M as MonthSpan, g as ResourceTimelineMove, h as ResourceTimelineResourceMenuCommand, i as TaskBarGeometry, W as WeekendBlock, j as alignToWorkingDay, k as areTasksHierarchicallyRelated, l as buildAdjacencyList, m as buildTaskRangeFromEnd, n as buildTaskRangeFromStart, o as calculateSuccessorDate, p as cascadeByLinks, q as clampTaskRangeForIncomingFS, r as computeLagFromDates, s as computeParentDates, t as computeParentProgress, u as detectCycles, v as findParentId, w as getAllDependencyEdges, x as getAllDescendants, y as getBusinessDayOffset, z as getChildren, A as getDependencyLag, B as getSuccessorChain, C as getTaskDuration, E as getTransitiveCascadeChain, F as isAncestorTask, H as isTaskParent, I as moveTaskRange, J as moveTaskWithCascade, K as normalizeDependencyLag, N as normalizePredecessorDates, O as normalizeUTCDate, P as parseDateOnly, Q as recalculateIncomingLags, S as recalculateProjectSchedule, U as recalculateTaskFromDependencies, X as reflowTasksOnModeSwitch, Y as removeDependenciesBetweenTasks, Z as resizeTaskWithCascade, _ as shiftBusinessDayOffset, $ as universalCascade, a0 as validateDependencies } from './index-DGOZyXZt.mjs';
2
+ import { T as Task$1, R as ResourceTimelineItem, V as ValidationResult, a as ResourcePlannerChartProps, b as ResourceTimelineResource } from './index-BbdHmt1Q.mjs';
3
+ export { D as DAY_MS, c as DependencyError, G as GanttChartMode, d as GanttDateRange, e as GridConfig, f as GridLine, L as LinkType, M as MonthSpan, g as ResourceTimelineMove, h as ResourceTimelineResourceMenuCommand, i as TaskBarGeometry, W as WeekendBlock, j as alignToWorkingDay, k as areTasksHierarchicallyRelated, l as buildAdjacencyList, m as buildTaskRangeFromEnd, n as buildTaskRangeFromStart, o as calculateSuccessorDate, p as cascadeByLinks, q as clampTaskRangeForIncomingFS, r as computeLagFromDates, s as computeParentDates, t as computeParentProgress, u as detectCycles, v as findParentId, w as getAllDependencyEdges, x as getAllDescendants, y as getBusinessDayOffset, z as getChildren, A as getDependencyLag, B as getSuccessorChain, C as getTaskDuration, E as getTransitiveCascadeChain, F as isAncestorTask, H as isTaskParent, I as moveTaskRange, J as moveTaskWithCascade, K as normalizeDependencyLag, N as normalizePredecessorDates, O as normalizeTaskDependencyLags, P as normalizeUTCDate, Q as parseDateOnly, S as recalculateIncomingLags, U as recalculateProjectSchedule, X as recalculateTaskFromDependencies, Y as reflowTasksOnModeSwitch, Z as removeDependenciesBetweenTasks, _ as resizeTaskWithCascade, $ as shiftBusinessDayOffset, a0 as universalCascade, a1 as validateDependencies } from './index-BbdHmt1Q.mjs';
4
4
  import * as react_jsx_runtime from 'react/jsx-runtime';
5
5
  import * as RadixPopover from '@radix-ui/react-popover';
6
6
 
@@ -372,7 +372,7 @@ interface Task {
372
372
  * Optional array of task dependencies
373
373
  * - Each dependency references a predecessor task by ID
374
374
  * - Supports 4 link types: FS (finish-to-start), SS (start-to-start), FF (finish-to-finish), SF (start-to-finish)
375
- * - Lag is required (positive = delay, negative = overlap)
375
+ * - Lag is required (positive = delay; FS lag is clamped to zero)
376
376
  */
377
377
  dependencies?: TaskDependency[];
378
378
  /**
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import React$1, { ReactNode } from 'react';
2
- import { T as Task$1, R as ResourceTimelineItem, V as ValidationResult, a as ResourcePlannerChartProps, b as ResourceTimelineResource } from './index-DGOZyXZt.js';
3
- export { D as DAY_MS, c as DependencyError, G as GanttChartMode, d as GanttDateRange, e as GridConfig, f as GridLine, L as LinkType, M as MonthSpan, g as ResourceTimelineMove, h as ResourceTimelineResourceMenuCommand, i as TaskBarGeometry, W as WeekendBlock, j as alignToWorkingDay, k as areTasksHierarchicallyRelated, l as buildAdjacencyList, m as buildTaskRangeFromEnd, n as buildTaskRangeFromStart, o as calculateSuccessorDate, p as cascadeByLinks, q as clampTaskRangeForIncomingFS, r as computeLagFromDates, s as computeParentDates, t as computeParentProgress, u as detectCycles, v as findParentId, w as getAllDependencyEdges, x as getAllDescendants, y as getBusinessDayOffset, z as getChildren, A as getDependencyLag, B as getSuccessorChain, C as getTaskDuration, E as getTransitiveCascadeChain, F as isAncestorTask, H as isTaskParent, I as moveTaskRange, J as moveTaskWithCascade, K as normalizeDependencyLag, N as normalizePredecessorDates, O as normalizeUTCDate, P as parseDateOnly, Q as recalculateIncomingLags, S as recalculateProjectSchedule, U as recalculateTaskFromDependencies, X as reflowTasksOnModeSwitch, Y as removeDependenciesBetweenTasks, Z as resizeTaskWithCascade, _ as shiftBusinessDayOffset, $ as universalCascade, a0 as validateDependencies } from './index-DGOZyXZt.js';
2
+ import { T as Task$1, R as ResourceTimelineItem, V as ValidationResult, a as ResourcePlannerChartProps, b as ResourceTimelineResource } from './index-BbdHmt1Q.js';
3
+ export { D as DAY_MS, c as DependencyError, G as GanttChartMode, d as GanttDateRange, e as GridConfig, f as GridLine, L as LinkType, M as MonthSpan, g as ResourceTimelineMove, h as ResourceTimelineResourceMenuCommand, i as TaskBarGeometry, W as WeekendBlock, j as alignToWorkingDay, k as areTasksHierarchicallyRelated, l as buildAdjacencyList, m as buildTaskRangeFromEnd, n as buildTaskRangeFromStart, o as calculateSuccessorDate, p as cascadeByLinks, q as clampTaskRangeForIncomingFS, r as computeLagFromDates, s as computeParentDates, t as computeParentProgress, u as detectCycles, v as findParentId, w as getAllDependencyEdges, x as getAllDescendants, y as getBusinessDayOffset, z as getChildren, A as getDependencyLag, B as getSuccessorChain, C as getTaskDuration, E as getTransitiveCascadeChain, F as isAncestorTask, H as isTaskParent, I as moveTaskRange, J as moveTaskWithCascade, K as normalizeDependencyLag, N as normalizePredecessorDates, O as normalizeTaskDependencyLags, P as normalizeUTCDate, Q as parseDateOnly, S as recalculateIncomingLags, U as recalculateProjectSchedule, X as recalculateTaskFromDependencies, Y as reflowTasksOnModeSwitch, Z as removeDependenciesBetweenTasks, _ as resizeTaskWithCascade, $ as shiftBusinessDayOffset, a0 as universalCascade, a1 as validateDependencies } from './index-BbdHmt1Q.js';
4
4
  import * as react_jsx_runtime from 'react/jsx-runtime';
5
5
  import * as RadixPopover from '@radix-ui/react-popover';
6
6
 
@@ -372,7 +372,7 @@ interface Task {
372
372
  * Optional array of task dependencies
373
373
  * - Each dependency references a predecessor task by ID
374
374
  * - Supports 4 link types: FS (finish-to-start), SS (start-to-start), FF (finish-to-finish), SF (start-to-finish)
375
- * - Lag is required (positive = delay, negative = overlap)
375
+ * - Lag is required (positive = delay; FS lag is clamped to zero)
376
376
  */
377
377
  dependencies?: TaskDependency[];
378
378
  /**
package/dist/index.js CHANGED
@@ -116,6 +116,7 @@ __export(index_exports, {
116
116
  normalizeHierarchyTasks: () => normalizeHierarchyTasks,
117
117
  normalizePredecessorDates: () => normalizePredecessorDates,
118
118
  normalizeTaskDates: () => normalizeTaskDates,
119
+ normalizeTaskDependencyLags: () => normalizeTaskDependencyLags,
119
120
  normalizeUTCDate: () => normalizeUTCDate,
120
121
  not: () => not,
121
122
  or: () => or,
@@ -586,17 +587,27 @@ function normalizePredecessorDates(predecessor, parseDateFn) {
586
587
  function getDependencyLag(dep) {
587
588
  return Number.isFinite(dep.lag) ? dep.lag : 0;
588
589
  }
590
+ function normalizeTaskDependencyLags(task) {
591
+ if (!task.dependencies?.length) {
592
+ return task;
593
+ }
594
+ let changed = false;
595
+ const dependencies = task.dependencies.map((dep) => {
596
+ const lag = getDependencyLag(dep);
597
+ const normalizedLag = dep.type === "FS" ? Math.max(0, lag) : lag;
598
+ if (normalizedLag === dep.lag) {
599
+ return dep;
600
+ }
601
+ changed = true;
602
+ return { ...dep, lag: normalizedLag };
603
+ });
604
+ return changed ? { ...task, dependencies } : task;
605
+ }
589
606
  function normalizeDependencyLag(linkType, lag, predecessorStart, predecessorEnd, businessDays = false, weekendPredicate) {
590
607
  if (linkType !== "FS") {
591
608
  return lag;
592
609
  }
593
- const predecessorDuration = getTaskDuration(
594
- predecessorStart,
595
- predecessorEnd,
596
- businessDays,
597
- weekendPredicate
598
- );
599
- return Math.max(-predecessorDuration, lag);
610
+ return Math.max(0, lag);
600
611
  }
601
612
  function computeLagFromDates(linkType, predStart, predEnd, succStart, succEnd, businessDays = false, weekendPredicate) {
602
613
  const pS = Date.UTC(predStart.getUTCFullYear(), predStart.getUTCMonth(), predStart.getUTCDate());
@@ -855,17 +866,11 @@ function clampTaskRangeForIncomingFS(task, proposedStart, proposedEnd, allTasks,
855
866
  continue;
856
867
  }
857
868
  const { predStart: predecessorStart, predEnd: predecessorEnd } = normalizePredecessorDates(predecessor, parseDateOnly);
858
- const predecessorDuration = getTaskDuration(
859
- predecessorStart,
860
- predecessorEnd,
861
- businessDays,
862
- weekendPredicate
863
- );
864
869
  const candidateMinStart = calculateSuccessorDate(
865
870
  predecessorStart,
866
871
  predecessorEnd,
867
872
  "FS",
868
- -predecessorDuration,
873
+ 0,
869
874
  businessDays,
870
875
  weekendPredicate
871
876
  );
@@ -976,11 +981,11 @@ function cascadeByLinks(movedTaskId, newStart, newEnd, allTasks, skipChildCascad
976
981
  const newChildEnd = new Date(origEnd.getTime() + parentEndDelta);
977
982
  visited.add(child.id);
978
983
  updatedDates.set(child.id, { start: newChildStart, end: newChildEnd });
979
- result.push({
984
+ result.push(normalizeTaskDependencyLags({
980
985
  ...child,
981
986
  startDate: newChildStart.toISOString().split("T")[0],
982
987
  endDate: newChildEnd.toISOString().split("T")[0]
983
- });
988
+ }));
984
989
  queue.push(child.id);
985
990
  }
986
991
  }
@@ -1016,11 +1021,11 @@ function cascadeByLinks(movedTaskId, newStart, newEnd, allTasks, skipChildCascad
1016
1021
  }
1017
1022
  visited.add(task.id);
1018
1023
  updatedDates.set(task.id, { start: newSuccStart, end: newSuccEnd });
1019
- result.push({
1024
+ result.push(normalizeTaskDependencyLags({
1020
1025
  ...task,
1021
1026
  startDate: newSuccStart.toISOString().split("T")[0],
1022
1027
  endDate: newSuccEnd.toISOString().split("T")[0]
1023
- });
1028
+ }));
1024
1029
  queue.push(task.id);
1025
1030
  break;
1026
1031
  }
@@ -1075,11 +1080,11 @@ function universalCascade(movedTask, newStart, newEnd, allTasks, businessDays =
1075
1080
  const updatedDates = /* @__PURE__ */ new Map();
1076
1081
  updatedDates.set(movedTask.id, { start: newStart, end: newEnd });
1077
1082
  const resultMap = /* @__PURE__ */ new Map();
1078
- resultMap.set(movedTask.id, {
1083
+ resultMap.set(movedTask.id, normalizeTaskDependencyLags({
1079
1084
  ...movedTask,
1080
1085
  startDate: newStart.toISOString().split("T")[0],
1081
1086
  endDate: newEnd.toISOString().split("T")[0]
1082
- });
1087
+ }));
1083
1088
  const queue = [[movedTask.id, "direct"]];
1084
1089
  const childShifted = /* @__PURE__ */ new Set();
1085
1090
  let iterations = 0;
@@ -1125,11 +1130,11 @@ function universalCascade(movedTask, newStart, newEnd, allTasks, businessDays =
1125
1130
  updatedDates.set(child.id, { start: childNewStart, end: childNewEnd });
1126
1131
  childShifted.add(child.id);
1127
1132
  queue.push([child.id, "child-delta"]);
1128
- resultMap.set(child.id, {
1133
+ resultMap.set(child.id, normalizeTaskDependencyLags({
1129
1134
  ...child,
1130
1135
  startDate: childNewStart.toISOString().split("T")[0],
1131
1136
  endDate: childNewEnd.toISOString().split("T")[0]
1132
- });
1137
+ }));
1133
1138
  }
1134
1139
  }
1135
1140
  const parentId = currentOriginal.parentId;
@@ -1147,11 +1152,11 @@ function universalCascade(movedTask, newStart, newEnd, allTasks, businessDays =
1147
1152
  if (!prev || prev.start.getTime() !== minStart.getTime() || prev.end.getTime() !== maxEnd.getTime()) {
1148
1153
  updatedDates.set(parentId, { start: minStart, end: maxEnd });
1149
1154
  queue.push([parentId, "parent-recalc"]);
1150
- resultMap.set(parentId, {
1155
+ resultMap.set(parentId, normalizeTaskDependencyLags({
1151
1156
  ...parent,
1152
1157
  startDate: minStart.toISOString().split("T")[0],
1153
1158
  endDate: maxEnd.toISOString().split("T")[0]
1154
- });
1159
+ }));
1155
1160
  }
1156
1161
  }
1157
1162
  }
@@ -1201,11 +1206,11 @@ function universalCascade(movedTask, newStart, newEnd, allTasks, businessDays =
1201
1206
  }
1202
1207
  updatedDates.set(task.id, { start: succNewStart, end: succNewEnd });
1203
1208
  queue.push([task.id, "dependency"]);
1204
- resultMap.set(task.id, {
1209
+ resultMap.set(task.id, normalizeTaskDependencyLags({
1205
1210
  ...task,
1206
1211
  startDate: succNewStart.toISOString().split("T")[0],
1207
1212
  endDate: succNewEnd.toISOString().split("T")[0]
1208
- });
1213
+ }));
1209
1214
  }
1210
1215
  }
1211
1216
  return Array.from(resultMap.values());
@@ -10149,6 +10154,7 @@ var nameContains = (substring, caseSensitive = false) => (task) => {
10149
10154
  normalizeHierarchyTasks,
10150
10155
  normalizePredecessorDates,
10151
10156
  normalizeTaskDates,
10157
+ normalizeTaskDependencyLags,
10152
10158
  normalizeUTCDate,
10153
10159
  not,
10154
10160
  or,