gantt-lib 0.60.2 → 0.62.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/core/scheduling/index.d.mts +1 -1
- package/dist/core/scheduling/index.d.ts +1 -1
- package/dist/core/scheduling/index.js +314 -60
- package/dist/core/scheduling/index.js.map +1 -1
- package/dist/core/scheduling/index.mjs +310 -58
- package/dist/core/scheduling/index.mjs.map +1 -1
- package/dist/{index-CliEEiHA.d.mts → index-DMA7NbWe.d.mts} +73 -21
- package/dist/{index-CliEEiHA.d.ts → index-DMA7NbWe.d.ts} +73 -21
- package/dist/index.d.mts +37 -3
- package/dist/index.d.ts +37 -3
- package/dist/index.js +384 -57
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +378 -57
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -825,62 +825,6 @@ function recalculateIncomingLags(task, newStartDate, newEndDate, allTasks, busin
|
|
|
825
825
|
return { ...dep, lag: nextLag };
|
|
826
826
|
});
|
|
827
827
|
}
|
|
828
|
-
function resolveDateRangeFromPixels(mode, left, width, monthStart, dayWidth, task, businessDays, weekendPredicate) {
|
|
829
|
-
const dayOffset = Math.round(left / dayWidth);
|
|
830
|
-
const rawStartDate = new Date(Date.UTC(
|
|
831
|
-
monthStart.getUTCFullYear(),
|
|
832
|
-
monthStart.getUTCMonth(),
|
|
833
|
-
monthStart.getUTCDate() + dayOffset
|
|
834
|
-
));
|
|
835
|
-
const rawEndOffset = dayOffset + Math.round(width / dayWidth) - 1;
|
|
836
|
-
const rawEndDate = new Date(Date.UTC(
|
|
837
|
-
monthStart.getUTCFullYear(),
|
|
838
|
-
monthStart.getUTCMonth(),
|
|
839
|
-
monthStart.getUTCDate() + rawEndOffset
|
|
840
|
-
));
|
|
841
|
-
if (!(businessDays && weekendPredicate)) {
|
|
842
|
-
return { start: rawStartDate, end: rawEndDate };
|
|
843
|
-
}
|
|
844
|
-
if (mode === "move") {
|
|
845
|
-
const originalStart2 = new Date(task.startDate);
|
|
846
|
-
const snapDirection2 = rawStartDate.getTime() >= originalStart2.getTime() ? 1 : -1;
|
|
847
|
-
return moveTaskRange(
|
|
848
|
-
task.startDate,
|
|
849
|
-
task.endDate,
|
|
850
|
-
rawStartDate,
|
|
851
|
-
true,
|
|
852
|
-
weekendPredicate,
|
|
853
|
-
snapDirection2
|
|
854
|
-
);
|
|
855
|
-
}
|
|
856
|
-
if (mode === "resize-right") {
|
|
857
|
-
const fixedStart = new Date(task.startDate);
|
|
858
|
-
const originalEnd = new Date(task.endDate);
|
|
859
|
-
const snapDirection2 = rawEndDate.getTime() >= originalEnd.getTime() ? 1 : -1;
|
|
860
|
-
const alignedEnd = alignToWorkingDay(rawEndDate, snapDirection2, weekendPredicate);
|
|
861
|
-
const duration2 = Math.max(1, getBusinessDaysCount(fixedStart, alignedEnd, weekendPredicate));
|
|
862
|
-
return buildTaskRangeFromStart(fixedStart, duration2, true, weekendPredicate);
|
|
863
|
-
}
|
|
864
|
-
const fixedEnd = new Date(task.endDate);
|
|
865
|
-
const originalStart = new Date(task.startDate);
|
|
866
|
-
const snapDirection = rawStartDate.getTime() >= originalStart.getTime() ? 1 : -1;
|
|
867
|
-
const alignedStart = alignToWorkingDay(rawStartDate, snapDirection, weekendPredicate);
|
|
868
|
-
const duration = Math.max(1, getBusinessDaysCount(alignedStart, fixedEnd, weekendPredicate));
|
|
869
|
-
return buildTaskRangeFromEnd(fixedEnd, duration, true, weekendPredicate);
|
|
870
|
-
}
|
|
871
|
-
function clampDateRangeForIncomingFS(task, range, allTasks, mode, businessDays, weekendPredicate) {
|
|
872
|
-
if (mode === "resize-right") {
|
|
873
|
-
return range;
|
|
874
|
-
}
|
|
875
|
-
return clampTaskRangeForIncomingFS(
|
|
876
|
-
task,
|
|
877
|
-
range.start,
|
|
878
|
-
range.end,
|
|
879
|
-
allTasks,
|
|
880
|
-
businessDays,
|
|
881
|
-
weekendPredicate
|
|
882
|
-
);
|
|
883
|
-
}
|
|
884
828
|
|
|
885
829
|
// src/core/scheduling/cascade.ts
|
|
886
830
|
function getSuccessorChain(draggedTaskId, allTasks, linkTypes = ["FS"]) {
|
|
@@ -1197,6 +1141,313 @@ function reflowTasksOnModeSwitch(sourceTasks, toBusinessDays, weekendPredicate)
|
|
|
1197
1141
|
return tasks;
|
|
1198
1142
|
}
|
|
1199
1143
|
|
|
1144
|
+
// src/core/scheduling/execute.ts
|
|
1145
|
+
init_dateMath();
|
|
1146
|
+
function toIsoDate(date) {
|
|
1147
|
+
return date.toISOString().split("T")[0];
|
|
1148
|
+
}
|
|
1149
|
+
function createChangedResult(snapshot, nextTasks) {
|
|
1150
|
+
const originalById = new Map(snapshot.map((task) => [task.id, task]));
|
|
1151
|
+
const changedTasks = nextTasks.filter((task) => JSON.stringify(originalById.get(task.id)) !== JSON.stringify(task));
|
|
1152
|
+
return {
|
|
1153
|
+
changedTasks,
|
|
1154
|
+
changedIds: changedTasks.map((task) => task.id)
|
|
1155
|
+
};
|
|
1156
|
+
}
|
|
1157
|
+
function moveTaskWithCascade(taskId, newStart, snapshot, options) {
|
|
1158
|
+
const task = snapshot.find((t) => t.id === taskId);
|
|
1159
|
+
if (!task) {
|
|
1160
|
+
return { changedTasks: [], changedIds: [] };
|
|
1161
|
+
}
|
|
1162
|
+
const businessDays = options?.businessDays ?? false;
|
|
1163
|
+
const weekendPredicate = options?.weekendPredicate;
|
|
1164
|
+
const newRange = moveTaskRange(
|
|
1165
|
+
task.startDate,
|
|
1166
|
+
task.endDate,
|
|
1167
|
+
newStart,
|
|
1168
|
+
businessDays,
|
|
1169
|
+
weekendPredicate
|
|
1170
|
+
);
|
|
1171
|
+
const updatedDependencies = recalculateIncomingLags(
|
|
1172
|
+
task,
|
|
1173
|
+
newRange.start,
|
|
1174
|
+
newRange.end,
|
|
1175
|
+
snapshot,
|
|
1176
|
+
businessDays,
|
|
1177
|
+
weekendPredicate
|
|
1178
|
+
);
|
|
1179
|
+
const movedTask = {
|
|
1180
|
+
...task,
|
|
1181
|
+
startDate: newRange.start.toISOString().split("T")[0],
|
|
1182
|
+
endDate: newRange.end.toISOString().split("T")[0],
|
|
1183
|
+
dependencies: updatedDependencies
|
|
1184
|
+
};
|
|
1185
|
+
if (options?.skipCascade) {
|
|
1186
|
+
return {
|
|
1187
|
+
changedTasks: [movedTask],
|
|
1188
|
+
changedIds: [movedTask.id]
|
|
1189
|
+
};
|
|
1190
|
+
}
|
|
1191
|
+
const cascadeResult = universalCascade(
|
|
1192
|
+
movedTask,
|
|
1193
|
+
newRange.start,
|
|
1194
|
+
newRange.end,
|
|
1195
|
+
snapshot,
|
|
1196
|
+
businessDays,
|
|
1197
|
+
weekendPredicate
|
|
1198
|
+
);
|
|
1199
|
+
const resultMap = /* @__PURE__ */ new Map();
|
|
1200
|
+
resultMap.set(movedTask.id, movedTask);
|
|
1201
|
+
for (const t of cascadeResult) {
|
|
1202
|
+
resultMap.set(t.id, t);
|
|
1203
|
+
}
|
|
1204
|
+
const changedTasks = Array.from(resultMap.values());
|
|
1205
|
+
return {
|
|
1206
|
+
changedTasks,
|
|
1207
|
+
changedIds: changedTasks.map((t) => t.id)
|
|
1208
|
+
};
|
|
1209
|
+
}
|
|
1210
|
+
function resizeTaskWithCascade(taskId, anchor, newDate, snapshot, options) {
|
|
1211
|
+
const task = snapshot.find((t) => t.id === taskId);
|
|
1212
|
+
if (!task) {
|
|
1213
|
+
return { changedTasks: [], changedIds: [] };
|
|
1214
|
+
}
|
|
1215
|
+
const businessDays = options?.businessDays ?? false;
|
|
1216
|
+
const weekendPredicate = options?.weekendPredicate;
|
|
1217
|
+
const originalStart = parseDateOnly(task.startDate);
|
|
1218
|
+
const originalEnd = parseDateOnly(task.endDate);
|
|
1219
|
+
let newRange;
|
|
1220
|
+
if (anchor === "end") {
|
|
1221
|
+
newRange = { start: originalStart, end: newDate };
|
|
1222
|
+
} else {
|
|
1223
|
+
newRange = { start: newDate, end: originalEnd };
|
|
1224
|
+
}
|
|
1225
|
+
const updatedDependencies = recalculateIncomingLags(
|
|
1226
|
+
task,
|
|
1227
|
+
newRange.start,
|
|
1228
|
+
newRange.end,
|
|
1229
|
+
snapshot,
|
|
1230
|
+
businessDays,
|
|
1231
|
+
weekendPredicate
|
|
1232
|
+
);
|
|
1233
|
+
const resizedTask = {
|
|
1234
|
+
...task,
|
|
1235
|
+
startDate: newRange.start.toISOString().split("T")[0],
|
|
1236
|
+
endDate: newRange.end.toISOString().split("T")[0],
|
|
1237
|
+
dependencies: updatedDependencies
|
|
1238
|
+
};
|
|
1239
|
+
if (options?.skipCascade) {
|
|
1240
|
+
return {
|
|
1241
|
+
changedTasks: [resizedTask],
|
|
1242
|
+
changedIds: [resizedTask.id]
|
|
1243
|
+
};
|
|
1244
|
+
}
|
|
1245
|
+
const cascadeResult = universalCascade(
|
|
1246
|
+
resizedTask,
|
|
1247
|
+
newRange.start,
|
|
1248
|
+
newRange.end,
|
|
1249
|
+
snapshot,
|
|
1250
|
+
businessDays,
|
|
1251
|
+
weekendPredicate
|
|
1252
|
+
);
|
|
1253
|
+
const resultMap = /* @__PURE__ */ new Map();
|
|
1254
|
+
resultMap.set(resizedTask.id, resizedTask);
|
|
1255
|
+
for (const t of cascadeResult) {
|
|
1256
|
+
resultMap.set(t.id, t);
|
|
1257
|
+
}
|
|
1258
|
+
const changedTasks = Array.from(resultMap.values());
|
|
1259
|
+
return {
|
|
1260
|
+
changedTasks,
|
|
1261
|
+
changedIds: changedTasks.map((t) => t.id)
|
|
1262
|
+
};
|
|
1263
|
+
}
|
|
1264
|
+
function recalculateTaskFromDependencies(taskId, snapshot, options) {
|
|
1265
|
+
const task = snapshot.find((t) => t.id === taskId);
|
|
1266
|
+
if (!task) {
|
|
1267
|
+
return { changedTasks: [], changedIds: [] };
|
|
1268
|
+
}
|
|
1269
|
+
const businessDays = options?.businessDays ?? false;
|
|
1270
|
+
const weekendPredicate = options?.weekendPredicate;
|
|
1271
|
+
if (!task.dependencies || task.dependencies.length === 0) {
|
|
1272
|
+
return {
|
|
1273
|
+
changedTasks: [task],
|
|
1274
|
+
changedIds: [task.id]
|
|
1275
|
+
};
|
|
1276
|
+
}
|
|
1277
|
+
let constrainedStart = null;
|
|
1278
|
+
let constrainedEnd = null;
|
|
1279
|
+
for (const dep of task.dependencies) {
|
|
1280
|
+
const predecessor = snapshot.find((t) => t.id === dep.taskId);
|
|
1281
|
+
if (!predecessor) continue;
|
|
1282
|
+
const predStart = parseDateOnly(predecessor.startDate);
|
|
1283
|
+
const predEnd = parseDateOnly(predecessor.endDate);
|
|
1284
|
+
const constraintDate = calculateSuccessorDate(
|
|
1285
|
+
predStart,
|
|
1286
|
+
predEnd,
|
|
1287
|
+
dep.type,
|
|
1288
|
+
getDependencyLag(dep),
|
|
1289
|
+
businessDays,
|
|
1290
|
+
weekendPredicate
|
|
1291
|
+
);
|
|
1292
|
+
const duration = getTaskDuration(
|
|
1293
|
+
parseDateOnly(task.startDate),
|
|
1294
|
+
parseDateOnly(task.endDate),
|
|
1295
|
+
businessDays,
|
|
1296
|
+
weekendPredicate
|
|
1297
|
+
);
|
|
1298
|
+
let range;
|
|
1299
|
+
if (dep.type === "FS" || dep.type === "SS") {
|
|
1300
|
+
range = buildTaskRangeFromStart(constraintDate, duration, businessDays, weekendPredicate);
|
|
1301
|
+
} else {
|
|
1302
|
+
range = buildTaskRangeFromEnd(constraintDate, duration, businessDays, weekendPredicate);
|
|
1303
|
+
}
|
|
1304
|
+
if (!constrainedStart || range.start.getTime() > constrainedStart.getTime()) {
|
|
1305
|
+
constrainedStart = range.start;
|
|
1306
|
+
constrainedEnd = range.end;
|
|
1307
|
+
}
|
|
1308
|
+
}
|
|
1309
|
+
if (!constrainedStart || !constrainedEnd) {
|
|
1310
|
+
return {
|
|
1311
|
+
changedTasks: [task],
|
|
1312
|
+
changedIds: [task.id]
|
|
1313
|
+
};
|
|
1314
|
+
}
|
|
1315
|
+
const updatedDependencies = recalculateIncomingLags(
|
|
1316
|
+
task,
|
|
1317
|
+
constrainedStart,
|
|
1318
|
+
constrainedEnd,
|
|
1319
|
+
snapshot,
|
|
1320
|
+
businessDays,
|
|
1321
|
+
weekendPredicate
|
|
1322
|
+
);
|
|
1323
|
+
const recalculatedTask = {
|
|
1324
|
+
...task,
|
|
1325
|
+
startDate: constrainedStart.toISOString().split("T")[0],
|
|
1326
|
+
endDate: constrainedEnd.toISOString().split("T")[0],
|
|
1327
|
+
dependencies: updatedDependencies
|
|
1328
|
+
};
|
|
1329
|
+
if (options?.skipCascade) {
|
|
1330
|
+
return {
|
|
1331
|
+
changedTasks: [recalculatedTask],
|
|
1332
|
+
changedIds: [recalculatedTask.id]
|
|
1333
|
+
};
|
|
1334
|
+
}
|
|
1335
|
+
const cascadeResult = universalCascade(
|
|
1336
|
+
recalculatedTask,
|
|
1337
|
+
constrainedStart,
|
|
1338
|
+
constrainedEnd,
|
|
1339
|
+
snapshot,
|
|
1340
|
+
businessDays,
|
|
1341
|
+
weekendPredicate
|
|
1342
|
+
);
|
|
1343
|
+
const resultMap = /* @__PURE__ */ new Map();
|
|
1344
|
+
resultMap.set(recalculatedTask.id, recalculatedTask);
|
|
1345
|
+
for (const t of cascadeResult) {
|
|
1346
|
+
resultMap.set(t.id, t);
|
|
1347
|
+
}
|
|
1348
|
+
const changedTasks = Array.from(resultMap.values());
|
|
1349
|
+
return {
|
|
1350
|
+
changedTasks,
|
|
1351
|
+
changedIds: changedTasks.map((t) => t.id)
|
|
1352
|
+
};
|
|
1353
|
+
}
|
|
1354
|
+
function recalculateProjectSchedule(snapshot, options) {
|
|
1355
|
+
const businessDays = options?.businessDays ?? false;
|
|
1356
|
+
const weekendPredicate = options?.weekendPredicate;
|
|
1357
|
+
const workingMap = new Map(snapshot.map((task) => [task.id, { ...task }]));
|
|
1358
|
+
const indegree = /* @__PURE__ */ new Map();
|
|
1359
|
+
const successorIdsByTask = /* @__PURE__ */ new Map();
|
|
1360
|
+
for (const task of snapshot) {
|
|
1361
|
+
indegree.set(task.id, 0);
|
|
1362
|
+
successorIdsByTask.set(task.id, []);
|
|
1363
|
+
}
|
|
1364
|
+
for (const task of snapshot) {
|
|
1365
|
+
for (const dep of task.dependencies ?? []) {
|
|
1366
|
+
if (!workingMap.has(dep.taskId)) {
|
|
1367
|
+
continue;
|
|
1368
|
+
}
|
|
1369
|
+
indegree.set(task.id, (indegree.get(task.id) ?? 0) + 1);
|
|
1370
|
+
successorIdsByTask.get(dep.taskId)?.push(task.id);
|
|
1371
|
+
}
|
|
1372
|
+
}
|
|
1373
|
+
const queue = snapshot.filter((task) => (indegree.get(task.id) ?? 0) === 0).map((task) => task.id);
|
|
1374
|
+
while (queue.length > 0) {
|
|
1375
|
+
const currentId = queue.shift();
|
|
1376
|
+
for (const successorId of successorIdsByTask.get(currentId) ?? []) {
|
|
1377
|
+
const nextIndegree = (indegree.get(successorId) ?? 0) - 1;
|
|
1378
|
+
indegree.set(successorId, nextIndegree);
|
|
1379
|
+
if (nextIndegree !== 0) {
|
|
1380
|
+
continue;
|
|
1381
|
+
}
|
|
1382
|
+
const currentTask = workingMap.get(successorId);
|
|
1383
|
+
if (!currentTask || currentTask.locked || !currentTask.dependencies?.length) {
|
|
1384
|
+
queue.push(successorId);
|
|
1385
|
+
continue;
|
|
1386
|
+
}
|
|
1387
|
+
const duration = getTaskDuration(
|
|
1388
|
+
parseDateOnly(currentTask.startDate),
|
|
1389
|
+
parseDateOnly(currentTask.endDate),
|
|
1390
|
+
businessDays,
|
|
1391
|
+
weekendPredicate
|
|
1392
|
+
);
|
|
1393
|
+
let constrainedRange = null;
|
|
1394
|
+
for (const dep of currentTask.dependencies) {
|
|
1395
|
+
const predecessor = workingMap.get(dep.taskId);
|
|
1396
|
+
if (!predecessor) {
|
|
1397
|
+
continue;
|
|
1398
|
+
}
|
|
1399
|
+
const predecessorStart = parseDateOnly(predecessor.startDate);
|
|
1400
|
+
const predecessorEnd = parseDateOnly(predecessor.endDate);
|
|
1401
|
+
const constraintDate = calculateSuccessorDate(
|
|
1402
|
+
predecessorStart,
|
|
1403
|
+
predecessorEnd,
|
|
1404
|
+
dep.type,
|
|
1405
|
+
getDependencyLag(dep),
|
|
1406
|
+
businessDays,
|
|
1407
|
+
weekendPredicate
|
|
1408
|
+
);
|
|
1409
|
+
const candidateRange = dep.type === "FS" || dep.type === "SS" ? buildTaskRangeFromStart(constraintDate, duration, businessDays, weekendPredicate) : buildTaskRangeFromEnd(constraintDate, duration, businessDays, weekendPredicate);
|
|
1410
|
+
if (!constrainedRange || candidateRange.start.getTime() > constrainedRange.start.getTime() || candidateRange.start.getTime() === constrainedRange.start.getTime() && candidateRange.end.getTime() > constrainedRange.end.getTime()) {
|
|
1411
|
+
constrainedRange = candidateRange;
|
|
1412
|
+
}
|
|
1413
|
+
}
|
|
1414
|
+
if (!constrainedRange) {
|
|
1415
|
+
queue.push(successorId);
|
|
1416
|
+
continue;
|
|
1417
|
+
}
|
|
1418
|
+
workingMap.set(successorId, {
|
|
1419
|
+
...currentTask,
|
|
1420
|
+
startDate: toIsoDate(constrainedRange.start),
|
|
1421
|
+
endDate: toIsoDate(constrainedRange.end)
|
|
1422
|
+
});
|
|
1423
|
+
queue.push(successorId);
|
|
1424
|
+
}
|
|
1425
|
+
}
|
|
1426
|
+
const parentsByDepth = snapshot.filter((task) => isTaskParent(task.id, snapshot)).map((task) => {
|
|
1427
|
+
let depth = 0;
|
|
1428
|
+
let current = task.parentId ? workingMap.get(task.parentId) : void 0;
|
|
1429
|
+
while (current) {
|
|
1430
|
+
depth++;
|
|
1431
|
+
current = current.parentId ? workingMap.get(current.parentId) : void 0;
|
|
1432
|
+
}
|
|
1433
|
+
return { taskId: task.id, depth };
|
|
1434
|
+
}).sort((left, right) => right.depth - left.depth);
|
|
1435
|
+
const workingTasks = () => Array.from(workingMap.values());
|
|
1436
|
+
for (const { taskId } of parentsByDepth) {
|
|
1437
|
+
const parent = workingMap.get(taskId);
|
|
1438
|
+
if (!parent || parent.locked) {
|
|
1439
|
+
continue;
|
|
1440
|
+
}
|
|
1441
|
+
const { startDate, endDate } = computeParentDates(taskId, workingTasks());
|
|
1442
|
+
workingMap.set(taskId, {
|
|
1443
|
+
...parent,
|
|
1444
|
+
startDate: toIsoDate(startDate),
|
|
1445
|
+
endDate: toIsoDate(endDate)
|
|
1446
|
+
});
|
|
1447
|
+
}
|
|
1448
|
+
return createChangedResult(snapshot, Array.from(workingMap.values()));
|
|
1449
|
+
}
|
|
1450
|
+
|
|
1200
1451
|
// src/core/scheduling/validation.ts
|
|
1201
1452
|
function buildAdjacencyList(tasks) {
|
|
1202
1453
|
const graph = /* @__PURE__ */ new Map();
|
|
@@ -1777,6 +2028,67 @@ var isTaskExpired = (task, referenceDate = /* @__PURE__ */ new Date()) => {
|
|
|
1777
2028
|
|
|
1778
2029
|
// src/hooks/useTaskDrag.ts
|
|
1779
2030
|
import { useEffect, useRef, useState, useCallback } from "react";
|
|
2031
|
+
|
|
2032
|
+
// src/adapters/scheduling/drag.ts
|
|
2033
|
+
init_dateMath();
|
|
2034
|
+
function resolveDateRangeFromPixels(mode, left, width, monthStart, dayWidth, task, businessDays, weekendPredicate) {
|
|
2035
|
+
const dayOffset = Math.round(left / dayWidth);
|
|
2036
|
+
const rawStartDate = new Date(Date.UTC(
|
|
2037
|
+
monthStart.getUTCFullYear(),
|
|
2038
|
+
monthStart.getUTCMonth(),
|
|
2039
|
+
monthStart.getUTCDate() + dayOffset
|
|
2040
|
+
));
|
|
2041
|
+
const rawEndOffset = dayOffset + Math.round(width / dayWidth) - 1;
|
|
2042
|
+
const rawEndDate = new Date(Date.UTC(
|
|
2043
|
+
monthStart.getUTCFullYear(),
|
|
2044
|
+
monthStart.getUTCMonth(),
|
|
2045
|
+
monthStart.getUTCDate() + rawEndOffset
|
|
2046
|
+
));
|
|
2047
|
+
if (!(businessDays && weekendPredicate)) {
|
|
2048
|
+
return { start: rawStartDate, end: rawEndDate };
|
|
2049
|
+
}
|
|
2050
|
+
if (mode === "move") {
|
|
2051
|
+
const originalStart2 = new Date(task.startDate);
|
|
2052
|
+
const snapDirection2 = rawStartDate.getTime() >= originalStart2.getTime() ? 1 : -1;
|
|
2053
|
+
return moveTaskRange(
|
|
2054
|
+
task.startDate,
|
|
2055
|
+
task.endDate,
|
|
2056
|
+
rawStartDate,
|
|
2057
|
+
true,
|
|
2058
|
+
weekendPredicate,
|
|
2059
|
+
snapDirection2
|
|
2060
|
+
);
|
|
2061
|
+
}
|
|
2062
|
+
if (mode === "resize-right") {
|
|
2063
|
+
const fixedStart = new Date(task.startDate);
|
|
2064
|
+
const originalEnd = new Date(task.endDate);
|
|
2065
|
+
const snapDirection2 = rawEndDate.getTime() >= originalEnd.getTime() ? 1 : -1;
|
|
2066
|
+
const alignedEnd = alignToWorkingDay(rawEndDate, snapDirection2, weekendPredicate);
|
|
2067
|
+
const duration2 = Math.max(1, getBusinessDaysCount(fixedStart, alignedEnd, weekendPredicate));
|
|
2068
|
+
return buildTaskRangeFromStart(fixedStart, duration2, true, weekendPredicate);
|
|
2069
|
+
}
|
|
2070
|
+
const fixedEnd = new Date(task.endDate);
|
|
2071
|
+
const originalStart = new Date(task.startDate);
|
|
2072
|
+
const snapDirection = rawStartDate.getTime() >= originalStart.getTime() ? 1 : -1;
|
|
2073
|
+
const alignedStart = alignToWorkingDay(rawStartDate, snapDirection, weekendPredicate);
|
|
2074
|
+
const duration = Math.max(1, getBusinessDaysCount(alignedStart, fixedEnd, weekendPredicate));
|
|
2075
|
+
return buildTaskRangeFromEnd(fixedEnd, duration, true, weekendPredicate);
|
|
2076
|
+
}
|
|
2077
|
+
function clampDateRangeForIncomingFS(task, range, allTasks, mode, businessDays, weekendPredicate) {
|
|
2078
|
+
if (mode === "resize-right") {
|
|
2079
|
+
return range;
|
|
2080
|
+
}
|
|
2081
|
+
return clampTaskRangeForIncomingFS(
|
|
2082
|
+
task,
|
|
2083
|
+
range.start,
|
|
2084
|
+
range.end,
|
|
2085
|
+
allTasks,
|
|
2086
|
+
businessDays,
|
|
2087
|
+
weekendPredicate
|
|
2088
|
+
);
|
|
2089
|
+
}
|
|
2090
|
+
|
|
2091
|
+
// src/hooks/useTaskDrag.ts
|
|
1780
2092
|
var globalActiveDrag = null;
|
|
1781
2093
|
var globalRafId = null;
|
|
1782
2094
|
function getDayOffsetFromMonthStart(date, monthStart) {
|
|
@@ -6718,8 +7030,11 @@ function GanttChartInner(props, ref) {
|
|
|
6718
7030
|
});
|
|
6719
7031
|
}
|
|
6720
7032
|
const normalized = normalizeHierarchyTasks(updated);
|
|
7033
|
+
if (onReorder) {
|
|
7034
|
+
onReorder(normalized, movedTaskId, inferredParentId);
|
|
7035
|
+
return;
|
|
7036
|
+
}
|
|
6721
7037
|
onTasksChange?.(normalized);
|
|
6722
|
-
onReorder?.(normalized, movedTaskId, inferredParentId);
|
|
6723
7038
|
}, [onTasksChange, onReorder]);
|
|
6724
7039
|
const dependencyOverrides = useMemo9(() => {
|
|
6725
7040
|
const map = new Map(cascadeOverrides);
|
|
@@ -7133,6 +7448,7 @@ export {
|
|
|
7133
7448
|
calculateWeekGridLines,
|
|
7134
7449
|
calculateWeekendBlocks,
|
|
7135
7450
|
cascadeByLinks,
|
|
7451
|
+
clampDateRangeForIncomingFS,
|
|
7136
7452
|
clampTaskRangeForIncomingFS,
|
|
7137
7453
|
computeLagFromDates,
|
|
7138
7454
|
computeParentDates,
|
|
@@ -7172,6 +7488,7 @@ export {
|
|
|
7172
7488
|
isToday,
|
|
7173
7489
|
isWeekend,
|
|
7174
7490
|
moveTaskRange,
|
|
7491
|
+
moveTaskWithCascade,
|
|
7175
7492
|
nameContains,
|
|
7176
7493
|
normalizeDependencyLag,
|
|
7177
7494
|
normalizeHierarchyTasks,
|
|
@@ -7184,8 +7501,12 @@ export {
|
|
|
7184
7501
|
pixelsToDate,
|
|
7185
7502
|
progressInRange,
|
|
7186
7503
|
recalculateIncomingLags,
|
|
7504
|
+
recalculateProjectSchedule,
|
|
7505
|
+
recalculateTaskFromDependencies,
|
|
7187
7506
|
reflowTasksOnModeSwitch,
|
|
7188
7507
|
removeDependenciesBetweenTasks,
|
|
7508
|
+
resizeTaskWithCascade,
|
|
7509
|
+
resolveDateRangeFromPixels,
|
|
7189
7510
|
shiftBusinessDayOffset,
|
|
7190
7511
|
subtractBusinessDays2 as subtractBusinessDays,
|
|
7191
7512
|
universalCascade,
|