@outbuild-company/schedule-core 1.36.0 → 1.38.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.cjs CHANGED
@@ -8225,25 +8225,39 @@ function getVisibleBaseline(activity) {
8225
8225
  return points.find((point) => point.isVisibleVersion) ?? null;
8226
8226
  }
8227
8227
 
8228
- // src/columns/baseline-variance/compute.ts
8228
+ // src/columns/baseline-variance/baseline-variance-days.ts
8229
8229
  var VARIANCE_DECIMAL_SCALE = 100;
8230
8230
  var roundToVariancePrecision = (days) => Math.round(days * VARIANCE_DECIMAL_SCALE) / VARIANCE_DECIMAL_SCALE;
8231
- function varianceDaysForBaselineEnd(activity, baselineEnd, calendars, hoursPerDay) {
8232
- if (hoursPerDay <= 0) return null;
8233
- const activityEnd = activity.endDate;
8234
- if (!baselineEnd || !activityEnd) return null;
8235
- const finishesLate = activityEnd.getTime() > baselineEnd.getTime();
8236
- const finishesEarly = baselineEnd.getTime() > activityEnd.getTime();
8231
+ function baselineVarianceDays(input) {
8232
+ const { endDate, baselineEnd, calendar, hoursPerDay } = input;
8233
+ const hasUsableHoursPerDay = Number.isFinite(hoursPerDay) && hoursPerDay > 0;
8234
+ if (!hasUsableHoursPerDay) return null;
8235
+ if (!baselineEnd || !endDate) return null;
8236
+ const hasValidDates = Number.isFinite(endDate.getTime()) && Number.isFinite(baselineEnd.getTime());
8237
+ if (!hasValidDates) return null;
8238
+ const finishesLate = endDate.getTime() > baselineEnd.getTime();
8239
+ const finishesEarly = baselineEnd.getTime() > endDate.getTime();
8237
8240
  if (!finishesLate && !finishesEarly) return 0;
8238
- const durationHours = calendars.calculateDuration({
8239
- startDate: finishesLate ? baselineEnd : activityEnd,
8240
- endDate: finishesLate ? activityEnd : baselineEnd,
8241
- task: activity
8242
- });
8241
+ const durationHours = calendar.calculateDuration(
8242
+ finishesLate ? baselineEnd : endDate,
8243
+ finishesLate ? endDate : baselineEnd
8244
+ );
8243
8245
  const magnitude = roundToVariancePrecision(durationHours / hoursPerDay);
8244
8246
  if (magnitude === 0) return 0;
8245
8247
  return finishesLate ? magnitude : -magnitude;
8246
8248
  }
8249
+
8250
+ // src/columns/baseline-variance/compute.ts
8251
+ function varianceDaysForBaselineEnd(activity, baselineEnd, calendars, hoursPerDay) {
8252
+ return baselineVarianceDays({
8253
+ endDate: activity.endDate,
8254
+ baselineEnd,
8255
+ calendar: {
8256
+ calculateDuration: (startDate, endDate) => calendars.calculateDuration({ startDate, endDate, task: activity })
8257
+ },
8258
+ hoursPerDay
8259
+ });
8260
+ }
8247
8261
  function computeBaselineVarianceDays(activity, calendars, hoursPerDay) {
8248
8262
  return varianceDaysForBaselineEnd(
8249
8263
  activity,
@@ -14124,6 +14138,14 @@ var PASTE_PLACEMENT = {
14124
14138
  END: "end"
14125
14139
  };
14126
14140
 
14141
+ // src/dispatch/confirmations.ts
14142
+ var LOOKAHEAD_CONFIRMATION_KIND = {
14143
+ HAS_LOOKAHEAD_TASKS: "has_lookahead_tasks"
14144
+ };
14145
+ var CUSTOM_ID_CONFIRMATION_KIND = {
14146
+ PASTE_CONFLICTS: "custom_id_paste_conflicts"
14147
+ };
14148
+
14127
14149
  // src/activity-copy-paste/paste.ts
14128
14150
  function childIdsInCorrelativeOrder(parentId, adapter) {
14129
14151
  return collectChildrenSnapshots(parentId, adapter).sort(compareActivitiesInVisualOrder).map((activity) => activity.id);
@@ -14179,6 +14201,59 @@ var invariantFailure = () => ({
14179
14201
  ok: false,
14180
14202
  reason: REJECTION_REASON.ACTIVITY_PASTE_INVARIANT_FAILED
14181
14203
  });
14204
+ function customIdHolders(adapter) {
14205
+ const holders = /* @__PURE__ */ new Map();
14206
+ adapter.forEachActivity((activity, activityId) => {
14207
+ if (activity.customId !== null) {
14208
+ holders.set(activity.customId, String(activityId));
14209
+ }
14210
+ });
14211
+ return holders;
14212
+ }
14213
+ function conflictingCustomIds(clipboard, deps) {
14214
+ const holders = customIdHolders(deps.adapter);
14215
+ const copiedCustomIds = /* @__PURE__ */ new Set();
14216
+ const conflicts = /* @__PURE__ */ new Set();
14217
+ for (const copied of clipboard.activities) {
14218
+ const customId = copied.overrides.customId;
14219
+ if (typeof customId !== "string" || customId.length === 0) continue;
14220
+ const isHeldByAnotherActivity = deps.customIdTracker.isCustomIdInUse(customId) && holders.get(customId) !== String(copied.originalId);
14221
+ if (isHeldByAnotherActivity || copiedCustomIds.has(customId)) {
14222
+ conflicts.add(customId);
14223
+ }
14224
+ copiedCustomIds.add(customId);
14225
+ }
14226
+ return [...conflicts];
14227
+ }
14228
+ function reserveFreeCopiedCustomIds(clipboard, deps) {
14229
+ const reserved = /* @__PURE__ */ new Set();
14230
+ for (const copied of clipboard.activities) {
14231
+ const customId = copied.overrides.customId;
14232
+ const isFreeCopiedCustomId = typeof customId === "string" && customId.length > 0 && !deps.customIdTracker.isCustomIdInUse(customId);
14233
+ if (!isFreeCopiedCustomId) continue;
14234
+ deps.customIdTracker.registerCustomId(customId);
14235
+ reserved.add(customId);
14236
+ }
14237
+ return reserved;
14238
+ }
14239
+ function releaseReservedCustomId(customId, reserved, deps) {
14240
+ if (typeof customId !== "string" || !reserved.has(customId)) return;
14241
+ deps.customIdTracker.releaseCustomId(customId);
14242
+ reserved.delete(customId);
14243
+ }
14244
+ function customIdConflictRejection(clipboard, options, deps) {
14245
+ if (options.regenerateConflictingCustomIds === true) return null;
14246
+ const customIds = conflictingCustomIds(clipboard, deps);
14247
+ if (customIds.length === 0) return null;
14248
+ return {
14249
+ ok: false,
14250
+ reason: REJECTION_REASON.CONFIRMATION_REQUIRED,
14251
+ confirmation: {
14252
+ kind: CUSTOM_ID_CONFIRMATION_KIND.PASTE_CONFLICTS,
14253
+ customIds
14254
+ }
14255
+ };
14256
+ }
14182
14257
  async function dispatchActivityPasteCopied(action, options, deps) {
14183
14258
  const clipboard = deps.activityClipboard.value;
14184
14259
  if (clipboard === null) {
@@ -14186,6 +14261,8 @@ async function dispatchActivityPasteCopied(action, options, deps) {
14186
14261
  }
14187
14262
  const destination = resolvePasteDestination(action.destination, deps.adapter);
14188
14263
  if (!destination.ok) return destination;
14264
+ const conflictRejection = customIdConflictRejection(clipboard, options, deps);
14265
+ if (conflictRejection !== null) return conflictRejection;
14189
14266
  const createOptions = createOptionsFor(action.destination, destination);
14190
14267
  const beforeSnapshot = await snapshotActivities(
14191
14268
  deps.adapter,
@@ -14195,7 +14272,9 @@ async function dispatchActivityPasteCopied(action, options, deps) {
14195
14272
  const originalToNew = /* @__PURE__ */ new Map();
14196
14273
  const createdIds = [];
14197
14274
  let previousRootId;
14275
+ const reservedCustomIds = reserveFreeCopiedCustomIds(clipboard, deps);
14198
14276
  for (const copied of clipboard.activities) {
14277
+ releaseReservedCustomId(copied.overrides.customId, reservedCustomIds, deps);
14199
14278
  const mappedParent = originalToNew.get(copied.originalParentId);
14200
14279
  const afterSiblingId = mappedParent === void 0 ? previousRootId ?? destination.afterSiblingId : void 0;
14201
14280
  const beforeSiblingId = mappedParent === void 0 && afterSiblingId === void 0 ? destination.beforeSiblingId : void 0;
@@ -14288,11 +14367,6 @@ async function dispatchActivityPasteCopied(action, options, deps) {
14288
14367
  };
14289
14368
  }
14290
14369
 
14291
- // src/dispatch/confirmations.ts
14292
- var LOOKAHEAD_CONFIRMATION_KIND = {
14293
- HAS_LOOKAHEAD_TASKS: "has_lookahead_tasks"
14294
- };
14295
-
14296
14370
  // src/dispatch/shared/hierarchy-cycle-guard.ts
14297
14371
  function reparentClosesEffectiveCycle(adapter, reparented) {
14298
14372
  return !validateReparenting(adapter, { reparented }).ok;
@@ -21032,7 +21106,7 @@ var ACTIVITY_COPY_FIELDS = [
21032
21106
 
21033
21107
  // src/activity-copy-paste/copy.ts
21034
21108
  function copyOverrides(activity) {
21035
- const overrides = {};
21109
+ const overrides = { customId: activity.customId };
21036
21110
  for (const field of ACTIVITY_COPY_FIELDS) {
21037
21111
  Object.assign(overrides, { [field]: cloneDomainValue(activity[field]) });
21038
21112
  }
@@ -38132,6 +38206,7 @@ exports.CONSTRAINT_TYPE = CONSTRAINT_TYPE;
38132
38206
  exports.CONSTRAINT_TYPE_TO_LABEL = CONSTRAINT_TYPE_TO_LABEL;
38133
38207
  exports.CONSTRAINT_WARNING_KIND = CONSTRAINT_WARNING_KIND;
38134
38208
  exports.CREATION_KIND = CREATION_KIND;
38209
+ exports.CUSTOM_ID_CONFIRMATION_KIND = CUSTOM_ID_CONFIRMATION_KIND;
38135
38210
  exports.DATA_DATE_PROPERTY_CONTRACT = P6_PROPERTY_CONTRACT;
38136
38211
  exports.DATE_GESTURE_KIND = DATE_GESTURE_KIND;
38137
38212
  exports.DEFAULT_HOURS_PER_DAY = DEFAULT_HOURS_PER_DAY;
@@ -38187,6 +38262,7 @@ exports.WORK_TIME_DIRECTION = WORK_TIME_DIRECTION;
38187
38262
  exports.activityBackendRow = activityBackendRow;
38188
38263
  exports.allowedSecondaryConstraintTypes = allowedSecondaryConstraintTypes;
38189
38264
  exports.appendGroupRowId = appendGroupRowId;
38265
+ exports.baselineVarianceDays = baselineVarianceDays;
38190
38266
  exports.buildGroupRowId = buildGroupRowId;
38191
38267
  exports.checkNoUpdatedLinks = checkNoUpdatedLinks;
38192
38268
  exports.computeExpectedProgress = computeExpectedProgress;
@@ -38201,6 +38277,7 @@ exports.expectedProgressFromBaseline = expectedProgressFromBaseline;
38201
38277
  exports.formatUtcAsP6WallDate = formatUtcAsP6WallDate;
38202
38278
  exports.getActiveBaseline = getActiveBaseline;
38203
38279
  exports.getUnsavedActivities = getUnsavedActivities;
38280
+ exports.getVisibleBaseline = getVisibleBaseline;
38204
38281
  exports.hostScheduleInput = hostScheduleInput;
38205
38282
  exports.isRestorableActivityField = isRestorableActivityField;
38206
38283
  exports.isRevertibleActivityField = isRevertibleActivityField;