@outbuild-company/schedule-core 1.9.4 → 1.10.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/cdn/schedule-core.global.js +1 -1
- package/dist/cdn/schedule-core.global.js.map +1 -1
- package/dist/index.cjs +68 -33
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +68 -33
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -338,6 +338,7 @@ var FIELD_REGISTRY = {
|
|
|
338
338
|
},
|
|
339
339
|
expectedProgressBaseline: {
|
|
340
340
|
valueKind: "number",
|
|
341
|
+
equalityPrecision: 2,
|
|
341
342
|
extract: (activity) => activity.expectedProgressBaseline
|
|
342
343
|
},
|
|
343
344
|
expectedProgress: {
|
|
@@ -426,6 +427,9 @@ function toTargetDate(value) {
|
|
|
426
427
|
}
|
|
427
428
|
return new Date(Number.NaN);
|
|
428
429
|
}
|
|
430
|
+
function utcDayMs(date2) {
|
|
431
|
+
return Date.UTC(date2.getUTCFullYear(), date2.getUTCMonth(), date2.getUTCDate());
|
|
432
|
+
}
|
|
429
433
|
function matchString(value, target, operator) {
|
|
430
434
|
const isAbsent = value === null;
|
|
431
435
|
if (operator === "includes") {
|
|
@@ -438,12 +442,13 @@ function matchString(value, target, operator) {
|
|
|
438
442
|
if (operator === "isNot") return isAbsent || String(value) !== target;
|
|
439
443
|
return false;
|
|
440
444
|
}
|
|
441
|
-
function matchNumber(value, target, operator) {
|
|
445
|
+
function matchNumber(value, target, operator, equalityPrecision) {
|
|
442
446
|
if (value === null || typeof value !== "number") {
|
|
443
447
|
return operator === "notEquals";
|
|
444
448
|
}
|
|
445
|
-
|
|
446
|
-
if (operator === "
|
|
449
|
+
const equalityValue = equalityPrecision === void 0 ? value : Number(value.toFixed(equalityPrecision));
|
|
450
|
+
if (operator === "equals") return equalityValue === target;
|
|
451
|
+
if (operator === "notEquals") return equalityValue !== target;
|
|
447
452
|
if (operator === "greaterThan") return value > target;
|
|
448
453
|
if (operator === "lessThan") return value < target;
|
|
449
454
|
if (operator === "greaterOrEqual") return value >= target;
|
|
@@ -455,14 +460,16 @@ function matchNumberBetween(value, minimum, maximum) {
|
|
|
455
460
|
}
|
|
456
461
|
function matchDate(value, target, operator) {
|
|
457
462
|
if (!(value instanceof Date)) return false;
|
|
458
|
-
|
|
459
|
-
|
|
463
|
+
const valueDay = utcDayMs(value);
|
|
464
|
+
const targetDay = utcDayMs(target);
|
|
465
|
+
if (operator === "after") return valueDay > targetDay;
|
|
466
|
+
if (operator === "before") return valueDay < targetDay;
|
|
460
467
|
return false;
|
|
461
468
|
}
|
|
462
469
|
function matchDateBetween(value, minimum, maximum) {
|
|
463
470
|
if (!(value instanceof Date)) return false;
|
|
464
|
-
const
|
|
465
|
-
return
|
|
471
|
+
const day = utcDayMs(value);
|
|
472
|
+
return day >= utcDayMs(minimum) && day <= utcDayMs(maximum);
|
|
466
473
|
}
|
|
467
474
|
function matchIdArray(value, allowed, operator) {
|
|
468
475
|
const ids = Array.isArray(value) ? value : [];
|
|
@@ -507,7 +514,12 @@ function matchCriterion(activity, criterion, context) {
|
|
|
507
514
|
return matchString(value, String(criterion.value), operator);
|
|
508
515
|
}
|
|
509
516
|
if (descriptor.valueKind === "number") {
|
|
510
|
-
return matchNumber(
|
|
517
|
+
return matchNumber(
|
|
518
|
+
value,
|
|
519
|
+
Number(criterion.value),
|
|
520
|
+
operator,
|
|
521
|
+
descriptor.equalityPrecision
|
|
522
|
+
);
|
|
511
523
|
}
|
|
512
524
|
if (descriptor.valueKind === "date") {
|
|
513
525
|
return matchDate(value, toTargetDate(criterion.value), operator);
|
|
@@ -529,10 +541,10 @@ function matchesCriteria(activity, filter, context) {
|
|
|
529
541
|
);
|
|
530
542
|
}
|
|
531
543
|
function overlapsRange(activity, range) {
|
|
532
|
-
const taskStart = activity.startDate
|
|
533
|
-
const taskEnd = activity.endDate
|
|
534
|
-
const windowStart = range.start
|
|
535
|
-
const windowEnd = range.end
|
|
544
|
+
const taskStart = utcDayMs(activity.startDate);
|
|
545
|
+
const taskEnd = utcDayMs(activity.endDate);
|
|
546
|
+
const windowStart = utcDayMs(range.start);
|
|
547
|
+
const windowEnd = utcDayMs(range.end);
|
|
536
548
|
const fullyInside = taskStart >= windowStart && taskEnd <= windowEnd;
|
|
537
549
|
const startsInside = taskStart >= windowStart && taskStart <= windowEnd;
|
|
538
550
|
const windowStartsInside = windowStart >= taskStart && windowStart <= taskEnd;
|
|
@@ -1681,13 +1693,19 @@ function resolveExpansionAnchors(originalLink, adapter) {
|
|
|
1681
1693
|
userLag: originalLink.lag ?? 0,
|
|
1682
1694
|
sourceEndpointIsStart,
|
|
1683
1695
|
targetLag: targetEndpointIsFinish ? -endpointSpanHours(target, targetBounds, adapter) : 0,
|
|
1684
|
-
summarySourceId: originalLink.type === LINK_TYPE.START_TO_START && sourceBounds ? originalLink.source : void 0
|
|
1696
|
+
summarySourceId: originalLink.type === LINK_TYPE.START_TO_START && sourceBounds ? originalLink.source : void 0,
|
|
1697
|
+
finishAnchoredSummaryTargetId: targetEndpointIsFinish && targetBounds ? originalLink.target : void 0
|
|
1685
1698
|
};
|
|
1686
1699
|
}
|
|
1687
1700
|
function pushOffsetPreservingLinks(expanded, sourceIds, leafIds, originalLink, adapter, virtualIdCounter, linksByActivity) {
|
|
1688
1701
|
const anchors = resolveExpansionAnchors(originalLink, adapter);
|
|
1689
1702
|
const { source, sourceBounds, targetStart, userLag } = anchors;
|
|
1690
|
-
const {
|
|
1703
|
+
const {
|
|
1704
|
+
sourceEndpointIsStart,
|
|
1705
|
+
targetLag,
|
|
1706
|
+
summarySourceId,
|
|
1707
|
+
finishAnchoredSummaryTargetId
|
|
1708
|
+
} = anchors;
|
|
1691
1709
|
let counter = virtualIdCounter;
|
|
1692
1710
|
for (const srcId of sourceIds) {
|
|
1693
1711
|
const sourceLag = sourceEndpointIsStart ? sourceLagForLeaf(srcId, source, sourceBounds, adapter) : 0;
|
|
@@ -1710,7 +1728,7 @@ function pushOffsetPreservingLinks(expanded, sourceIds, leafIds, originalLink, a
|
|
|
1710
1728
|
targetLag,
|
|
1711
1729
|
userLag + offTarget,
|
|
1712
1730
|
summarySourceId,
|
|
1713
|
-
offTarget !== 0 && targetLag === 0 ? originalLink.target : void 0
|
|
1731
|
+
finishAnchoredSummaryTargetId ?? (offTarget !== 0 && targetLag === 0 ? originalLink.target : void 0)
|
|
1714
1732
|
)
|
|
1715
1733
|
);
|
|
1716
1734
|
counter += 1;
|
|
@@ -2158,7 +2176,7 @@ async function asapPass(orderedIds, links, adapter, options, isCurrent, plans) {
|
|
|
2158
2176
|
if (!maxStart || result.successorStart > maxStart) {
|
|
2159
2177
|
maxStart = result.successorStart;
|
|
2160
2178
|
drivingLinkId = String(link.id);
|
|
2161
|
-
drivingOffsetIsStale = link._summaryTargetId !== void 0 && !predecessorMovedThisRun;
|
|
2179
|
+
drivingOffsetIsStale = link._summaryTargetId !== void 0 && !predecessorMovedThisRun && (link._targetLag === 0 || options.preventSummaryTargetPullback === true);
|
|
2162
2180
|
}
|
|
2163
2181
|
}
|
|
2164
2182
|
const staleOffsetWouldPullBack = maxStart !== null && drivingOffsetIsStale && maxStart < activity.startDate;
|
|
@@ -10021,7 +10039,11 @@ async function runPostMutation(deps, args) {
|
|
|
10021
10039
|
if (passes.has(DERIVED_PASS.AUTOSCHEDULE)) {
|
|
10022
10040
|
await refreshMutatedParentBounds(deps.adapter, args);
|
|
10023
10041
|
}
|
|
10024
|
-
const schedule = passes.has(DERIVED_PASS.AUTOSCHEDULE) ? await runAutoschedule(
|
|
10042
|
+
const schedule = passes.has(DERIVED_PASS.AUTOSCHEDULE) ? await runAutoschedule(
|
|
10043
|
+
deps,
|
|
10044
|
+
args.autoscheduleFrom,
|
|
10045
|
+
args.preventSummaryTargetPullback
|
|
10046
|
+
) : emptySchedule();
|
|
10025
10047
|
await rollUpParentBounds(
|
|
10026
10048
|
deps.adapter,
|
|
10027
10049
|
args,
|
|
@@ -10092,8 +10114,11 @@ function collectFieldProgressInvalidations(adapter, beforeById, dirtySeeds, affe
|
|
|
10092
10114
|
}
|
|
10093
10115
|
}
|
|
10094
10116
|
}
|
|
10095
|
-
async function runAutoschedule(deps, autoscheduleFrom) {
|
|
10117
|
+
async function runAutoschedule(deps, autoscheduleFrom, preventSummaryTargetPullback = false) {
|
|
10096
10118
|
const options = autoscheduleFrom === "roots" ? {} : { triggerId: autoscheduleFrom };
|
|
10119
|
+
if (preventSummaryTargetPullback) {
|
|
10120
|
+
options.preventSummaryTargetPullback = true;
|
|
10121
|
+
}
|
|
10097
10122
|
const result = await deps.scheduler.schedule(options);
|
|
10098
10123
|
const outcome = captureScheduledRows(deps.adapter, result.updatedIds);
|
|
10099
10124
|
applyResults(deps.adapter, result);
|
|
@@ -11562,14 +11587,21 @@ async function createActivityCore(action, deps, opts = {}) {
|
|
|
11562
11587
|
recomputeUsedCostCascadeForActivity(newId, adapter);
|
|
11563
11588
|
recomputeCostCascadeForActivity(newId, adapter);
|
|
11564
11589
|
}
|
|
11565
|
-
|
|
11590
|
+
const correlativeShifts = recomputeCorrelatives(
|
|
11566
11591
|
adapter,
|
|
11567
11592
|
newId,
|
|
11568
|
-
beforeSnap,
|
|
11569
11593
|
initialTouched,
|
|
11570
11594
|
opts
|
|
11571
11595
|
);
|
|
11572
|
-
return {
|
|
11596
|
+
return {
|
|
11597
|
+
ok: true,
|
|
11598
|
+
newId,
|
|
11599
|
+
parent,
|
|
11600
|
+
newActivity,
|
|
11601
|
+
beforeSnap,
|
|
11602
|
+
initialTouched,
|
|
11603
|
+
correlativeShifts
|
|
11604
|
+
};
|
|
11573
11605
|
}
|
|
11574
11606
|
function validateCreateTarget(action, adapter) {
|
|
11575
11607
|
const isRoot = isRootParent(action.parentId);
|
|
@@ -11664,20 +11696,16 @@ function applyParentMutations(action, newId, parent, adapter, parentWasLeaf) {
|
|
|
11664
11696
|
);
|
|
11665
11697
|
}
|
|
11666
11698
|
}
|
|
11667
|
-
function
|
|
11668
|
-
if (opts.skipCorrelativeRecompute) return;
|
|
11669
|
-
const
|
|
11670
|
-
|
|
11671
|
-
foldCorrelativeShifts(
|
|
11672
|
-
adapter,
|
|
11673
|
-
correlativeShifts,
|
|
11674
|
-
/* @__PURE__ */ new Set([String(newId)]),
|
|
11675
|
-
beforeSnap,
|
|
11676
|
-
initialTouched
|
|
11699
|
+
function recomputeCorrelatives(adapter, newId, initialTouched, opts) {
|
|
11700
|
+
if (opts.skipCorrelativeRecompute) return [];
|
|
11701
|
+
const shifts = recomputeCorrelativeIds(adapter).filter(
|
|
11702
|
+
(shift) => shift.activityId !== String(newId)
|
|
11677
11703
|
);
|
|
11704
|
+
for (const shift of shifts) initialTouched.add(shift.activityId);
|
|
11705
|
+
return shifts;
|
|
11678
11706
|
}
|
|
11679
11707
|
async function buildCreateChangeSet(adapter, action, coreResult, scheduledIds, hoursPerDay) {
|
|
11680
|
-
const { newId, newActivity, beforeSnap, initialTouched } = coreResult;
|
|
11708
|
+
const { newId, newActivity, beforeSnap, initialTouched, correlativeShifts } = coreResult;
|
|
11681
11709
|
const trackingEvent = {
|
|
11682
11710
|
name: DISPATCH_TRACK_EVENT.ACTIVITY_CREATION,
|
|
11683
11711
|
properties: {
|
|
@@ -11694,6 +11722,7 @@ async function buildCreateChangeSet(adapter, action, coreResult, scheduledIds, h
|
|
|
11694
11722
|
beforeSnap,
|
|
11695
11723
|
touchedIds: initialTouched,
|
|
11696
11724
|
scheduledIds,
|
|
11725
|
+
correlativeShifts,
|
|
11697
11726
|
trackingEvents: [trackingEvent]});
|
|
11698
11727
|
}
|
|
11699
11728
|
async function dispatchActivityCreate(action, options, deps) {
|
|
@@ -11722,8 +11751,9 @@ async function dispatchActivityCreate(action, options, deps) {
|
|
|
11722
11751
|
},
|
|
11723
11752
|
{
|
|
11724
11753
|
action,
|
|
11725
|
-
autoscheduleFrom:
|
|
11754
|
+
autoscheduleFrom: newId,
|
|
11726
11755
|
recomputeParentsFrom: [newId],
|
|
11756
|
+
preventSummaryTargetPullback: true,
|
|
11727
11757
|
now: deps.now,
|
|
11728
11758
|
options
|
|
11729
11759
|
}
|
|
@@ -21410,6 +21440,11 @@ var ScheduleCore = class _ScheduleCore {
|
|
|
21410
21440
|
this.assertReady();
|
|
21411
21441
|
return this.coreRuntime.state.hiddenIds().map(String);
|
|
21412
21442
|
}
|
|
21443
|
+
getVisibleActivityIds() {
|
|
21444
|
+
this.assertReady();
|
|
21445
|
+
const hiddenIds = new Set(this.coreRuntime.state.hiddenIds().map(String));
|
|
21446
|
+
return this.coreRuntime.state.getAllIds().map(String).filter((activityId) => !hiddenIds.has(activityId));
|
|
21447
|
+
}
|
|
21413
21448
|
getActiveFilter() {
|
|
21414
21449
|
this.assertReady();
|
|
21415
21450
|
return cloneDomainValue(this.coreRuntime.state.getActiveFilter());
|