@outbuild-company/schedule-core 1.8.0 → 1.9.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 +319 -128
- 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 +319 -128
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -420,6 +420,107 @@ function getFieldDescriptor(field) {
|
|
|
420
420
|
return FIELD_REGISTRY[field] ?? null;
|
|
421
421
|
}
|
|
422
422
|
|
|
423
|
+
// src/internal/state/view-state.ts
|
|
424
|
+
function isRelativePlacementPinValid(activityId, pin, parentOf) {
|
|
425
|
+
const branchParentId = String(pin.branchParentId);
|
|
426
|
+
const currentParentId = String(parentOf(activityId) ?? "0");
|
|
427
|
+
if (currentParentId !== branchParentId) return false;
|
|
428
|
+
const referenceId = String(pin.referenceId);
|
|
429
|
+
return referenceId === branchParentId || String(parentOf(referenceId) ?? "0") === branchParentId;
|
|
430
|
+
}
|
|
431
|
+
var ViewStateStore = class {
|
|
432
|
+
checkedSet = /* @__PURE__ */ new Set();
|
|
433
|
+
hiddenSet = /* @__PURE__ */ new Set();
|
|
434
|
+
activeFilter = null;
|
|
435
|
+
activeOrder = null;
|
|
436
|
+
relativePlacementPins = /* @__PURE__ */ new Map();
|
|
437
|
+
isChecked(activityId) {
|
|
438
|
+
return this.checkedSet.has(activityId);
|
|
439
|
+
}
|
|
440
|
+
isVisible(activityId) {
|
|
441
|
+
return !this.hiddenSet.has(activityId);
|
|
442
|
+
}
|
|
443
|
+
hiddenIds() {
|
|
444
|
+
return [...this.hiddenSet];
|
|
445
|
+
}
|
|
446
|
+
getActiveFilter() {
|
|
447
|
+
return this.activeFilter;
|
|
448
|
+
}
|
|
449
|
+
setActiveFilter(nextFilter) {
|
|
450
|
+
this.activeFilter = nextFilter;
|
|
451
|
+
}
|
|
452
|
+
getActiveOrder() {
|
|
453
|
+
return this.activeOrder;
|
|
454
|
+
}
|
|
455
|
+
setActiveOrder(nextOrder) {
|
|
456
|
+
this.activeOrder = nextOrder;
|
|
457
|
+
}
|
|
458
|
+
setRelativePlacementPin(activityId, pin) {
|
|
459
|
+
this.relativePlacementPins.set(String(activityId), {
|
|
460
|
+
referenceId: String(pin.referenceId),
|
|
461
|
+
branchParentId: String(pin.branchParentId),
|
|
462
|
+
side: pin.side
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
getRelativePlacementPins() {
|
|
466
|
+
return this.relativePlacementPins;
|
|
467
|
+
}
|
|
468
|
+
restoreRelativePlacementPins(pins) {
|
|
469
|
+
this.relativePlacementPins = new Map(pins);
|
|
470
|
+
}
|
|
471
|
+
checkedIds() {
|
|
472
|
+
return [...this.checkedSet];
|
|
473
|
+
}
|
|
474
|
+
checkedCount() {
|
|
475
|
+
return this.checkedSet.size;
|
|
476
|
+
}
|
|
477
|
+
setChecked(activityId, nextChecked) {
|
|
478
|
+
if (nextChecked === this.checkedSet.has(activityId)) return false;
|
|
479
|
+
if (nextChecked) this.checkedSet.add(activityId);
|
|
480
|
+
else this.checkedSet.delete(activityId);
|
|
481
|
+
return true;
|
|
482
|
+
}
|
|
483
|
+
setVisible(activityId, nextVisible) {
|
|
484
|
+
if (nextVisible === !this.hiddenSet.has(activityId)) return false;
|
|
485
|
+
if (nextVisible) this.hiddenSet.delete(activityId);
|
|
486
|
+
else this.hiddenSet.add(activityId);
|
|
487
|
+
return true;
|
|
488
|
+
}
|
|
489
|
+
forget(activityId) {
|
|
490
|
+
this.checkedSet.delete(activityId);
|
|
491
|
+
this.hiddenSet.delete(activityId);
|
|
492
|
+
this.relativePlacementPins.delete(activityId);
|
|
493
|
+
for (const [pinnedId, pin] of this.relativePlacementPins) {
|
|
494
|
+
if (pin.referenceId === activityId) {
|
|
495
|
+
this.relativePlacementPins.delete(pinnedId);
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
hydrate(seed2) {
|
|
500
|
+
this.checkedSet = new Set(seed2.checkedIds ?? []);
|
|
501
|
+
this.hiddenSet = new Set(seed2.hiddenIds ?? []);
|
|
502
|
+
this.activeFilter = null;
|
|
503
|
+
this.activeOrder = null;
|
|
504
|
+
this.relativePlacementPins = /* @__PURE__ */ new Map();
|
|
505
|
+
}
|
|
506
|
+
snapshot() {
|
|
507
|
+
return {
|
|
508
|
+
checked: new Set(this.checkedSet),
|
|
509
|
+
hidden: new Set(this.hiddenSet),
|
|
510
|
+
activeFilter: this.activeFilter,
|
|
511
|
+
activeOrder: this.activeOrder,
|
|
512
|
+
relativePlacementPins: new Map(this.relativePlacementPins)
|
|
513
|
+
};
|
|
514
|
+
}
|
|
515
|
+
restore(snapshot) {
|
|
516
|
+
this.checkedSet = new Set(snapshot.checked);
|
|
517
|
+
this.hiddenSet = new Set(snapshot.hidden);
|
|
518
|
+
this.activeFilter = snapshot.activeFilter;
|
|
519
|
+
this.activeOrder = snapshot.activeOrder;
|
|
520
|
+
this.relativePlacementPins = new Map(snapshot.relativePlacementPins);
|
|
521
|
+
}
|
|
522
|
+
};
|
|
523
|
+
|
|
423
524
|
// src/internal/filter/evaluate-filter.ts
|
|
424
525
|
function toTargetDate(value) {
|
|
425
526
|
if (value instanceof Date) return value;
|
|
@@ -562,13 +663,8 @@ function seedFilterProjection(input) {
|
|
|
562
663
|
);
|
|
563
664
|
}
|
|
564
665
|
const isMatch = matchesFilter(activity, filter, context);
|
|
565
|
-
|
|
566
|
-
visibleReferenceCounts.set(
|
|
567
|
-
activityId,
|
|
568
|
-
(isMatch ? 1 : 0) + (isPinned ? 1 : 0)
|
|
569
|
-
);
|
|
666
|
+
visibleReferenceCounts.set(activityId, isMatch ? 1 : 0);
|
|
570
667
|
if (isMatch) matchedIds.add(activityId);
|
|
571
|
-
if (isPinned) pinnedVisibleIds.add(activityId);
|
|
572
668
|
}
|
|
573
669
|
return {
|
|
574
670
|
matchedIds,
|
|
@@ -578,6 +674,29 @@ function seedFilterProjection(input) {
|
|
|
578
674
|
remainingChildren
|
|
579
675
|
};
|
|
580
676
|
}
|
|
677
|
+
function applyRelativePlacementPins(seed2, pins) {
|
|
678
|
+
if (pins === void 0) return;
|
|
679
|
+
for (const [activityId, pin] of pins) {
|
|
680
|
+
const pinnedId = String(activityId);
|
|
681
|
+
const referenceId = String(pin.referenceId);
|
|
682
|
+
if (!seed2.parentIds.has(pinnedId) || !seed2.parentIds.has(referenceId) || !isRelativePlacementPinValid(
|
|
683
|
+
pinnedId,
|
|
684
|
+
pin,
|
|
685
|
+
(activityId2) => seed2.parentIds.get(activityId2) ?? null
|
|
686
|
+
) || (seed2.visibleReferenceCounts.get(referenceId) ?? 0) === 0) {
|
|
687
|
+
continue;
|
|
688
|
+
}
|
|
689
|
+
seed2.pinnedVisibleIds.add(pinnedId);
|
|
690
|
+
let currentId = pinnedId;
|
|
691
|
+
while (currentId !== null) {
|
|
692
|
+
seed2.visibleReferenceCounts.set(
|
|
693
|
+
currentId,
|
|
694
|
+
(seed2.visibleReferenceCounts.get(currentId) ?? 0) + 1
|
|
695
|
+
);
|
|
696
|
+
currentId = seed2.parentIds.get(currentId) ?? null;
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
}
|
|
581
700
|
function propagateVisibleReferenceCounts(seed2) {
|
|
582
701
|
const { visibleReferenceCounts, parentIds, remainingChildren } = seed2;
|
|
583
702
|
const pendingIds = [];
|
|
@@ -609,6 +728,7 @@ function collectVisibleIds(visibleReferenceCounts) {
|
|
|
609
728
|
function buildFilterProjection(input) {
|
|
610
729
|
const seed2 = seedFilterProjection(input);
|
|
611
730
|
propagateVisibleReferenceCounts(seed2);
|
|
731
|
+
applyRelativePlacementPins(seed2, input.relativePlacementPins);
|
|
612
732
|
const visibleIds = collectVisibleIds(seed2.visibleReferenceCounts);
|
|
613
733
|
return {
|
|
614
734
|
filter: input.filter,
|
|
@@ -796,7 +916,8 @@ function resolveFilter(adapter, filter, hoursPerDay) {
|
|
|
796
916
|
activities,
|
|
797
917
|
parentOf: (activityId) => adapter.getParentId(activityId),
|
|
798
918
|
filter,
|
|
799
|
-
context: buildFilterContext(hoursPerDay)
|
|
919
|
+
context: buildFilterContext(hoursPerDay),
|
|
920
|
+
relativePlacementPins: adapter.getRelativePlacementPins()
|
|
800
921
|
});
|
|
801
922
|
return { visibleIds: projection.visibleIds, projection };
|
|
802
923
|
}
|
|
@@ -847,25 +968,118 @@ function normalizeParentKey(parent) {
|
|
|
847
968
|
|
|
848
969
|
// src/internal/hierarchy/visual-order.ts
|
|
849
970
|
var NOT_SET_SORT_VALUE = Number.MAX_SAFE_INTEGER;
|
|
850
|
-
|
|
971
|
+
var EMPTY_RELATIVE_PLACEMENT_PINS = /* @__PURE__ */ new Map();
|
|
972
|
+
function buildRelativePlacementPinIndex(adapter) {
|
|
973
|
+
const index = /* @__PURE__ */ new Map();
|
|
974
|
+
for (const [activityId, pin] of adapter.getRelativePlacementPins?.() ?? []) {
|
|
975
|
+
const pinnedId = String(activityId);
|
|
976
|
+
const referenceId = String(pin.referenceId);
|
|
977
|
+
if (adapter.getActivity(pinnedId) === null || adapter.getActivity(referenceId) === null || !isRelativePlacementPinValid(
|
|
978
|
+
pinnedId,
|
|
979
|
+
pin,
|
|
980
|
+
(activityId2) => adapter.getParentId(activityId2)
|
|
981
|
+
)) {
|
|
982
|
+
continue;
|
|
983
|
+
}
|
|
984
|
+
const targetParentId = String(pin.branchParentId);
|
|
985
|
+
const branchPins = index.get(targetParentId) ?? /* @__PURE__ */ new Map();
|
|
986
|
+
branchPins.set(pinnedId, pin);
|
|
987
|
+
index.set(targetParentId, branchPins);
|
|
988
|
+
}
|
|
989
|
+
return index;
|
|
990
|
+
}
|
|
991
|
+
function getChildrenInVisualOrder(parentId, adapter, pinIndex = buildRelativePlacementPinIndex(adapter)) {
|
|
851
992
|
const children = collectChildrenSnapshots(parentId, adapter);
|
|
852
993
|
const userOrder = adapter.getOrderComparator?.() ?? null;
|
|
853
994
|
children.sort(
|
|
854
995
|
userOrder === null ? compareActivitiesInVisualOrder : (a, b) => userOrder(a, b) || compareActivitiesInVisualOrder(a, b)
|
|
855
996
|
);
|
|
856
|
-
return
|
|
997
|
+
return applyRelativePlacementPins2(
|
|
998
|
+
children.map((activity) => String(activity.id)),
|
|
999
|
+
parentId,
|
|
1000
|
+
pinIndex.get(String(parentId)) ?? EMPTY_RELATIVE_PLACEMENT_PINS
|
|
1001
|
+
);
|
|
1002
|
+
}
|
|
1003
|
+
function applyRelativePlacementPins2(orderedIds, parentId, pins) {
|
|
1004
|
+
const order = buildLinkedActivityOrder(orderedIds);
|
|
1005
|
+
for (const [activityId, pin] of pins) {
|
|
1006
|
+
const pinnedId = String(activityId);
|
|
1007
|
+
const referenceId = String(pin.referenceId);
|
|
1008
|
+
const isFirstChild = referenceId === String(parentId);
|
|
1009
|
+
if (!order.previous.has(pinnedId) || !isFirstChild && (!order.previous.has(referenceId) || pinnedId === referenceId)) {
|
|
1010
|
+
continue;
|
|
1011
|
+
}
|
|
1012
|
+
detachActivity(order, pinnedId);
|
|
1013
|
+
if (isFirstChild) insertActivityFirst(order, pinnedId);
|
|
1014
|
+
else insertActivityBeside(order, pinnedId, referenceId, pin.side);
|
|
1015
|
+
}
|
|
1016
|
+
return materializeActivityOrder(order);
|
|
1017
|
+
}
|
|
1018
|
+
function buildLinkedActivityOrder(orderedIds) {
|
|
1019
|
+
const previous = /* @__PURE__ */ new Map();
|
|
1020
|
+
const next = /* @__PURE__ */ new Map();
|
|
1021
|
+
for (let index = 0; index < orderedIds.length; index++) {
|
|
1022
|
+
const activityId = orderedIds[index];
|
|
1023
|
+
if (activityId === void 0) continue;
|
|
1024
|
+
previous.set(activityId, orderedIds[index - 1] ?? null);
|
|
1025
|
+
next.set(activityId, orderedIds[index + 1] ?? null);
|
|
1026
|
+
}
|
|
1027
|
+
return { previous, next, head: orderedIds[0] ?? null };
|
|
1028
|
+
}
|
|
1029
|
+
function detachActivity(order, activityId) {
|
|
1030
|
+
const before = order.previous.get(activityId) ?? null;
|
|
1031
|
+
const after = order.next.get(activityId) ?? null;
|
|
1032
|
+
if (before === null) order.head = after;
|
|
1033
|
+
else order.next.set(before, after);
|
|
1034
|
+
if (after !== null) order.previous.set(after, before);
|
|
1035
|
+
}
|
|
1036
|
+
function insertActivityFirst(order, activityId) {
|
|
1037
|
+
order.previous.set(activityId, null);
|
|
1038
|
+
order.next.set(activityId, order.head);
|
|
1039
|
+
if (order.head !== null) order.previous.set(order.head, activityId);
|
|
1040
|
+
order.head = activityId;
|
|
1041
|
+
}
|
|
1042
|
+
function insertActivityBeside(order, activityId, referenceId, side) {
|
|
1043
|
+
if (side === "before") {
|
|
1044
|
+
const before = order.previous.get(referenceId) ?? null;
|
|
1045
|
+
order.previous.set(activityId, before);
|
|
1046
|
+
order.next.set(activityId, referenceId);
|
|
1047
|
+
order.previous.set(referenceId, activityId);
|
|
1048
|
+
if (before === null) order.head = activityId;
|
|
1049
|
+
else order.next.set(before, activityId);
|
|
1050
|
+
return;
|
|
1051
|
+
}
|
|
1052
|
+
const after = order.next.get(referenceId) ?? null;
|
|
1053
|
+
order.previous.set(activityId, referenceId);
|
|
1054
|
+
order.next.set(activityId, after);
|
|
1055
|
+
order.next.set(referenceId, activityId);
|
|
1056
|
+
if (after !== null) order.previous.set(after, activityId);
|
|
1057
|
+
}
|
|
1058
|
+
function materializeActivityOrder(order) {
|
|
1059
|
+
const result = [];
|
|
1060
|
+
let activityId = order.head;
|
|
1061
|
+
while (activityId !== null) {
|
|
1062
|
+
result.push(activityId);
|
|
1063
|
+
activityId = order.next.get(activityId) ?? null;
|
|
1064
|
+
}
|
|
1065
|
+
return result;
|
|
857
1066
|
}
|
|
858
1067
|
function iterateInVisualOrder(adapter) {
|
|
859
1068
|
const result = [];
|
|
1069
|
+
const pinIndex = buildRelativePlacementPinIndex(adapter);
|
|
860
1070
|
const visit = (activity) => {
|
|
861
1071
|
result.push(activity);
|
|
862
|
-
const childIds = getChildrenInVisualOrder(
|
|
1072
|
+
const childIds = getChildrenInVisualOrder(
|
|
1073
|
+
String(activity.id),
|
|
1074
|
+
adapter,
|
|
1075
|
+
pinIndex
|
|
1076
|
+
);
|
|
863
1077
|
for (const childId of childIds) {
|
|
864
1078
|
const child = adapter.getActivity(childId);
|
|
865
1079
|
if (child) visit(child);
|
|
866
1080
|
}
|
|
867
1081
|
};
|
|
868
|
-
const rootIds = getChildrenInVisualOrder(ROOT_PARENT_ID, adapter);
|
|
1082
|
+
const rootIds = getChildrenInVisualOrder(ROOT_PARENT_ID, adapter, pinIndex);
|
|
869
1083
|
for (const rootId of rootIds) {
|
|
870
1084
|
const root = adapter.getActivity(rootId);
|
|
871
1085
|
if (root) visit(root);
|
|
@@ -926,8 +1140,9 @@ function setHas(set, id) {
|
|
|
926
1140
|
// src/dispatch/shared/collect-branch-order.ts
|
|
927
1141
|
function collectBranchOrder(adapter) {
|
|
928
1142
|
const branches = [];
|
|
1143
|
+
const pinIndex = buildRelativePlacementPinIndex(adapter);
|
|
929
1144
|
const visit = (parentId) => {
|
|
930
|
-
const childIds = getChildrenInVisualOrder(parentId, adapter);
|
|
1145
|
+
const childIds = getChildrenInVisualOrder(parentId, adapter, pinIndex);
|
|
931
1146
|
if (childIds.length > 1) {
|
|
932
1147
|
branches.push({ parentId, childIds });
|
|
933
1148
|
}
|
|
@@ -940,8 +1155,9 @@ function collectBranchOrder(adapter) {
|
|
|
940
1155
|
}
|
|
941
1156
|
function collectBranchOrderForParents(adapter, parentIds) {
|
|
942
1157
|
const branches = [];
|
|
1158
|
+
const pinIndex = buildRelativePlacementPinIndex(adapter);
|
|
943
1159
|
for (const parentId of parentIds) {
|
|
944
|
-
const childIds = getChildrenInVisualOrder(parentId, adapter);
|
|
1160
|
+
const childIds = getChildrenInVisualOrder(parentId, adapter, pinIndex);
|
|
945
1161
|
if (childIds.length > 1) branches.push({ parentId, childIds });
|
|
946
1162
|
}
|
|
947
1163
|
return branches;
|
|
@@ -4086,8 +4302,8 @@ var costPipeline = {
|
|
|
4086
4302
|
}
|
|
4087
4303
|
return canEdit();
|
|
4088
4304
|
},
|
|
4089
|
-
parseInput(rawValue
|
|
4090
|
-
if (String(rawValue).trim() === "") return parsed(
|
|
4305
|
+
parseInput(rawValue) {
|
|
4306
|
+
if (String(rawValue).trim() === "") return parsed(0);
|
|
4091
4307
|
const numericValue = parseFloat(String(rawValue));
|
|
4092
4308
|
if (Number.isNaN(numericValue)) return parseError("not_a_number");
|
|
4093
4309
|
return parsed(numericValue);
|
|
@@ -4136,8 +4352,8 @@ var usedCostPipeline = {
|
|
|
4136
4352
|
}
|
|
4137
4353
|
return canEdit();
|
|
4138
4354
|
},
|
|
4139
|
-
parseInput(rawValue
|
|
4140
|
-
if (String(rawValue).trim() === "") return parsed(
|
|
4355
|
+
parseInput(rawValue) {
|
|
4356
|
+
if (String(rawValue).trim() === "") return parsed(0);
|
|
4141
4357
|
const numericValue = parseFloat(String(rawValue));
|
|
4142
4358
|
if (Number.isNaN(numericValue)) return parseError("not_a_number");
|
|
4143
4359
|
return parsed(numericValue);
|
|
@@ -17662,77 +17878,6 @@ var HierarchyIndex = class {
|
|
|
17662
17878
|
}
|
|
17663
17879
|
};
|
|
17664
17880
|
|
|
17665
|
-
// src/internal/state/view-state.ts
|
|
17666
|
-
var ViewStateStore = class {
|
|
17667
|
-
checkedSet = /* @__PURE__ */ new Set();
|
|
17668
|
-
hiddenSet = /* @__PURE__ */ new Set();
|
|
17669
|
-
activeFilter = null;
|
|
17670
|
-
activeOrder = null;
|
|
17671
|
-
isChecked(activityId) {
|
|
17672
|
-
return this.checkedSet.has(activityId);
|
|
17673
|
-
}
|
|
17674
|
-
isVisible(activityId) {
|
|
17675
|
-
return !this.hiddenSet.has(activityId);
|
|
17676
|
-
}
|
|
17677
|
-
hiddenIds() {
|
|
17678
|
-
return [...this.hiddenSet];
|
|
17679
|
-
}
|
|
17680
|
-
getActiveFilter() {
|
|
17681
|
-
return this.activeFilter;
|
|
17682
|
-
}
|
|
17683
|
-
setActiveFilter(nextFilter) {
|
|
17684
|
-
this.activeFilter = nextFilter;
|
|
17685
|
-
}
|
|
17686
|
-
getActiveOrder() {
|
|
17687
|
-
return this.activeOrder;
|
|
17688
|
-
}
|
|
17689
|
-
setActiveOrder(nextOrder) {
|
|
17690
|
-
this.activeOrder = nextOrder;
|
|
17691
|
-
}
|
|
17692
|
-
checkedIds() {
|
|
17693
|
-
return [...this.checkedSet];
|
|
17694
|
-
}
|
|
17695
|
-
checkedCount() {
|
|
17696
|
-
return this.checkedSet.size;
|
|
17697
|
-
}
|
|
17698
|
-
setChecked(activityId, nextChecked) {
|
|
17699
|
-
if (nextChecked === this.checkedSet.has(activityId)) return false;
|
|
17700
|
-
if (nextChecked) this.checkedSet.add(activityId);
|
|
17701
|
-
else this.checkedSet.delete(activityId);
|
|
17702
|
-
return true;
|
|
17703
|
-
}
|
|
17704
|
-
setVisible(activityId, nextVisible) {
|
|
17705
|
-
if (nextVisible === !this.hiddenSet.has(activityId)) return false;
|
|
17706
|
-
if (nextVisible) this.hiddenSet.delete(activityId);
|
|
17707
|
-
else this.hiddenSet.add(activityId);
|
|
17708
|
-
return true;
|
|
17709
|
-
}
|
|
17710
|
-
forget(activityId) {
|
|
17711
|
-
this.checkedSet.delete(activityId);
|
|
17712
|
-
this.hiddenSet.delete(activityId);
|
|
17713
|
-
}
|
|
17714
|
-
hydrate(seed2) {
|
|
17715
|
-
this.checkedSet = new Set(seed2.checkedIds ?? []);
|
|
17716
|
-
this.hiddenSet = new Set(seed2.hiddenIds ?? []);
|
|
17717
|
-
this.activeFilter = null;
|
|
17718
|
-
this.activeOrder = null;
|
|
17719
|
-
}
|
|
17720
|
-
snapshot() {
|
|
17721
|
-
return {
|
|
17722
|
-
checked: new Set(this.checkedSet),
|
|
17723
|
-
hidden: new Set(this.hiddenSet),
|
|
17724
|
-
activeFilter: this.activeFilter,
|
|
17725
|
-
activeOrder: this.activeOrder
|
|
17726
|
-
};
|
|
17727
|
-
}
|
|
17728
|
-
restore(snapshot) {
|
|
17729
|
-
this.checkedSet = new Set(snapshot.checked);
|
|
17730
|
-
this.hiddenSet = new Set(snapshot.hidden);
|
|
17731
|
-
this.activeFilter = snapshot.activeFilter;
|
|
17732
|
-
this.activeOrder = snapshot.activeOrder;
|
|
17733
|
-
}
|
|
17734
|
-
};
|
|
17735
|
-
|
|
17736
17881
|
// src/internal/state/schedule-state.ts
|
|
17737
17882
|
var ScheduleState = class _ScheduleState {
|
|
17738
17883
|
_activities = /* @__PURE__ */ new Map();
|
|
@@ -17911,6 +18056,18 @@ var ScheduleState = class _ScheduleState {
|
|
|
17911
18056
|
this._viewState.setActiveOrder(nextOrder);
|
|
17912
18057
|
this.invalidateDerivedOrder();
|
|
17913
18058
|
}
|
|
18059
|
+
setRelativePlacementPin(activityId, pin) {
|
|
18060
|
+
this._viewState.setRelativePlacementPin(String(activityId), pin);
|
|
18061
|
+
this.invalidateVisualOrderIds();
|
|
18062
|
+
}
|
|
18063
|
+
getRelativePlacementPins() {
|
|
18064
|
+
return this._viewState.getRelativePlacementPins();
|
|
18065
|
+
}
|
|
18066
|
+
restoreRelativePlacementPins(pins) {
|
|
18067
|
+
this._viewState.restoreRelativePlacementPins(pins);
|
|
18068
|
+
this._filterProjection = null;
|
|
18069
|
+
this.invalidateVisualOrderIds();
|
|
18070
|
+
}
|
|
17914
18071
|
/**
|
|
17915
18072
|
* Rebuild-on-demand, memoized: at most one build per invalidation, never one
|
|
17916
18073
|
* per comparison. getChildrenInVisualOrder asks for this once and then sorts a
|
|
@@ -18117,10 +18274,14 @@ var ScheduleState = class _ScheduleState {
|
|
|
18117
18274
|
const activity = this.getActivity(activityId);
|
|
18118
18275
|
if (activity) this._writeCapture.noteRemove(String(activityId), activity);
|
|
18119
18276
|
const key = String(activityId);
|
|
18120
|
-
|
|
18277
|
+
const relativePlacementPins = this._viewState.getRelativePlacementPins();
|
|
18278
|
+
const hasDependentPin = [...relativePlacementPins.values()].some(
|
|
18279
|
+
({ referenceId }) => referenceId === key
|
|
18280
|
+
);
|
|
18281
|
+
if (this._viewState.isChecked(key) || !this._viewState.isVisible(key) || relativePlacementPins.has(key) || hasDependentPin) {
|
|
18121
18282
|
this._captureViewStateOnce();
|
|
18122
|
-
this._viewState.forget(key);
|
|
18123
18283
|
}
|
|
18284
|
+
this._viewState.forget(key);
|
|
18124
18285
|
this._activities.delete(activityId);
|
|
18125
18286
|
if (this._lastStartDate.has(String(activityId))) {
|
|
18126
18287
|
this._captureLastStartDateOnce();
|
|
@@ -18378,13 +18539,15 @@ function buildHistoryChangeSet(changes) {
|
|
|
18378
18539
|
links: linksWithoutAfter
|
|
18379
18540
|
});
|
|
18380
18541
|
}
|
|
18381
|
-
function buildUndoEntry(changeSet, beforeSnap, beforeLinks, afterSnap, afterLinks) {
|
|
18542
|
+
function buildUndoEntry(changeSet, beforeSnap, beforeLinks, afterSnap, afterLinks, relativePlacementPinsBefore, relativePlacementPinsAfter) {
|
|
18382
18543
|
return {
|
|
18383
18544
|
changeSet,
|
|
18384
18545
|
beforeSnap,
|
|
18385
18546
|
beforeLinks: resetDerivedLinkSnapshots(beforeLinks),
|
|
18386
18547
|
afterSnap,
|
|
18387
|
-
afterLinks: resetDerivedLinkSnapshots(afterLinks)
|
|
18548
|
+
afterLinks: resetDerivedLinkSnapshots(afterLinks),
|
|
18549
|
+
relativePlacementPinsBefore,
|
|
18550
|
+
relativePlacementPinsAfter
|
|
18388
18551
|
};
|
|
18389
18552
|
}
|
|
18390
18553
|
function resetDerivedLinkSnapshots(snapshots) {
|
|
@@ -18687,6 +18850,8 @@ function applyChangeSetSide(state, entry, side) {
|
|
|
18687
18850
|
);
|
|
18688
18851
|
}
|
|
18689
18852
|
}
|
|
18853
|
+
const pins = side === "before" ? entry.relativePlacementPinsBefore : entry.relativePlacementPinsAfter;
|
|
18854
|
+
if (pins !== void 0) state.restoreRelativePlacementPins(pins);
|
|
18690
18855
|
}
|
|
18691
18856
|
|
|
18692
18857
|
// src/dispatch/undo/undo-recorder.ts
|
|
@@ -21031,12 +21196,41 @@ function collectChangedActivities(changes, adapter) {
|
|
|
21031
21196
|
}
|
|
21032
21197
|
return activities;
|
|
21033
21198
|
}
|
|
21199
|
+
function changesAffectRelativePinProjection(changes, changedActivities, adapter, pins) {
|
|
21200
|
+
if (pins.size === 0) return false;
|
|
21201
|
+
if (changes.activities.some(
|
|
21202
|
+
(change) => change.kind === "created" && pins.has(String(change.id))
|
|
21203
|
+
)) {
|
|
21204
|
+
return true;
|
|
21205
|
+
}
|
|
21206
|
+
const referenceIds = new Set(
|
|
21207
|
+
[...pins.values()].map(({ referenceId }) => String(referenceId))
|
|
21208
|
+
);
|
|
21209
|
+
for (const activity of changedActivities) {
|
|
21210
|
+
let activityId = String(activity.id);
|
|
21211
|
+
while (activityId !== null) {
|
|
21212
|
+
if (referenceIds.has(activityId)) return true;
|
|
21213
|
+
activityId = adapter.getParentId(activityId);
|
|
21214
|
+
}
|
|
21215
|
+
}
|
|
21216
|
+
return false;
|
|
21217
|
+
}
|
|
21034
21218
|
function isCurrentFilterProjection(projection, filter, context) {
|
|
21035
21219
|
if (projection === null || projection.filter !== filter) return false;
|
|
21036
21220
|
const hasCurrentHours = projection.context.hoursPerDay === context.hoursPerDay;
|
|
21037
21221
|
const hasCurrentLocale = projection.context.locale === context.locale;
|
|
21038
21222
|
return hasCurrentHours && hasCurrentLocale;
|
|
21039
21223
|
}
|
|
21224
|
+
function relativePlacementPinsEqual(left, right) {
|
|
21225
|
+
if (left.size !== right.size) return false;
|
|
21226
|
+
for (const [activityId, pin] of left) {
|
|
21227
|
+
const other = right.get(activityId);
|
|
21228
|
+
if (other === void 0 || other.referenceId !== pin.referenceId || other.branchParentId !== pin.branchParentId || other.side !== pin.side) {
|
|
21229
|
+
return false;
|
|
21230
|
+
}
|
|
21231
|
+
}
|
|
21232
|
+
return true;
|
|
21233
|
+
}
|
|
21040
21234
|
var ScheduleCore = class _ScheduleCore {
|
|
21041
21235
|
_activityClipboard = { value: null };
|
|
21042
21236
|
_status = SCHEDULE_CORE_STATUS.READY;
|
|
@@ -21484,6 +21678,8 @@ var ScheduleCore = class _ScheduleCore {
|
|
|
21484
21678
|
dateFormat: this.coreRuntime.sector.dateFormat
|
|
21485
21679
|
});
|
|
21486
21680
|
const historyPolicy = getDispatchHistoryPolicy(action);
|
|
21681
|
+
const capturesRelativePlacementPins = action.kind === "activity-create" || action.kind === "activity-delete" || action.kind === "activity-batch" && action.mode === "replace";
|
|
21682
|
+
const relativePlacementPinsBefore = capturesRelativePlacementPins ? new Map(this.coreRuntime.state.getRelativePlacementPins()) : void 0;
|
|
21487
21683
|
const generatorSnapshot = [
|
|
21488
21684
|
this.coreRuntime.activityIdGenerator.snapshot(),
|
|
21489
21685
|
this.coreRuntime.linkIdGenerator.snapshot(),
|
|
@@ -21520,18 +21716,26 @@ var ScheduleCore = class _ScheduleCore {
|
|
|
21520
21716
|
this.coreRuntime.state.endWriteCapture();
|
|
21521
21717
|
this.coreRuntime.customIdTracker.commitCustomIdTransaction();
|
|
21522
21718
|
}
|
|
21719
|
+
if (result.ok) this._recordRelativePlacementPin(action, result.changes);
|
|
21523
21720
|
if (result.ok && historyPolicy === "record" && changeSetIsSubstantive(result.changes)) {
|
|
21524
21721
|
const created = captureCreatedSnapshots(
|
|
21525
21722
|
this.coreRuntime.state,
|
|
21526
21723
|
result.changes
|
|
21527
21724
|
);
|
|
21725
|
+
const relativePlacementPinsAfter = capturesRelativePlacementPins ? new Map(this.coreRuntime.state.getRelativePlacementPins()) : void 0;
|
|
21726
|
+
const relativePlacementPinsChanged = relativePlacementPinsBefore !== void 0 && relativePlacementPinsAfter !== void 0 && !relativePlacementPinsEqual(
|
|
21727
|
+
relativePlacementPinsBefore,
|
|
21728
|
+
relativePlacementPinsAfter
|
|
21729
|
+
);
|
|
21528
21730
|
this._undo.record(
|
|
21529
21731
|
buildUndoEntry(
|
|
21530
21732
|
buildHistoryChangeSet(result.changes),
|
|
21531
21733
|
result.__beforeSnap,
|
|
21532
21734
|
result.__beforeLinks,
|
|
21533
21735
|
created.afterSnap,
|
|
21534
|
-
created.afterLinks
|
|
21736
|
+
created.afterLinks,
|
|
21737
|
+
relativePlacementPinsChanged ? relativePlacementPinsBefore : void 0,
|
|
21738
|
+
relativePlacementPinsChanged ? relativePlacementPinsAfter : void 0
|
|
21535
21739
|
),
|
|
21536
21740
|
computeCoalesceKey(action),
|
|
21537
21741
|
Date.now()
|
|
@@ -21599,6 +21803,19 @@ var ScheduleCore = class _ScheduleCore {
|
|
|
21599
21803
|
const merged = this._reapplyViewState(result.changes);
|
|
21600
21804
|
return merged === null ? result : { ...result, changes: merged };
|
|
21601
21805
|
}
|
|
21806
|
+
_recordRelativePlacementPin(action, changes) {
|
|
21807
|
+
const state = this.coreRuntime.state;
|
|
21808
|
+
if (action.kind !== "activity-create") return;
|
|
21809
|
+
const referenceId = action.afterSiblingId ?? action.beforeSiblingId ?? (action.eventSource === "Creation button (+)" && action.parentId !== ROOT_PARENT_ID ? action.parentId : void 0);
|
|
21810
|
+
if (referenceId === void 0) return;
|
|
21811
|
+
const created = changes.activities.find(({ kind }) => kind === "created");
|
|
21812
|
+
if (created === void 0) return;
|
|
21813
|
+
state.setRelativePlacementPin(created.id, {
|
|
21814
|
+
referenceId,
|
|
21815
|
+
branchParentId: action.parentId,
|
|
21816
|
+
side: action.beforeSiblingId === void 0 ? "after" : "before"
|
|
21817
|
+
});
|
|
21818
|
+
}
|
|
21602
21819
|
/**
|
|
21603
21820
|
* The single place the two view-state passes are chained. Dispatch, undo and
|
|
21604
21821
|
* redo all route through here: when this existed only inside the dispatch
|
|
@@ -21621,39 +21838,7 @@ var ScheduleCore = class _ScheduleCore {
|
|
|
21621
21838
|
sequenced.changes ?? withFilter ?? changes,
|
|
21622
21839
|
sequenced.touchedParents
|
|
21623
21840
|
);
|
|
21624
|
-
|
|
21625
|
-
const finalChanges = reapplied ?? changes;
|
|
21626
|
-
const createdIds = finalChanges.activities.filter((change) => change.kind === "created").map((change) => String(change.id));
|
|
21627
|
-
if (createdIds.length === 0) return reapplied;
|
|
21628
|
-
const createdAndAncestors = new Set(createdIds);
|
|
21629
|
-
const filterProjection = this.coreRuntime.state.getFilterProjection();
|
|
21630
|
-
for (const createdId of createdIds) {
|
|
21631
|
-
if (filterProjection !== null) {
|
|
21632
|
-
filterProjection.pinnedVisibleIds.add(createdId);
|
|
21633
|
-
}
|
|
21634
|
-
let activityId = createdId;
|
|
21635
|
-
while (activityId !== null && activityId !== ROOT_PARENT_ID) {
|
|
21636
|
-
createdAndAncestors.add(activityId);
|
|
21637
|
-
if (filterProjection !== null) {
|
|
21638
|
-
filterProjection.visibleIds.add(activityId);
|
|
21639
|
-
filterProjection.visibleReferenceCounts.set(
|
|
21640
|
-
activityId,
|
|
21641
|
-
(filterProjection.visibleReferenceCounts.get(activityId) ?? 0) + 1
|
|
21642
|
-
);
|
|
21643
|
-
}
|
|
21644
|
-
activityId = this.coreRuntime.state.getParentId(activityId);
|
|
21645
|
-
}
|
|
21646
|
-
}
|
|
21647
|
-
const createdVisibility = applyVisibleSet(
|
|
21648
|
-
this.coreRuntime.state,
|
|
21649
|
-
createdAndAncestors,
|
|
21650
|
-
createdAndAncestors
|
|
21651
|
-
);
|
|
21652
|
-
if (createdVisibility.length === 0) return reapplied;
|
|
21653
|
-
return {
|
|
21654
|
-
...finalChanges,
|
|
21655
|
-
viewState: [...finalChanges.viewState ?? [], ...createdVisibility]
|
|
21656
|
-
};
|
|
21841
|
+
return withOrder ?? sequenced.changes ?? withFilter;
|
|
21657
21842
|
}
|
|
21658
21843
|
/**
|
|
21659
21844
|
* Emits `order` for the branches this mutation resequenced, when no user order
|
|
@@ -21732,16 +21917,22 @@ var ScheduleCore = class _ScheduleCore {
|
|
|
21732
21917
|
context
|
|
21733
21918
|
);
|
|
21734
21919
|
const changedActivities = changesRequireFilterProjectionRebuild(changes) ? null : collectChangedActivities(changes, adapter);
|
|
21920
|
+
const relativePlacementPins = adapter.getRelativePlacementPins();
|
|
21735
21921
|
let affectedIds;
|
|
21736
21922
|
let visibleIds;
|
|
21737
|
-
const needsProjectionRebuild = changedActivities === null || !projectionIsCurrent
|
|
21923
|
+
const needsProjectionRebuild = changedActivities === null || !projectionIsCurrent || changesAffectRelativePinProjection(
|
|
21924
|
+
changes,
|
|
21925
|
+
changedActivities,
|
|
21926
|
+
adapter,
|
|
21927
|
+
relativePlacementPins
|
|
21928
|
+
);
|
|
21738
21929
|
if (needsProjectionRebuild) {
|
|
21739
21930
|
const rebuiltProjection = buildFilterProjection({
|
|
21740
21931
|
activities: adapter.getAllActivities(),
|
|
21741
21932
|
parentOf: (activityId) => adapter.getParentId(activityId),
|
|
21742
21933
|
filter,
|
|
21743
21934
|
context,
|
|
21744
|
-
|
|
21935
|
+
relativePlacementPins
|
|
21745
21936
|
});
|
|
21746
21937
|
adapter.setFilterProjection(rebuiltProjection);
|
|
21747
21938
|
visibleIds = rebuiltProjection.visibleIds;
|