@timeax/digital-service-engine 0.3.5 → 0.3.6
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/index.cjs +659 -162
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +48 -6
- package/dist/core/index.d.ts +48 -6
- package/dist/core/index.js +650 -161
- package/dist/core/index.js.map +1 -1
- package/dist/react/index.cjs +1424 -448
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +48 -5
- package/dist/react/index.d.ts +48 -5
- package/dist/react/index.js +1424 -448
- package/dist/react/index.js.map +1 -1
- package/dist/schema/index.d.cts +19 -2
- package/dist/schema/index.d.ts +19 -2
- package/dist/workspace/index.cjs +1235 -374
- package/dist/workspace/index.cjs.map +1 -1
- package/dist/workspace/index.d.cts +45 -4
- package/dist/workspace/index.d.ts +45 -4
- package/dist/workspace/index.js +1235 -374
- package/dist/workspace/index.js.map +1 -1
- package/package.json +1 -1
- package/schema/editor-snapshot.schema.json +38 -0
- package/schema/service-props.schema.json +38 -0
package/dist/react/index.cjs
CHANGED
|
@@ -731,6 +731,9 @@ function normalise(input, opts = {}) {
|
|
|
731
731
|
const excludes_for_buttons = toStringArrayMap(
|
|
732
732
|
obj.excludes_for_buttons
|
|
733
733
|
);
|
|
734
|
+
const option_effects_for_buttons = toOptionEffectMap(
|
|
735
|
+
obj.option_effects_for_buttons
|
|
736
|
+
);
|
|
734
737
|
const orderKinds = toStringMap(obj.orderKinds);
|
|
735
738
|
const notices = toNoticeArray(obj.notices);
|
|
736
739
|
let filters = rawFilters.map((t) => coerceTag(t, constraints));
|
|
@@ -746,6 +749,9 @@ function normalise(input, opts = {}) {
|
|
|
746
749
|
...isNonEmpty(orderKinds) && { orderKinds },
|
|
747
750
|
...isNonEmpty(includes_for_buttons) && { includes_for_buttons },
|
|
748
751
|
...isNonEmpty(excludes_for_buttons) && { excludes_for_buttons },
|
|
752
|
+
...isNonEmpty(option_effects_for_buttons) && {
|
|
753
|
+
option_effects_for_buttons
|
|
754
|
+
},
|
|
749
755
|
...fallbacks && (isNonEmpty(fallbacks.nodes) || isNonEmpty(fallbacks.global)) && {
|
|
750
756
|
fallbacks
|
|
751
757
|
},
|
|
@@ -900,6 +906,7 @@ function coerceOption(src, inheritRole) {
|
|
|
900
906
|
const value = typeof src.value === "string" || typeof src.value === "number" ? src.value : void 0;
|
|
901
907
|
const pricing_role = src.pricing_role === "utility" || src.pricing_role === "base" ? src.pricing_role : inheritRole;
|
|
902
908
|
const meta = src.meta && typeof src.meta === "object" ? src.meta : void 0;
|
|
909
|
+
const children = Array.isArray(src.children) ? src.children.map((child) => coerceOption(child, pricing_role)) : void 0;
|
|
903
910
|
const option = {
|
|
904
911
|
id: "",
|
|
905
912
|
label: "",
|
|
@@ -908,7 +915,8 @@ function coerceOption(src, inheritRole) {
|
|
|
908
915
|
...value !== void 0 && { value },
|
|
909
916
|
...service_id !== void 0 && { service_id },
|
|
910
917
|
pricing_role,
|
|
911
|
-
...meta && { meta }
|
|
918
|
+
...meta && { meta },
|
|
919
|
+
...children && children.length && { children }
|
|
912
920
|
};
|
|
913
921
|
return option;
|
|
914
922
|
}
|
|
@@ -973,6 +981,35 @@ function toStringArrayMap(src) {
|
|
|
973
981
|
}
|
|
974
982
|
return Object.keys(out).length ? out : void 0;
|
|
975
983
|
}
|
|
984
|
+
function toOptionEffectMap(src) {
|
|
985
|
+
var _a, _b;
|
|
986
|
+
if (!src || typeof src !== "object") return void 0;
|
|
987
|
+
const out = {};
|
|
988
|
+
for (const [triggerId, rawTargets] of Object.entries(src)) {
|
|
989
|
+
if (!triggerId || !rawTargets || typeof rawTargets !== "object") {
|
|
990
|
+
continue;
|
|
991
|
+
}
|
|
992
|
+
const targets = {};
|
|
993
|
+
for (const [fieldId, rawEffect] of Object.entries(rawTargets)) {
|
|
994
|
+
if (!fieldId || !rawEffect || typeof rawEffect !== "object") {
|
|
995
|
+
continue;
|
|
996
|
+
}
|
|
997
|
+
const effect = rawEffect;
|
|
998
|
+
const include2 = toStringArray(effect.include);
|
|
999
|
+
const exclude2 = toStringArray(effect.exclude);
|
|
1000
|
+
const next = {
|
|
1001
|
+
...effect.forceVisible === true ? { forceVisible: true } : {},
|
|
1002
|
+
...include2.length ? { include: dedupe(include2) } : {},
|
|
1003
|
+
...exclude2.length ? { exclude: dedupe(exclude2) } : {}
|
|
1004
|
+
};
|
|
1005
|
+
if (next.forceVisible === true || ((_a = next.include) == null ? void 0 : _a.length) || ((_b = next.exclude) == null ? void 0 : _b.length)) {
|
|
1006
|
+
targets[fieldId] = next;
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
if (Object.keys(targets).length) out[triggerId] = targets;
|
|
1010
|
+
}
|
|
1011
|
+
return Object.keys(out).length ? out : void 0;
|
|
1012
|
+
}
|
|
976
1013
|
function toStringArray(v) {
|
|
977
1014
|
if (!Array.isArray(v)) return [];
|
|
978
1015
|
return v.map((x) => String(x)).filter((s) => !!s && s.trim().length > 0);
|
|
@@ -1047,6 +1084,72 @@ function normalizeFieldValidation(input) {
|
|
|
1047
1084
|
return one ? [one] : void 0;
|
|
1048
1085
|
}
|
|
1049
1086
|
|
|
1087
|
+
// src/core/options.ts
|
|
1088
|
+
function walkFieldOptions(field) {
|
|
1089
|
+
const out = [];
|
|
1090
|
+
const visit = (options, depth, parentId) => {
|
|
1091
|
+
for (const option of options != null ? options : []) {
|
|
1092
|
+
out.push({
|
|
1093
|
+
field,
|
|
1094
|
+
fieldId: field.id,
|
|
1095
|
+
option,
|
|
1096
|
+
optionId: option.id,
|
|
1097
|
+
depth,
|
|
1098
|
+
parentId
|
|
1099
|
+
});
|
|
1100
|
+
visit(option.children, depth + 1, option.id);
|
|
1101
|
+
}
|
|
1102
|
+
};
|
|
1103
|
+
visit(field.options, 0);
|
|
1104
|
+
return out;
|
|
1105
|
+
}
|
|
1106
|
+
function fieldOptionIds(field) {
|
|
1107
|
+
return walkFieldOptions(field).map((visit) => visit.optionId);
|
|
1108
|
+
}
|
|
1109
|
+
function fieldOptionIdSet(field) {
|
|
1110
|
+
return new Set(fieldOptionIds(field));
|
|
1111
|
+
}
|
|
1112
|
+
function findFieldOption(field, optionId) {
|
|
1113
|
+
var _a;
|
|
1114
|
+
if (!field) return void 0;
|
|
1115
|
+
return (_a = walkFieldOptions(field).find((visit) => visit.optionId === optionId)) == null ? void 0 : _a.option;
|
|
1116
|
+
}
|
|
1117
|
+
function findOptionOwnerField(fields, optionId) {
|
|
1118
|
+
for (const field of fields) {
|
|
1119
|
+
if (findFieldOption(field, optionId)) return field;
|
|
1120
|
+
}
|
|
1121
|
+
return void 0;
|
|
1122
|
+
}
|
|
1123
|
+
function optionOwnerMap(fields) {
|
|
1124
|
+
const out = /* @__PURE__ */ new Map();
|
|
1125
|
+
for (const field of fields) {
|
|
1126
|
+
for (const visit of walkFieldOptions(field)) {
|
|
1127
|
+
if (!out.has(visit.optionId)) {
|
|
1128
|
+
out.set(visit.optionId, {
|
|
1129
|
+
fieldId: field.id,
|
|
1130
|
+
option: visit.option
|
|
1131
|
+
});
|
|
1132
|
+
}
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1135
|
+
return out;
|
|
1136
|
+
}
|
|
1137
|
+
function filterFieldOptionsById(options, allowed) {
|
|
1138
|
+
if (!Array.isArray(options)) return void 0;
|
|
1139
|
+
const out = [];
|
|
1140
|
+
for (const option of options) {
|
|
1141
|
+
const children = filterFieldOptionsById(option.children, allowed);
|
|
1142
|
+
if (!allowed.has(option.id) && (!children || children.length === 0)) {
|
|
1143
|
+
continue;
|
|
1144
|
+
}
|
|
1145
|
+
out.push({
|
|
1146
|
+
...option,
|
|
1147
|
+
...children ? { children } : {}
|
|
1148
|
+
});
|
|
1149
|
+
}
|
|
1150
|
+
return out;
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1050
1153
|
// src/core/validate/shared.ts
|
|
1051
1154
|
function isFiniteNumber(v) {
|
|
1052
1155
|
return typeof v === "number" && Number.isFinite(v);
|
|
@@ -1055,8 +1158,9 @@ function isServiceIdRef(v) {
|
|
|
1055
1158
|
return typeof v === "string" && v.trim().length > 0 || typeof v === "number" && Number.isFinite(v);
|
|
1056
1159
|
}
|
|
1057
1160
|
function hasAnyServiceOption(f) {
|
|
1058
|
-
|
|
1059
|
-
|
|
1161
|
+
return walkFieldOptions(f).some(
|
|
1162
|
+
(visit) => isServiceIdRef(visit.option.service_id)
|
|
1163
|
+
);
|
|
1060
1164
|
}
|
|
1061
1165
|
function getByPath(obj, path) {
|
|
1062
1166
|
if (!path) return void 0;
|
|
@@ -1145,14 +1249,14 @@ function withAffected(details, ids) {
|
|
|
1145
1249
|
|
|
1146
1250
|
// src/core/node-map.ts
|
|
1147
1251
|
function buildNodeMap(props) {
|
|
1148
|
-
var _a, _b
|
|
1252
|
+
var _a, _b;
|
|
1149
1253
|
const map = /* @__PURE__ */ new Map();
|
|
1150
1254
|
for (const t of (_a = props.filters) != null ? _a : []) {
|
|
1151
1255
|
if (!map.has(t.id)) map.set(t.id, { kind: "tag", id: t.id, node: t });
|
|
1152
1256
|
}
|
|
1153
1257
|
for (const f of (_b = props.fields) != null ? _b : []) {
|
|
1154
1258
|
if (!map.has(f.id)) map.set(f.id, { kind: "field", id: f.id, node: f });
|
|
1155
|
-
for (const o of (
|
|
1259
|
+
for (const { option: o } of walkFieldOptions(f)) {
|
|
1156
1260
|
if (!map.has(o.id))
|
|
1157
1261
|
map.set(o.id, {
|
|
1158
1262
|
kind: "option",
|
|
@@ -1165,12 +1269,6 @@ function buildNodeMap(props) {
|
|
|
1165
1269
|
return map;
|
|
1166
1270
|
}
|
|
1167
1271
|
function resolveTrigger(trigger, nodeMap) {
|
|
1168
|
-
const idx = trigger.indexOf("::");
|
|
1169
|
-
if (idx !== -1) {
|
|
1170
|
-
const fieldId = trigger.slice(0, idx);
|
|
1171
|
-
const optionId = trigger.slice(idx + 2);
|
|
1172
|
-
return { kind: "composite", triggerKey: trigger, fieldId, optionId };
|
|
1173
|
-
}
|
|
1174
1272
|
const direct = nodeMap.get(trigger);
|
|
1175
1273
|
if (!direct) return void 0;
|
|
1176
1274
|
if (direct.kind === "option") {
|
|
@@ -1222,11 +1320,6 @@ function visibleFieldIdsUnder(props, tagId, opts = {}) {
|
|
|
1222
1320
|
const ownerDepthForTriggerKey = (triggerKey) => {
|
|
1223
1321
|
const t = resolveTrigger(triggerKey, nodeMap);
|
|
1224
1322
|
if (!t) return void 0;
|
|
1225
|
-
if (t.kind === "composite") {
|
|
1226
|
-
const f = fieldById.get(t.fieldId);
|
|
1227
|
-
if (!f) return void 0;
|
|
1228
|
-
return ownerDepthForField(f);
|
|
1229
|
-
}
|
|
1230
1323
|
if (t.kind === "field") {
|
|
1231
1324
|
const f = fieldById.get(t.id);
|
|
1232
1325
|
if (!f || f.button !== true) return void 0;
|
|
@@ -1309,6 +1402,84 @@ function visibleFieldsUnder(props, tagId, opts = {}) {
|
|
|
1309
1402
|
const fieldById = new Map(((_a = props.fields) != null ? _a : []).map((f) => [f.id, f]));
|
|
1310
1403
|
return ids.map((id) => fieldById.get(id)).filter(Boolean);
|
|
1311
1404
|
}
|
|
1405
|
+
function resolveVisibility(props, tagId, selectedKeys) {
|
|
1406
|
+
var _a, _b, _c, _d;
|
|
1407
|
+
const selected = new Set(selectedKeys != null ? selectedKeys : []);
|
|
1408
|
+
const baseFieldIds = visibleFieldIdsUnder(props, tagId, { selectedKeys: selected });
|
|
1409
|
+
const fieldById = new Map(((_a = props.fields) != null ? _a : []).map((field) => [field.id, field]));
|
|
1410
|
+
const visible = new Set(baseFieldIds);
|
|
1411
|
+
const forced = /* @__PURE__ */ new Set();
|
|
1412
|
+
const optionsByFieldId = {};
|
|
1413
|
+
const optionIdsByFieldId = /* @__PURE__ */ new Map();
|
|
1414
|
+
const getOptionIds = (field) => {
|
|
1415
|
+
let ids = optionIdsByFieldId.get(field.id);
|
|
1416
|
+
if (!ids) {
|
|
1417
|
+
ids = fieldOptionIds(field);
|
|
1418
|
+
optionIdsByFieldId.set(field.id, ids);
|
|
1419
|
+
}
|
|
1420
|
+
return ids;
|
|
1421
|
+
};
|
|
1422
|
+
const ensureOptions = (field) => {
|
|
1423
|
+
const ids = getOptionIds(field);
|
|
1424
|
+
if (!ids.length) return void 0;
|
|
1425
|
+
if (!optionsByFieldId[field.id]) optionsByFieldId[field.id] = [...ids];
|
|
1426
|
+
return optionsByFieldId[field.id];
|
|
1427
|
+
};
|
|
1428
|
+
for (const fieldId of baseFieldIds) {
|
|
1429
|
+
const field = fieldById.get(fieldId);
|
|
1430
|
+
if (field) ensureOptions(field);
|
|
1431
|
+
}
|
|
1432
|
+
const effects = (_b = props.option_effects_for_buttons) != null ? _b : {};
|
|
1433
|
+
for (const triggerId of selected) {
|
|
1434
|
+
const targetRules = effects[triggerId];
|
|
1435
|
+
if (!targetRules) continue;
|
|
1436
|
+
for (const [targetFieldId, rule] of Object.entries(targetRules)) {
|
|
1437
|
+
const field = fieldById.get(targetFieldId);
|
|
1438
|
+
if (!field) continue;
|
|
1439
|
+
const isVisible = visible.has(targetFieldId);
|
|
1440
|
+
if (!isVisible && rule.forceVisible !== true) continue;
|
|
1441
|
+
if (!isVisible && rule.forceVisible === true) {
|
|
1442
|
+
visible.add(targetFieldId);
|
|
1443
|
+
forced.add(targetFieldId);
|
|
1444
|
+
}
|
|
1445
|
+
const orderedOptionIds = getOptionIds(field);
|
|
1446
|
+
if (!orderedOptionIds.length) continue;
|
|
1447
|
+
const known = new Set(orderedOptionIds);
|
|
1448
|
+
let allowed = (_c = optionsByFieldId[targetFieldId]) != null ? _c : [...orderedOptionIds];
|
|
1449
|
+
if (Array.isArray(rule.include) && rule.include.length) {
|
|
1450
|
+
const include2 = new Set(
|
|
1451
|
+
rule.include.filter((optionId) => known.has(optionId))
|
|
1452
|
+
);
|
|
1453
|
+
allowed = orderedOptionIds.filter(
|
|
1454
|
+
(optionId) => include2.has(optionId) && allowed.includes(optionId)
|
|
1455
|
+
);
|
|
1456
|
+
}
|
|
1457
|
+
if (Array.isArray(rule.exclude) && rule.exclude.length) {
|
|
1458
|
+
const exclude2 = new Set(
|
|
1459
|
+
rule.exclude.filter((optionId) => known.has(optionId))
|
|
1460
|
+
);
|
|
1461
|
+
allowed = allowed.filter((optionId) => !exclude2.has(optionId));
|
|
1462
|
+
}
|
|
1463
|
+
optionsByFieldId[targetFieldId] = allowed;
|
|
1464
|
+
}
|
|
1465
|
+
}
|
|
1466
|
+
const visibleFieldIds = baseFieldIds.filter((fieldId) => visible.has(fieldId));
|
|
1467
|
+
const seen = new Set(visibleFieldIds);
|
|
1468
|
+
for (const field of (_d = props.fields) != null ? _d : []) {
|
|
1469
|
+
if (!visible.has(field.id) || seen.has(field.id)) continue;
|
|
1470
|
+
seen.add(field.id);
|
|
1471
|
+
visibleFieldIds.push(field.id);
|
|
1472
|
+
ensureOptions(field);
|
|
1473
|
+
}
|
|
1474
|
+
for (const fieldId of Object.keys(optionsByFieldId)) {
|
|
1475
|
+
if (!visible.has(fieldId)) delete optionsByFieldId[fieldId];
|
|
1476
|
+
}
|
|
1477
|
+
return {
|
|
1478
|
+
fieldIds: visibleFieldIds,
|
|
1479
|
+
optionsByFieldId,
|
|
1480
|
+
forcedFieldIds: visibleFieldIds.filter((fieldId) => forced.has(fieldId))
|
|
1481
|
+
};
|
|
1482
|
+
}
|
|
1312
1483
|
|
|
1313
1484
|
// src/core/validate/steps/visibility.ts
|
|
1314
1485
|
function createFieldsVisibleUnder(v) {
|
|
@@ -1326,7 +1497,6 @@ function resolveRootTags(tags) {
|
|
|
1326
1497
|
return roots.length ? roots : tags.slice(0, 1);
|
|
1327
1498
|
}
|
|
1328
1499
|
function collectSelectableTriggersInContext(v, tagId, selectedKeys, effectfulKeys) {
|
|
1329
|
-
var _a;
|
|
1330
1500
|
const visible = visibleFieldsUnder(v.props, tagId, {
|
|
1331
1501
|
selectedKeys
|
|
1332
1502
|
});
|
|
@@ -1336,7 +1506,7 @@ function collectSelectableTriggersInContext(v, tagId, selectedKeys, effectfulKey
|
|
|
1336
1506
|
const t = f.id;
|
|
1337
1507
|
if (effectfulKeys.has(t)) triggers.push(t);
|
|
1338
1508
|
}
|
|
1339
|
-
for (const o of (
|
|
1509
|
+
for (const { option: o } of walkFieldOptions(f)) {
|
|
1340
1510
|
const t = o.id;
|
|
1341
1511
|
if (effectfulKeys.has(t)) triggers.push(t);
|
|
1342
1512
|
}
|
|
@@ -1345,7 +1515,7 @@ function collectSelectableTriggersInContext(v, tagId, selectedKeys, effectfulKey
|
|
|
1345
1515
|
return triggers;
|
|
1346
1516
|
}
|
|
1347
1517
|
function runVisibilityRulesOnce(v) {
|
|
1348
|
-
var _a, _b, _c, _d
|
|
1518
|
+
var _a, _b, _c, _d;
|
|
1349
1519
|
for (const t of v.tags) {
|
|
1350
1520
|
const visible = v.fieldsVisibleUnder(t.id);
|
|
1351
1521
|
const seen = /* @__PURE__ */ new Map();
|
|
@@ -1395,9 +1565,9 @@ function runVisibilityRulesOnce(v) {
|
|
|
1395
1565
|
let hasUtility = false;
|
|
1396
1566
|
const utilityOptionIds = [];
|
|
1397
1567
|
for (const f of visible) {
|
|
1398
|
-
for (const o of (
|
|
1568
|
+
for (const { option: o } of walkFieldOptions(f)) {
|
|
1399
1569
|
if (!isServiceIdRef(o.service_id)) continue;
|
|
1400
|
-
const role = (
|
|
1570
|
+
const role = (_d = (_c = o.pricing_role) != null ? _c : f.pricing_role) != null ? _d : "base";
|
|
1401
1571
|
if (role === "base") hasBase = true;
|
|
1402
1572
|
else if (role === "utility") {
|
|
1403
1573
|
hasUtility = true;
|
|
@@ -1438,7 +1608,7 @@ function dedupeErrorsInPlace(v, startIndex) {
|
|
|
1438
1608
|
v.errors.splice(startIndex, v.errors.length - startIndex, ...kept);
|
|
1439
1609
|
}
|
|
1440
1610
|
function validateVisibility(v, options = {}) {
|
|
1441
|
-
var _a, _b, _c, _d, _e;
|
|
1611
|
+
var _a, _b, _c, _d, _e, _f;
|
|
1442
1612
|
v.simulatedVisibilityContexts = [];
|
|
1443
1613
|
const simulate = options.simulate === true;
|
|
1444
1614
|
if (!simulate) {
|
|
@@ -1463,10 +1633,13 @@ function validateVisibility(v, options = {}) {
|
|
|
1463
1633
|
for (const key of Object.keys((_d = v.props.excludes_for_buttons) != null ? _d : {})) {
|
|
1464
1634
|
effectfulKeys.add(key);
|
|
1465
1635
|
}
|
|
1636
|
+
for (const key of Object.keys((_e = v.props.option_effects_for_buttons) != null ? _e : {})) {
|
|
1637
|
+
effectfulKeys.add(key);
|
|
1638
|
+
}
|
|
1466
1639
|
}
|
|
1467
1640
|
const roots = resolveRootTags(v.tags);
|
|
1468
1641
|
const rootTags = options.simulateAllRoots ? roots : roots.slice(0, 1);
|
|
1469
|
-
const originalSelected = new Set((
|
|
1642
|
+
const originalSelected = new Set((_f = v.selectedKeys) != null ? _f : []);
|
|
1470
1643
|
const errorsStart = v.errors.length;
|
|
1471
1644
|
const visited = /* @__PURE__ */ new Set();
|
|
1472
1645
|
const seenContexts = /* @__PURE__ */ new Set();
|
|
@@ -1607,7 +1780,7 @@ function validateStructure(v) {
|
|
|
1607
1780
|
|
|
1608
1781
|
// src/core/validate/steps/identity.ts
|
|
1609
1782
|
function validateIdentity(v) {
|
|
1610
|
-
var _a
|
|
1783
|
+
var _a;
|
|
1611
1784
|
const tags = v.tags;
|
|
1612
1785
|
const fields = v.fields;
|
|
1613
1786
|
{
|
|
@@ -1707,7 +1880,7 @@ function validateIdentity(v) {
|
|
|
1707
1880
|
}
|
|
1708
1881
|
}
|
|
1709
1882
|
for (const f of fields) {
|
|
1710
|
-
for (const o of (
|
|
1883
|
+
for (const { option: o } of walkFieldOptions(f)) {
|
|
1711
1884
|
if (!o.label || !o.label.trim()) {
|
|
1712
1885
|
v.errors.push({
|
|
1713
1886
|
code: "label_missing",
|
|
@@ -1722,25 +1895,11 @@ function validateIdentity(v) {
|
|
|
1722
1895
|
}
|
|
1723
1896
|
|
|
1724
1897
|
// src/core/validate/steps/option-maps.ts
|
|
1725
|
-
function parseFieldOptionKey(key) {
|
|
1726
|
-
const idx = key.indexOf("::");
|
|
1727
|
-
if (idx === -1) return null;
|
|
1728
|
-
const fieldId = key.slice(0, idx).trim();
|
|
1729
|
-
const optionId = key.slice(idx + 2).trim();
|
|
1730
|
-
if (!fieldId || !optionId) return null;
|
|
1731
|
-
return { fieldId, optionId };
|
|
1732
|
-
}
|
|
1733
|
-
function hasOption(v, fid, oid) {
|
|
1734
|
-
var _a;
|
|
1735
|
-
const f = v.fieldById.get(fid);
|
|
1736
|
-
if (!f) return false;
|
|
1737
|
-
return !!((_a = f.options) != null ? _a : []).find((o) => o.id === oid);
|
|
1738
|
-
}
|
|
1739
1898
|
function validateOptionMaps(v) {
|
|
1740
|
-
var _a, _b;
|
|
1899
|
+
var _a, _b, _c;
|
|
1741
1900
|
const incMap = (_a = v.props.includes_for_buttons) != null ? _a : {};
|
|
1742
1901
|
const excMap = (_b = v.props.excludes_for_buttons) != null ? _b : {};
|
|
1743
|
-
const badKeyMessage = (key) => `Invalid trigger-map key "${key}". Expected a known
|
|
1902
|
+
const badKeyMessage = (key) => `Invalid trigger-map key "${key}". Expected a known option id or button-field id.`;
|
|
1744
1903
|
const validateTriggerKey = (key) => {
|
|
1745
1904
|
const ref = v.nodeMap.get(key);
|
|
1746
1905
|
if (ref) {
|
|
@@ -1759,19 +1918,7 @@ function validateOptionMaps(v) {
|
|
|
1759
1918
|
}
|
|
1760
1919
|
return { ok: false, nodeId: ref.id, affected: [ref.id] };
|
|
1761
1920
|
}
|
|
1762
|
-
|
|
1763
|
-
if (!p) return { ok: false };
|
|
1764
|
-
if (!hasOption(v, p.fieldId, p.optionId))
|
|
1765
|
-
return {
|
|
1766
|
-
ok: false,
|
|
1767
|
-
nodeId: p.fieldId,
|
|
1768
|
-
affected: [p.fieldId, p.optionId]
|
|
1769
|
-
};
|
|
1770
|
-
return {
|
|
1771
|
-
ok: true,
|
|
1772
|
-
nodeId: p.fieldId,
|
|
1773
|
-
affected: [p.fieldId, p.optionId]
|
|
1774
|
-
};
|
|
1921
|
+
return { ok: false };
|
|
1775
1922
|
};
|
|
1776
1923
|
for (const k of Object.keys(incMap)) {
|
|
1777
1924
|
const r = validateTriggerKey(k);
|
|
@@ -1797,6 +1944,57 @@ function validateOptionMaps(v) {
|
|
|
1797
1944
|
});
|
|
1798
1945
|
}
|
|
1799
1946
|
}
|
|
1947
|
+
const effectMap = (_c = v.props.option_effects_for_buttons) != null ? _c : {};
|
|
1948
|
+
for (const [triggerKey, targets] of Object.entries(effectMap)) {
|
|
1949
|
+
const trigger = validateTriggerKey(triggerKey);
|
|
1950
|
+
if (!trigger.ok) {
|
|
1951
|
+
v.errors.push({
|
|
1952
|
+
code: "bad_option_effect_key",
|
|
1953
|
+
severity: "error",
|
|
1954
|
+
message: badKeyMessage(triggerKey),
|
|
1955
|
+
nodeId: trigger.nodeId,
|
|
1956
|
+
details: withAffected({ key: triggerKey }, trigger.affected)
|
|
1957
|
+
});
|
|
1958
|
+
}
|
|
1959
|
+
for (const [targetFieldId, effect] of Object.entries(targets != null ? targets : {})) {
|
|
1960
|
+
const field = v.fieldById.get(targetFieldId);
|
|
1961
|
+
if (!field) {
|
|
1962
|
+
v.errors.push({
|
|
1963
|
+
code: "bad_option_effect_target",
|
|
1964
|
+
severity: "error",
|
|
1965
|
+
message: `Option effect trigger "${triggerKey}" targets unknown field "${targetFieldId}".`,
|
|
1966
|
+
details: withAffected(
|
|
1967
|
+
{ key: triggerKey, targetFieldId },
|
|
1968
|
+
trigger.affected
|
|
1969
|
+
)
|
|
1970
|
+
});
|
|
1971
|
+
continue;
|
|
1972
|
+
}
|
|
1973
|
+
const validOptionIds = fieldOptionIdSet(field);
|
|
1974
|
+
const checkTargetOptions = (kind, optionIds) => {
|
|
1975
|
+
for (const optionId of optionIds != null ? optionIds : []) {
|
|
1976
|
+
if (validOptionIds.has(optionId)) continue;
|
|
1977
|
+
v.errors.push({
|
|
1978
|
+
code: "bad_option_effect_option",
|
|
1979
|
+
severity: "error",
|
|
1980
|
+
message: `Option effect trigger "${triggerKey}" references unknown ${kind} option "${optionId}" for field "${targetFieldId}".`,
|
|
1981
|
+
nodeId: targetFieldId,
|
|
1982
|
+
details: withAffected(
|
|
1983
|
+
{
|
|
1984
|
+
key: triggerKey,
|
|
1985
|
+
targetFieldId,
|
|
1986
|
+
optionId,
|
|
1987
|
+
kind
|
|
1988
|
+
},
|
|
1989
|
+
[targetFieldId, optionId]
|
|
1990
|
+
)
|
|
1991
|
+
});
|
|
1992
|
+
}
|
|
1993
|
+
};
|
|
1994
|
+
checkTargetOptions("include", effect == null ? void 0 : effect.include);
|
|
1995
|
+
checkTargetOptions("exclude", effect == null ? void 0 : effect.exclude);
|
|
1996
|
+
}
|
|
1997
|
+
}
|
|
1800
1998
|
for (const k of Object.keys(incMap)) {
|
|
1801
1999
|
if (!(k in excMap)) continue;
|
|
1802
2000
|
const r = validateTriggerKey(k);
|
|
@@ -1810,27 +2008,231 @@ function validateOptionMaps(v) {
|
|
|
1810
2008
|
}
|
|
1811
2009
|
}
|
|
1812
2010
|
|
|
1813
|
-
// src/
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
const
|
|
1817
|
-
if (
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
2011
|
+
// src/core/validate/steps/visibility-cycles.ts
|
|
2012
|
+
var MAX_VISIBILITY_CYCLE_DEPTH = 20;
|
|
2013
|
+
function validateVisibilityCycles(v) {
|
|
2014
|
+
const triggerById = buildTriggerIndex(v.fields);
|
|
2015
|
+
if (!triggerById.size) return;
|
|
2016
|
+
const fieldTriggers = buildFieldTriggerIndex(v.fields);
|
|
2017
|
+
const revealTargetsByTrigger = buildRevealIndex(v, triggerById);
|
|
2018
|
+
const reported = /* @__PURE__ */ new Set();
|
|
2019
|
+
for (const rootTriggerId of Array.from(triggerById.keys()).sort()) {
|
|
2020
|
+
const required = makeRequiredState(triggerById, [rootTriggerId]);
|
|
2021
|
+
walkFromTrigger({
|
|
2022
|
+
v,
|
|
2023
|
+
triggerById,
|
|
2024
|
+
fieldTriggers,
|
|
2025
|
+
revealTargetsByTrigger,
|
|
2026
|
+
rootTriggerId,
|
|
2027
|
+
currentTriggerId: rootTriggerId,
|
|
2028
|
+
required,
|
|
2029
|
+
path: [rootTriggerId],
|
|
2030
|
+
visited: /* @__PURE__ */ new Set(),
|
|
2031
|
+
reported,
|
|
2032
|
+
depth: 0
|
|
2033
|
+
});
|
|
2034
|
+
}
|
|
2035
|
+
}
|
|
2036
|
+
function buildTriggerIndex(fields) {
|
|
2037
|
+
const out = /* @__PURE__ */ new Map();
|
|
2038
|
+
const owners = optionOwnerMap(fields);
|
|
2039
|
+
for (const field of fields) {
|
|
2040
|
+
if (field.button === true) {
|
|
2041
|
+
out.set(field.id, {
|
|
2042
|
+
kind: "field",
|
|
2043
|
+
id: field.id,
|
|
2044
|
+
ownerFieldId: field.id
|
|
2045
|
+
});
|
|
2046
|
+
}
|
|
2047
|
+
}
|
|
2048
|
+
for (const [optionId, owner] of owners) {
|
|
2049
|
+
out.set(optionId, {
|
|
2050
|
+
kind: "option",
|
|
2051
|
+
id: optionId,
|
|
2052
|
+
ownerFieldId: owner.fieldId
|
|
2053
|
+
});
|
|
2054
|
+
}
|
|
2055
|
+
return out;
|
|
2056
|
+
}
|
|
2057
|
+
function buildFieldTriggerIndex(fields) {
|
|
2058
|
+
const out = /* @__PURE__ */ new Map();
|
|
2059
|
+
for (const field of fields) {
|
|
2060
|
+
const triggers = [];
|
|
2061
|
+
if (field.button === true) triggers.push(field.id);
|
|
2062
|
+
for (const visit of walkFieldOptions(field)) {
|
|
2063
|
+
triggers.push(visit.optionId);
|
|
2064
|
+
}
|
|
2065
|
+
out.set(field.id, triggers);
|
|
2066
|
+
}
|
|
2067
|
+
return out;
|
|
2068
|
+
}
|
|
2069
|
+
function buildRevealIndex(v, triggerById) {
|
|
2070
|
+
var _a, _b;
|
|
2071
|
+
const out = /* @__PURE__ */ new Map();
|
|
2072
|
+
const addReveal = (triggerId, targetFieldId) => {
|
|
2073
|
+
var _a2;
|
|
2074
|
+
if (!triggerById.has(triggerId)) return;
|
|
2075
|
+
if (!v.fieldById.has(targetFieldId)) return;
|
|
2076
|
+
const set = (_a2 = out.get(triggerId)) != null ? _a2 : /* @__PURE__ */ new Set();
|
|
2077
|
+
set.add(targetFieldId);
|
|
2078
|
+
out.set(triggerId, set);
|
|
2079
|
+
};
|
|
2080
|
+
for (const [triggerId, targetIds] of Object.entries(
|
|
2081
|
+
(_a = v.props.includes_for_buttons) != null ? _a : {}
|
|
2082
|
+
)) {
|
|
2083
|
+
for (const targetId of targetIds != null ? targetIds : []) addReveal(triggerId, targetId);
|
|
2084
|
+
}
|
|
2085
|
+
for (const [triggerId, targets] of Object.entries(
|
|
2086
|
+
(_b = v.props.option_effects_for_buttons) != null ? _b : {}
|
|
2087
|
+
)) {
|
|
2088
|
+
for (const [targetFieldId, effect] of Object.entries(targets != null ? targets : {})) {
|
|
2089
|
+
if ((effect == null ? void 0 : effect.forceVisible) === true)
|
|
2090
|
+
addReveal(triggerId, targetFieldId);
|
|
2091
|
+
}
|
|
2092
|
+
}
|
|
2093
|
+
return new Map(
|
|
2094
|
+
Array.from(out.entries()).map(([triggerId, fieldIds]) => [
|
|
2095
|
+
triggerId,
|
|
2096
|
+
Array.from(fieldIds).sort()
|
|
2097
|
+
])
|
|
2098
|
+
);
|
|
2099
|
+
}
|
|
2100
|
+
function walkFromTrigger(args) {
|
|
2101
|
+
var _a, _b, _c;
|
|
2102
|
+
if (args.depth >= MAX_VISIBILITY_CYCLE_DEPTH) return;
|
|
2103
|
+
const visitedKey = `${args.rootTriggerId}::${args.currentTriggerId}::${args.path.join(">")}`;
|
|
2104
|
+
if (args.visited.has(visitedKey)) return;
|
|
2105
|
+
args.visited.add(visitedKey);
|
|
2106
|
+
const revealedFieldIds = (_a = args.revealTargetsByTrigger.get(args.currentTriggerId)) != null ? _a : [];
|
|
2107
|
+
for (const revealedFieldId of revealedFieldIds) {
|
|
2108
|
+
const reachableTriggers = (_c = (_b = args.fieldTriggers.get(revealedFieldId)) == null ? void 0 : _b.slice().sort()) != null ? _c : [];
|
|
2109
|
+
for (const reachableTriggerId of reachableTriggers) {
|
|
2110
|
+
const invalidation = invalidatesRequiredPath(
|
|
2111
|
+
args.v,
|
|
2112
|
+
args.triggerById,
|
|
2113
|
+
reachableTriggerId,
|
|
2114
|
+
args.required
|
|
2115
|
+
);
|
|
2116
|
+
if (invalidation) {
|
|
2117
|
+
emitCycleError({
|
|
2118
|
+
v: args.v,
|
|
2119
|
+
rootTriggerId: args.rootTriggerId,
|
|
2120
|
+
revealedFieldId,
|
|
2121
|
+
conflictingTriggerId: reachableTriggerId,
|
|
2122
|
+
invalidatedId: invalidation.invalidatedId,
|
|
2123
|
+
path: [...args.path, reachableTriggerId],
|
|
2124
|
+
reported: args.reported
|
|
2125
|
+
});
|
|
2126
|
+
}
|
|
2127
|
+
if (args.path.includes(reachableTriggerId)) continue;
|
|
2128
|
+
walkFromTrigger({
|
|
2129
|
+
...args,
|
|
2130
|
+
currentTriggerId: reachableTriggerId,
|
|
2131
|
+
required: addRequiredTrigger(
|
|
2132
|
+
args.triggerById,
|
|
2133
|
+
args.required,
|
|
2134
|
+
reachableTriggerId
|
|
2135
|
+
),
|
|
2136
|
+
path: [...args.path, reachableTriggerId],
|
|
2137
|
+
depth: args.depth + 1
|
|
2138
|
+
});
|
|
2139
|
+
}
|
|
2140
|
+
}
|
|
2141
|
+
}
|
|
2142
|
+
function makeRequiredState(triggerById, triggerIds) {
|
|
2143
|
+
let required = {
|
|
2144
|
+
triggers: /* @__PURE__ */ new Set(),
|
|
2145
|
+
ownerFields: /* @__PURE__ */ new Set()
|
|
2146
|
+
};
|
|
2147
|
+
for (const triggerId of triggerIds) {
|
|
2148
|
+
required = addRequiredTrigger(triggerById, required, triggerId);
|
|
2149
|
+
}
|
|
2150
|
+
return required;
|
|
2151
|
+
}
|
|
2152
|
+
function addRequiredTrigger(triggerById, current, triggerId) {
|
|
2153
|
+
const next = {
|
|
2154
|
+
triggers: new Set(current.triggers),
|
|
2155
|
+
ownerFields: new Set(current.ownerFields)
|
|
2156
|
+
};
|
|
2157
|
+
const trigger = triggerById.get(triggerId);
|
|
2158
|
+
if (!trigger) return next;
|
|
2159
|
+
next.triggers.add(triggerId);
|
|
2160
|
+
next.ownerFields.add(trigger.ownerFieldId);
|
|
2161
|
+
return next;
|
|
2162
|
+
}
|
|
2163
|
+
function invalidatesRequiredPath(v, triggerById, conflictingTriggerId, required) {
|
|
2164
|
+
var _a, _b, _c, _d, _e, _f;
|
|
2165
|
+
for (const targetId of (_b = (_a = v.props.excludes_for_buttons) == null ? void 0 : _a[conflictingTriggerId]) != null ? _b : []) {
|
|
2166
|
+
if (required.ownerFields.has(targetId)) {
|
|
2167
|
+
return { invalidatedId: targetId };
|
|
2168
|
+
}
|
|
2169
|
+
const targetTrigger = triggerById.get(targetId);
|
|
2170
|
+
if ((targetTrigger == null ? void 0 : targetTrigger.kind) === "option" && required.triggers.has(targetId)) {
|
|
2171
|
+
return { invalidatedId: targetId };
|
|
2172
|
+
}
|
|
2173
|
+
}
|
|
2174
|
+
const effects = (_d = (_c = v.props.option_effects_for_buttons) == null ? void 0 : _c[conflictingTriggerId]) != null ? _d : {};
|
|
2175
|
+
for (const [targetFieldId, effect] of Object.entries(effects)) {
|
|
2176
|
+
if (!v.fieldById.has(targetFieldId)) continue;
|
|
2177
|
+
if ((_e = effect == null ? void 0 : effect.exclude) == null ? void 0 : _e.length) {
|
|
2178
|
+
const excluded = new Set(effect.exclude);
|
|
2179
|
+
for (const requiredTriggerId of required.triggers) {
|
|
2180
|
+
const requiredTrigger = triggerById.get(requiredTriggerId);
|
|
2181
|
+
if ((requiredTrigger == null ? void 0 : requiredTrigger.kind) !== "option") continue;
|
|
2182
|
+
if (requiredTrigger.ownerFieldId !== targetFieldId) continue;
|
|
2183
|
+
if (excluded.has(requiredTriggerId)) {
|
|
2184
|
+
return { invalidatedId: requiredTriggerId };
|
|
2185
|
+
}
|
|
1824
2186
|
}
|
|
1825
2187
|
}
|
|
1826
|
-
if (
|
|
1827
|
-
const
|
|
1828
|
-
|
|
1829
|
-
|
|
2188
|
+
if ((_f = effect == null ? void 0 : effect.include) == null ? void 0 : _f.length) {
|
|
2189
|
+
const included = new Set(effect.include);
|
|
2190
|
+
for (const requiredTriggerId of required.triggers) {
|
|
2191
|
+
const requiredTrigger = triggerById.get(requiredTriggerId);
|
|
2192
|
+
if ((requiredTrigger == null ? void 0 : requiredTrigger.kind) !== "option") continue;
|
|
2193
|
+
if (requiredTrigger.ownerFieldId !== targetFieldId) continue;
|
|
2194
|
+
if (!included.has(requiredTriggerId)) {
|
|
2195
|
+
return { invalidatedId: requiredTriggerId };
|
|
2196
|
+
}
|
|
1830
2197
|
}
|
|
1831
2198
|
}
|
|
1832
|
-
return void 0;
|
|
1833
2199
|
}
|
|
2200
|
+
return void 0;
|
|
2201
|
+
}
|
|
2202
|
+
function emitCycleError(args) {
|
|
2203
|
+
const key = [
|
|
2204
|
+
args.rootTriggerId,
|
|
2205
|
+
args.conflictingTriggerId,
|
|
2206
|
+
args.invalidatedId,
|
|
2207
|
+
args.path.join(">")
|
|
2208
|
+
].join("::");
|
|
2209
|
+
if (args.reported.has(key)) return;
|
|
2210
|
+
args.reported.add(key);
|
|
2211
|
+
args.v.errors.push({
|
|
2212
|
+
code: "visibility_dependency_cycle",
|
|
2213
|
+
severity: "error",
|
|
2214
|
+
message: `Visibility dependency cycle: trigger "${args.rootTriggerId}" reveals "${args.revealedFieldId}", but reachable trigger "${args.conflictingTriggerId}" can hide or remove "${args.invalidatedId}".`,
|
|
2215
|
+
nodeId: args.conflictingTriggerId,
|
|
2216
|
+
details: withAffected(
|
|
2217
|
+
{
|
|
2218
|
+
rootTriggerId: args.rootTriggerId,
|
|
2219
|
+
conflictingTriggerId: args.conflictingTriggerId,
|
|
2220
|
+
invalidatedId: args.invalidatedId,
|
|
2221
|
+
path: args.path
|
|
2222
|
+
},
|
|
2223
|
+
[
|
|
2224
|
+
args.rootTriggerId,
|
|
2225
|
+
args.revealedFieldId,
|
|
2226
|
+
args.conflictingTriggerId,
|
|
2227
|
+
args.invalidatedId
|
|
2228
|
+
]
|
|
2229
|
+
)
|
|
2230
|
+
});
|
|
2231
|
+
}
|
|
2232
|
+
|
|
2233
|
+
// src/utils/order-kind.ts
|
|
2234
|
+
function normalizeSelectedTriggerKey(key, nodeMap) {
|
|
2235
|
+
if (!key) return void 0;
|
|
1834
2236
|
const ref = nodeMap.get(key);
|
|
1835
2237
|
if (!ref) return void 0;
|
|
1836
2238
|
if (ref.kind !== "field" && ref.kind !== "option") return void 0;
|
|
@@ -1989,8 +2391,7 @@ function validateUtilityMarkers(v) {
|
|
|
1989
2391
|
"percent"
|
|
1990
2392
|
]);
|
|
1991
2393
|
for (const f of v.fields) {
|
|
1992
|
-
const
|
|
1993
|
-
for (const o of optsArr) {
|
|
2394
|
+
for (const { option: o } of walkFieldOptions(f)) {
|
|
1994
2395
|
const role = (_b = (_a = o.pricing_role) != null ? _a : f.pricing_role) != null ? _b : "base";
|
|
1995
2396
|
const hasService = isServiceIdRef(o.service_id);
|
|
1996
2397
|
const util = (_c = o.meta) == null ? void 0 : _c.utility;
|
|
@@ -2226,13 +2627,13 @@ function normalizeServiceRef(value) {
|
|
|
2226
2627
|
|
|
2227
2628
|
// src/core/validate/steps/rates.ts
|
|
2228
2629
|
function validateRates(v) {
|
|
2229
|
-
var _a, _b
|
|
2630
|
+
var _a, _b;
|
|
2230
2631
|
const ratePolicy = normalizeRatePolicy(v.options.ratePolicy);
|
|
2231
2632
|
for (const f of v.fields) {
|
|
2232
2633
|
if (!isMultiField(f)) continue;
|
|
2233
2634
|
const baseRates = [];
|
|
2234
|
-
for (const o of (
|
|
2235
|
-
const role = (
|
|
2635
|
+
for (const { option: o } of walkFieldOptions(f)) {
|
|
2636
|
+
const role = (_b = (_a = o.pricing_role) != null ? _a : f.pricing_role) != null ? _b : "base";
|
|
2236
2637
|
if (role !== "base") continue;
|
|
2237
2638
|
const sid = o.service_id;
|
|
2238
2639
|
if (!isServiceIdRef(sid)) continue;
|
|
@@ -2643,7 +3044,7 @@ function effectiveConstraints(v, tagId) {
|
|
|
2643
3044
|
return out;
|
|
2644
3045
|
}
|
|
2645
3046
|
function validateConstraints(v) {
|
|
2646
|
-
var _a
|
|
3047
|
+
var _a;
|
|
2647
3048
|
for (const t of v.tags) {
|
|
2648
3049
|
const eff = effectiveConstraints(v, t.id);
|
|
2649
3050
|
const hasAnyRequired = Object.values(eff).some(
|
|
@@ -2652,7 +3053,7 @@ function validateConstraints(v) {
|
|
|
2652
3053
|
if (!hasAnyRequired) continue;
|
|
2653
3054
|
const visible = v.fieldsVisibleUnder(t.id);
|
|
2654
3055
|
for (const f of visible) {
|
|
2655
|
-
for (const o of (
|
|
3056
|
+
for (const { option: o } of walkFieldOptions(f)) {
|
|
2656
3057
|
if (!isServiceIdRef(o.service_id)) continue;
|
|
2657
3058
|
const svc = getServiceCapability(v.serviceMap, o.service_id);
|
|
2658
3059
|
if (!svc || typeof svc !== "object") continue;
|
|
@@ -2706,7 +3107,7 @@ function validateConstraints(v) {
|
|
|
2706
3107
|
if (!row) continue;
|
|
2707
3108
|
const from = row.from === true;
|
|
2708
3109
|
const to = row.to === true;
|
|
2709
|
-
const origin = String((
|
|
3110
|
+
const origin = String((_a = row.origin) != null ? _a : "");
|
|
2710
3111
|
v.errors.push({
|
|
2711
3112
|
code: "constraint_overridden",
|
|
2712
3113
|
severity: "warning",
|
|
@@ -2740,14 +3141,14 @@ function validateCustomFields(v) {
|
|
|
2740
3141
|
|
|
2741
3142
|
// src/core/validate/steps/global-utility-guard.ts
|
|
2742
3143
|
function validateGlobalUtilityGuard(v) {
|
|
2743
|
-
var _a, _b
|
|
3144
|
+
var _a, _b;
|
|
2744
3145
|
if (!v.options.globalUtilityGuard) return;
|
|
2745
3146
|
let hasUtility = false;
|
|
2746
3147
|
let hasBase = false;
|
|
2747
3148
|
for (const f of v.fields) {
|
|
2748
|
-
for (const o of (
|
|
3149
|
+
for (const { option: o } of walkFieldOptions(f)) {
|
|
2749
3150
|
if (!isServiceIdRef(o.service_id)) continue;
|
|
2750
|
-
const role = (
|
|
3151
|
+
const role = (_b = (_a = o.pricing_role) != null ? _a : f.pricing_role) != null ? _b : "base";
|
|
2751
3152
|
if (role === "base") hasBase = true;
|
|
2752
3153
|
else if (role === "utility") hasUtility = true;
|
|
2753
3154
|
if (hasUtility && hasBase) break;
|
|
@@ -2949,7 +3350,7 @@ function applyFilterAllowLists(tagId, fieldId, filter) {
|
|
|
2949
3350
|
return true;
|
|
2950
3351
|
}
|
|
2951
3352
|
function collectServiceItems(args) {
|
|
2952
|
-
var _a, _b, _c, _d
|
|
3353
|
+
var _a, _b, _c, _d;
|
|
2953
3354
|
const filter = args.filter;
|
|
2954
3355
|
const roleFilter = (_a = filter == null ? void 0 : filter.role) != null ? _a : "both";
|
|
2955
3356
|
const where = filter == null ? void 0 : filter.where;
|
|
@@ -2999,7 +3400,7 @@ function collectServiceItems(args) {
|
|
|
2999
3400
|
affectedIds: [`field:${f.id}`, `service:${String(fSid)}`]
|
|
3000
3401
|
});
|
|
3001
3402
|
}
|
|
3002
|
-
for (const o of (
|
|
3403
|
+
for (const { option: o } of walkFieldOptions(f)) {
|
|
3003
3404
|
const oSid = o.service_id;
|
|
3004
3405
|
if (!isServiceIdRef2(oSid)) continue;
|
|
3005
3406
|
const role = fieldRoleOf(f, o);
|
|
@@ -3084,7 +3485,7 @@ function collectServiceItems(args) {
|
|
|
3084
3485
|
}
|
|
3085
3486
|
} else if (includeGroupFallbacks) {
|
|
3086
3487
|
const allowPrimaries = new Set(
|
|
3087
|
-
((
|
|
3488
|
+
((_d = args.visiblePrimaries) != null ? _d : []).map((x) => String(x))
|
|
3088
3489
|
);
|
|
3089
3490
|
for (const primaryKey of allowPrimaries) {
|
|
3090
3491
|
const list = globalFb[primaryKey];
|
|
@@ -3165,17 +3566,15 @@ function affectedFromItems(items) {
|
|
|
3165
3566
|
return uniq(ids);
|
|
3166
3567
|
}
|
|
3167
3568
|
function visibleGroupNodeIds(tag, fields) {
|
|
3168
|
-
var _a;
|
|
3169
3569
|
const ids = [tag.id];
|
|
3170
3570
|
for (const f of fields) {
|
|
3171
|
-
for (const o of (
|
|
3571
|
+
for (const { option: o } of walkFieldOptions(f)) {
|
|
3172
3572
|
ids.push(o.id);
|
|
3173
3573
|
}
|
|
3174
3574
|
}
|
|
3175
3575
|
return uniq(ids);
|
|
3176
3576
|
}
|
|
3177
3577
|
function visibleGroupPrimaries(tag, fields) {
|
|
3178
|
-
var _a;
|
|
3179
3578
|
const prim = [];
|
|
3180
3579
|
const tagSid = tag.service_id;
|
|
3181
3580
|
if (typeof tagSid === "string" || typeof tagSid === "number" && Number.isFinite(tagSid)) {
|
|
@@ -3186,7 +3585,7 @@ function visibleGroupPrimaries(tag, fields) {
|
|
|
3186
3585
|
if (typeof fsid === "string" || typeof fsid === "number" && Number.isFinite(fsid)) {
|
|
3187
3586
|
prim.push(fsid);
|
|
3188
3587
|
}
|
|
3189
|
-
for (const o of (
|
|
3588
|
+
for (const { option: o } of walkFieldOptions(f)) {
|
|
3190
3589
|
const osid = o.service_id;
|
|
3191
3590
|
if (typeof osid === "string" || typeof osid === "number" && Number.isFinite(osid)) {
|
|
3192
3591
|
prim.push(osid);
|
|
@@ -3410,6 +3809,7 @@ function validate(props, ctx = {}) {
|
|
|
3410
3809
|
validateStructure(v);
|
|
3411
3810
|
validateIdentity(v);
|
|
3412
3811
|
validateOptionMaps(v);
|
|
3812
|
+
validateVisibilityCycles(v);
|
|
3413
3813
|
validateOrderKinds(v);
|
|
3414
3814
|
v.fieldsVisibleUnder = createFieldsVisibleUnder(v);
|
|
3415
3815
|
const visSim = readVisibilitySimOpts(options);
|
|
@@ -3543,14 +3943,14 @@ var BuilderImpl = class {
|
|
|
3543
3943
|
const showOptions = showSet.has(f.id);
|
|
3544
3944
|
if (!showOptions) continue;
|
|
3545
3945
|
if (!Array.isArray(f.options)) continue;
|
|
3546
|
-
for (const o of f
|
|
3946
|
+
for (const { option: o, parentId } of walkFieldOptions(f)) {
|
|
3547
3947
|
nodes.push({
|
|
3548
3948
|
id: o.id,
|
|
3549
3949
|
kind: "option",
|
|
3550
3950
|
label: o.label
|
|
3551
3951
|
});
|
|
3552
3952
|
const e = {
|
|
3553
|
-
from: f.id,
|
|
3953
|
+
from: parentId != null ? parentId : f.id,
|
|
3554
3954
|
to: o.id,
|
|
3555
3955
|
kind: "option",
|
|
3556
3956
|
meta: { ownerField: f.id }
|
|
@@ -3597,7 +3997,7 @@ var BuilderImpl = class {
|
|
|
3597
3997
|
return { nodes, edges };
|
|
3598
3998
|
}
|
|
3599
3999
|
cleanedProps() {
|
|
3600
|
-
var _a, _b, _c, _d, _e;
|
|
4000
|
+
var _a, _b, _c, _d, _e, _f;
|
|
3601
4001
|
const fieldIds = new Set(this.props.fields.map((f) => f.id));
|
|
3602
4002
|
const optionIds = /* @__PURE__ */ new Set();
|
|
3603
4003
|
this.optionOwnerById.forEach((_v, oid) => optionIds.add(oid));
|
|
@@ -3609,6 +4009,7 @@ var BuilderImpl = class {
|
|
|
3609
4009
|
}
|
|
3610
4010
|
const incMap = (_c = this.props.includes_for_buttons) != null ? _c : {};
|
|
3611
4011
|
const excMap = (_d = this.props.excludes_for_buttons) != null ? _d : {};
|
|
4012
|
+
const effectMap = (_e = this.props.option_effects_for_buttons) != null ? _e : {};
|
|
3612
4013
|
const includedByButtons = /* @__PURE__ */ new Set();
|
|
3613
4014
|
const referencedKeys = /* @__PURE__ */ new Set();
|
|
3614
4015
|
const referencedOwnerFields = /* @__PURE__ */ new Set();
|
|
@@ -3628,6 +4029,14 @@ var BuilderImpl = class {
|
|
|
3628
4029
|
void fid;
|
|
3629
4030
|
}
|
|
3630
4031
|
}
|
|
4032
|
+
for (const [key, targets] of Object.entries(effectMap)) {
|
|
4033
|
+
referencedKeys.add(key);
|
|
4034
|
+
const owner = this.optionOwnerById.get(key);
|
|
4035
|
+
if (owner) referencedOwnerFields.add(owner.fieldId);
|
|
4036
|
+
for (const [fid, effect] of Object.entries(targets != null ? targets : {})) {
|
|
4037
|
+
if ((effect == null ? void 0 : effect.forceVisible) === true) includedByButtons.add(fid);
|
|
4038
|
+
}
|
|
4039
|
+
}
|
|
3631
4040
|
const boundIds = /* @__PURE__ */ new Set();
|
|
3632
4041
|
for (const f of this.props.fields) {
|
|
3633
4042
|
const b = f.bind_id;
|
|
@@ -3645,6 +4054,7 @@ var BuilderImpl = class {
|
|
|
3645
4054
|
return bound || included || referenced || !excluded;
|
|
3646
4055
|
});
|
|
3647
4056
|
const allowedTargets = new Set(fields.map((f) => f.id));
|
|
4057
|
+
const allowedFieldById = new Map(fields.map((f) => [f.id, f]));
|
|
3648
4058
|
const pruneButtons = (src) => {
|
|
3649
4059
|
if (!src) return void 0;
|
|
3650
4060
|
const out2 = {};
|
|
@@ -3664,13 +4074,52 @@ var BuilderImpl = class {
|
|
|
3664
4074
|
const excludes_for_buttons = pruneButtons(
|
|
3665
4075
|
this.props.excludes_for_buttons
|
|
3666
4076
|
);
|
|
4077
|
+
const pruneOptionEffects = (src) => {
|
|
4078
|
+
var _a2, _b2, _c2, _d2;
|
|
4079
|
+
if (!src) return void 0;
|
|
4080
|
+
const out2 = {};
|
|
4081
|
+
for (const [key, targets] of Object.entries(src)) {
|
|
4082
|
+
const keyIsValid = optionIds.has(key) || fieldIds.has(key);
|
|
4083
|
+
if (!keyIsValid) continue;
|
|
4084
|
+
const cleanedTargets = {};
|
|
4085
|
+
for (const [targetFieldId, effect] of Object.entries(
|
|
4086
|
+
targets != null ? targets : {}
|
|
4087
|
+
)) {
|
|
4088
|
+
const field = allowedFieldById.get(targetFieldId);
|
|
4089
|
+
if (!field || !effect) continue;
|
|
4090
|
+
const validOptionIds = fieldOptionIdSet(field);
|
|
4091
|
+
const include2 = Array.from(
|
|
4092
|
+
new Set((_a2 = effect.include) != null ? _a2 : [])
|
|
4093
|
+
).filter((optionId) => validOptionIds.has(optionId));
|
|
4094
|
+
const exclude2 = Array.from(
|
|
4095
|
+
new Set((_b2 = effect.exclude) != null ? _b2 : [])
|
|
4096
|
+
).filter((optionId) => validOptionIds.has(optionId));
|
|
4097
|
+
const next = {
|
|
4098
|
+
...effect.forceVisible === true ? { forceVisible: true } : {},
|
|
4099
|
+
...include2.length ? { include: include2 } : {},
|
|
4100
|
+
...exclude2.length ? { exclude: exclude2 } : {}
|
|
4101
|
+
};
|
|
4102
|
+
if (next.forceVisible === true || ((_c2 = next.include) == null ? void 0 : _c2.length) || ((_d2 = next.exclude) == null ? void 0 : _d2.length)) {
|
|
4103
|
+
cleanedTargets[targetFieldId] = next;
|
|
4104
|
+
}
|
|
4105
|
+
}
|
|
4106
|
+
if (Object.keys(cleanedTargets).length) {
|
|
4107
|
+
out2[key] = cleanedTargets;
|
|
4108
|
+
}
|
|
4109
|
+
}
|
|
4110
|
+
return Object.keys(out2).length ? out2 : void 0;
|
|
4111
|
+
};
|
|
4112
|
+
const option_effects_for_buttons = pruneOptionEffects(
|
|
4113
|
+
this.props.option_effects_for_buttons
|
|
4114
|
+
);
|
|
3667
4115
|
const out = {
|
|
3668
4116
|
filters: this.props.filters.slice(),
|
|
3669
4117
|
fields,
|
|
3670
4118
|
...this.props.orderKinds ? { orderKinds: this.props.orderKinds } : {},
|
|
3671
4119
|
...includes_for_buttons && { includes_for_buttons },
|
|
3672
4120
|
...excludes_for_buttons && { excludes_for_buttons },
|
|
3673
|
-
|
|
4121
|
+
...option_effects_for_buttons && { option_effects_for_buttons },
|
|
4122
|
+
schema_version: (_f = this.props.schema_version) != null ? _f : "1.0",
|
|
3674
4123
|
// keep fallbacks & other maps as-is
|
|
3675
4124
|
...this.props.fallbacks ? { fallbacks: this.props.fallbacks } : {}
|
|
3676
4125
|
};
|
|
@@ -3683,12 +4132,15 @@ var BuilderImpl = class {
|
|
|
3683
4132
|
return (0, import_lodash_es2.cloneDeep)(this.options);
|
|
3684
4133
|
}
|
|
3685
4134
|
visibleFields(tagId, selectedKeys) {
|
|
4135
|
+
return this.resolveVisibility(tagId, selectedKeys).fieldIds;
|
|
4136
|
+
}
|
|
4137
|
+
resolveVisibility(tagId, selectedKeys) {
|
|
3686
4138
|
var _a;
|
|
3687
|
-
return
|
|
3688
|
-
|
|
3689
|
-
|
|
3690
|
-
)
|
|
3691
|
-
|
|
4139
|
+
return resolveVisibility(
|
|
4140
|
+
this.props,
|
|
4141
|
+
tagId,
|
|
4142
|
+
(_a = selectedKeys != null ? selectedKeys : this.options.selectedOptionKeys) != null ? _a : []
|
|
4143
|
+
);
|
|
3692
4144
|
}
|
|
3693
4145
|
getNodeMap() {
|
|
3694
4146
|
if (!this._nodemap) this._nodemap = buildNodeMap(this.getProps());
|
|
@@ -3703,9 +4155,8 @@ var BuilderImpl = class {
|
|
|
3703
4155
|
for (const t of this.props.filters) this.tagById.set(t.id, t);
|
|
3704
4156
|
for (const f of this.props.fields) {
|
|
3705
4157
|
this.fieldById.set(f.id, f);
|
|
3706
|
-
|
|
3707
|
-
|
|
3708
|
-
this.optionOwnerById.set(o.id, { fieldId: f.id });
|
|
4158
|
+
for (const [optionId, owner] of optionOwnerMap([f])) {
|
|
4159
|
+
this.optionOwnerById.set(optionId, { fieldId: owner.fieldId });
|
|
3709
4160
|
}
|
|
3710
4161
|
}
|
|
3711
4162
|
}
|
|
@@ -5142,20 +5593,20 @@ function isFiniteNumber2(v) {
|
|
|
5142
5593
|
|
|
5143
5594
|
// src/utils/build-order-snapshot/selection.ts
|
|
5144
5595
|
function isOptionBased(f) {
|
|
5145
|
-
const hasOptions =
|
|
5596
|
+
const hasOptions = fieldOptionIdSet(f).size > 0;
|
|
5146
5597
|
return hasOptions || isMultiField(f);
|
|
5147
5598
|
}
|
|
5148
5599
|
function toSelectedOptionKeys(byField) {
|
|
5149
5600
|
const keys = [];
|
|
5150
|
-
for (const
|
|
5601
|
+
for (const optionIds of Object.values(byField != null ? byField : {})) {
|
|
5151
5602
|
for (const optionId of optionIds != null ? optionIds : []) {
|
|
5152
|
-
keys.push(
|
|
5603
|
+
keys.push(optionId);
|
|
5153
5604
|
}
|
|
5154
5605
|
}
|
|
5155
5606
|
return keys;
|
|
5156
5607
|
}
|
|
5157
|
-
function getSelectedOptionsByFieldId(selection, fieldById, mode) {
|
|
5158
|
-
var _a
|
|
5608
|
+
function getSelectedOptionsByFieldId(selection, fieldById, mode, visibleOptionsByFieldId) {
|
|
5609
|
+
var _a;
|
|
5159
5610
|
const collected = {};
|
|
5160
5611
|
for (const visit of buildSelectedNodeVisitOrder(selection, fieldById)) {
|
|
5161
5612
|
if (visit.kind !== "option") continue;
|
|
@@ -5166,18 +5617,18 @@ function getSelectedOptionsByFieldId(selection, fieldById, mode) {
|
|
|
5166
5617
|
for (const [fieldId, optionIds] of Object.entries(collected)) {
|
|
5167
5618
|
const field = fieldById.get(fieldId);
|
|
5168
5619
|
if (!field) continue;
|
|
5169
|
-
const validOptionIds =
|
|
5170
|
-
|
|
5171
|
-
);
|
|
5620
|
+
const validOptionIds = fieldOptionIdSet(field);
|
|
5621
|
+
const visibleOptionIds = (visibleOptionsByFieldId == null ? void 0 : visibleOptionsByFieldId[fieldId]) ? new Set(visibleOptionsByFieldId[fieldId]) : void 0;
|
|
5172
5622
|
const dedupedValid = [];
|
|
5173
5623
|
const seen = /* @__PURE__ */ new Set();
|
|
5174
5624
|
for (const optionId of optionIds) {
|
|
5175
5625
|
if (!validOptionIds.has(optionId)) continue;
|
|
5626
|
+
if (visibleOptionIds && !visibleOptionIds.has(optionId)) continue;
|
|
5176
5627
|
if (seen.has(optionId)) continue;
|
|
5177
5628
|
seen.add(optionId);
|
|
5178
5629
|
dedupedValid.push(optionId);
|
|
5179
5630
|
}
|
|
5180
|
-
const isMulti = ((
|
|
5631
|
+
const isMulti = ((_a = field.meta) == null ? void 0 : _a.multi) === true;
|
|
5181
5632
|
const normalized = mode === "prod" && !isMulti ? dedupedValid.length ? [dedupedValid[dedupedValid.length - 1]] : [] : dedupedValid;
|
|
5182
5633
|
if (normalized.length) out[fieldId] = normalized;
|
|
5183
5634
|
}
|
|
@@ -5194,57 +5645,49 @@ function buildSelectedNodeVisitOrder(selection, fieldById) {
|
|
|
5194
5645
|
out.push({ kind: "field", fieldId });
|
|
5195
5646
|
}
|
|
5196
5647
|
function pushOption(fieldId, optionId) {
|
|
5197
|
-
const key = `option:${
|
|
5648
|
+
const key = `option:${optionId}`;
|
|
5198
5649
|
if (seen.has(key)) return;
|
|
5199
5650
|
seen.add(key);
|
|
5200
5651
|
out.push({ kind: "option", fieldId, optionId });
|
|
5201
5652
|
}
|
|
5202
|
-
for (const
|
|
5203
|
-
|
|
5653
|
+
for (const optionId of (_a = selection.optionTraversalOrder) != null ? _a : []) {
|
|
5654
|
+
const ownerField = findOptionOwnerField(fieldById.values(), optionId);
|
|
5655
|
+
if (ownerField) pushOption(ownerField.id, optionId);
|
|
5204
5656
|
}
|
|
5205
5657
|
for (const rawKey of (_b = selection.selectedKeys) != null ? _b : []) {
|
|
5206
5658
|
const key = String(rawKey);
|
|
5207
|
-
if (key.includes("::")) {
|
|
5208
|
-
const [fieldId, optionId] = key.split("::", 2);
|
|
5209
|
-
if (fieldId && optionId) pushOption(fieldId, optionId);
|
|
5210
|
-
continue;
|
|
5211
|
-
}
|
|
5212
5659
|
const field = fieldById.get(key);
|
|
5213
5660
|
if (field) {
|
|
5214
5661
|
pushField(field.id);
|
|
5215
5662
|
continue;
|
|
5216
5663
|
}
|
|
5217
|
-
const ownerField = findOptionOwnerField(
|
|
5664
|
+
const ownerField = findOptionOwnerField(fieldById.values(), key);
|
|
5218
5665
|
if (ownerField) pushOption(ownerField.id, key);
|
|
5219
5666
|
}
|
|
5220
5667
|
for (const [fieldId, optionIds] of Object.entries(
|
|
5221
5668
|
(_c = selection.optionSelectionsByFieldId) != null ? _c : {}
|
|
5222
5669
|
)) {
|
|
5223
|
-
|
|
5670
|
+
const hintedField = fieldById.get(fieldId);
|
|
5671
|
+
if (!hintedField) continue;
|
|
5224
5672
|
for (const optionId of optionIds != null ? optionIds : []) {
|
|
5225
|
-
|
|
5673
|
+
const ownerField = findOptionOwnerField(fieldById.values(), optionId);
|
|
5674
|
+
if ((ownerField == null ? void 0 : ownerField.id) === hintedField.id) {
|
|
5675
|
+
pushOption(ownerField.id, optionId);
|
|
5676
|
+
}
|
|
5226
5677
|
}
|
|
5227
5678
|
}
|
|
5228
5679
|
return out;
|
|
5229
5680
|
}
|
|
5230
|
-
function findOptionOwnerField(optionId, fieldById) {
|
|
5231
|
-
var _a;
|
|
5232
|
-
for (const field of fieldById.values()) {
|
|
5233
|
-
if ((_a = field.options) == null ? void 0 : _a.some((option) => option.id === optionId)) return field;
|
|
5234
|
-
}
|
|
5235
|
-
return void 0;
|
|
5236
|
-
}
|
|
5237
5681
|
|
|
5238
5682
|
// src/utils/build-order-snapshot/services.ts
|
|
5239
5683
|
function isServiceBased(field) {
|
|
5240
|
-
var _a;
|
|
5241
5684
|
if (field.service_id !== void 0 && field.service_id !== null) return true;
|
|
5242
|
-
return
|
|
5243
|
-
(
|
|
5244
|
-
)
|
|
5685
|
+
return walkFieldOptions(field).some(
|
|
5686
|
+
({ option }) => option.service_id !== void 0 && option.service_id !== null
|
|
5687
|
+
);
|
|
5245
5688
|
}
|
|
5246
5689
|
function resolveServices(tagId, visibleFieldIds, selection, tagById, fieldById, services) {
|
|
5247
|
-
var _a, _b, _c
|
|
5690
|
+
var _a, _b, _c;
|
|
5248
5691
|
const serviceMap = {};
|
|
5249
5692
|
const visible = new Set(visibleFieldIds);
|
|
5250
5693
|
const selectedBaseServices = [];
|
|
@@ -5271,9 +5714,9 @@ function resolveServices(tagId, visibleFieldIds, selection, tagById, fieldById,
|
|
|
5271
5714
|
}
|
|
5272
5715
|
continue;
|
|
5273
5716
|
}
|
|
5274
|
-
const option = (
|
|
5717
|
+
const option = findFieldOption(field, visit.optionId);
|
|
5275
5718
|
if (!option) continue;
|
|
5276
|
-
const role = (
|
|
5719
|
+
const role = (_c = (_b = option.pricing_role) != null ? _b : field.pricing_role) != null ? _c : "base";
|
|
5277
5720
|
if (role === "utility") continue;
|
|
5278
5721
|
if (option.service_id !== void 0 && option.service_id !== null) {
|
|
5279
5722
|
addSelectedBaseService(option.id, option.service_id);
|
|
@@ -5404,16 +5847,15 @@ function resolveQuantity(visibleFieldIds, fieldById, tagById, selection, tagId,
|
|
|
5404
5847
|
return { quantity: hostDefault, source: { kind: "default", defaultedFromHost: true } };
|
|
5405
5848
|
}
|
|
5406
5849
|
function resolveNodeDefaultQuantity(visibleFieldIds, fieldById, tagById, selection, tagId) {
|
|
5407
|
-
var _a, _b
|
|
5850
|
+
var _a, _b;
|
|
5408
5851
|
const visible = new Set(visibleFieldIds);
|
|
5409
5852
|
const visits = buildSelectedNodeVisitOrder(selection, fieldById);
|
|
5410
5853
|
for (const visit of visits) {
|
|
5411
5854
|
if (visit.kind !== "option") continue;
|
|
5412
5855
|
if (!visible.has(visit.fieldId)) continue;
|
|
5413
5856
|
const field = fieldById.get(visit.fieldId);
|
|
5414
|
-
|
|
5415
|
-
const
|
|
5416
|
-
const quantity = readPositiveFiniteNumber((_b = option == null ? void 0 : option.meta) == null ? void 0 : _b.quantityDefault);
|
|
5857
|
+
const option = findFieldOption(field, visit.optionId);
|
|
5858
|
+
const quantity = readPositiveFiniteNumber((_a = option == null ? void 0 : option.meta) == null ? void 0 : _a.quantityDefault);
|
|
5417
5859
|
if (quantity !== void 0) {
|
|
5418
5860
|
return { quantity, source: { kind: "option", id: option.id } };
|
|
5419
5861
|
}
|
|
@@ -5428,7 +5870,7 @@ function resolveNodeDefaultQuantity(visibleFieldIds, fieldById, tagById, selecti
|
|
|
5428
5870
|
}
|
|
5429
5871
|
}
|
|
5430
5872
|
const tag = tagById.get(tagId);
|
|
5431
|
-
const tagQuantity = readPositiveFiniteNumber((
|
|
5873
|
+
const tagQuantity = readPositiveFiniteNumber((_b = tag == null ? void 0 : tag.meta) == null ? void 0 : _b.quantityDefault);
|
|
5432
5874
|
if (tagQuantity !== void 0) {
|
|
5433
5875
|
return { quantity: tagQuantity, source: { kind: "tag", id: tagId } };
|
|
5434
5876
|
}
|
|
@@ -5531,12 +5973,10 @@ function collectUtilityLineItems(visibleFieldIds, fieldById, selection, selected
|
|
|
5531
5973
|
const item = buildUtilityItemFromMarker(field.id, marker, quantity, value);
|
|
5532
5974
|
if (item) items.push(item);
|
|
5533
5975
|
}
|
|
5534
|
-
|
|
5535
|
-
|
|
5536
|
-
if (!selectedOptionIds.length) continue;
|
|
5537
|
-
const optById = new Map(field.options.map((o) => [o.id, o]));
|
|
5976
|
+
const selectedOptionIds = (_c = selectedOptionsByFieldId[field.id]) != null ? _c : [];
|
|
5977
|
+
if (selectedOptionIds.length) {
|
|
5538
5978
|
for (const oid of selectedOptionIds) {
|
|
5539
|
-
const option =
|
|
5979
|
+
const option = findFieldOption(field, oid);
|
|
5540
5980
|
if (!option) continue;
|
|
5541
5981
|
if (((_d = option.pricing_role) != null ? _d : "base") !== "utility") continue;
|
|
5542
5982
|
const optionMarker = readUtilityMarker((_e = option.meta) == null ? void 0 : _e.utility);
|
|
@@ -5652,7 +6092,7 @@ function buildDevWarnings(props, svcMap, originalFallbacks, fieldById, visibleFi
|
|
|
5652
6092
|
|
|
5653
6093
|
// src/utils/build-order-snapshot/index.ts
|
|
5654
6094
|
function buildOrderSnapshot(props, builder, selection, services, settings = {}) {
|
|
5655
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
6095
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
5656
6096
|
const mode = (_a = settings.mode) != null ? _a : "prod";
|
|
5657
6097
|
const hostDefaultQty = Number.isFinite((_b = settings.hostDefaultQuantity) != null ? _b : 1) ? settings.hostDefaultQuantity : 1;
|
|
5658
6098
|
const fbSettings = {
|
|
@@ -5665,14 +6105,31 @@ function buildOrderSnapshot(props, builder, selection, services, settings = {})
|
|
|
5665
6105
|
const builtAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
5666
6106
|
const tagId = selection.activeTagId;
|
|
5667
6107
|
const selectedButtonKeys = (_d = selection.selectedKeys) != null ? _d : toSelectedOptionKeys(selection.optionSelectionsByFieldId);
|
|
5668
|
-
const visibleFieldIds = builder.visibleFields(tagId, selectedButtonKeys);
|
|
5669
6108
|
const tagById = new Map(((_e = props.filters) != null ? _e : []).map((t) => [t.id, t]));
|
|
5670
6109
|
const fieldById = new Map(((_f = props.fields) != null ? _f : []).map((f) => [f.id, f]));
|
|
5671
|
-
const
|
|
6110
|
+
const resolve = typeof builder.resolveVisibility === "function" ? builder.resolveVisibility.bind(builder) : void 0;
|
|
6111
|
+
let resolvedVisibility = resolve == null ? void 0 : resolve(tagId, selectedButtonKeys);
|
|
6112
|
+
let visibleFieldIds = (_g = resolvedVisibility == null ? void 0 : resolvedVisibility.fieldIds) != null ? _g : builder.visibleFields(tagId, selectedButtonKeys);
|
|
6113
|
+
const filteredSelectedButtonKeys = filterSelectedKeysByVisibility(
|
|
6114
|
+
selectedButtonKeys,
|
|
6115
|
+
visibleFieldIds,
|
|
6116
|
+
resolvedVisibility == null ? void 0 : resolvedVisibility.optionsByFieldId,
|
|
6117
|
+
fieldById
|
|
6118
|
+
);
|
|
6119
|
+
if (resolve && filteredSelectedButtonKeys.join("\0") !== selectedButtonKeys.join("\0")) {
|
|
6120
|
+
resolvedVisibility = resolve(tagId, filteredSelectedButtonKeys);
|
|
6121
|
+
visibleFieldIds = resolvedVisibility.fieldIds;
|
|
6122
|
+
}
|
|
6123
|
+
const effectiveSelection = {
|
|
6124
|
+
...selection,
|
|
6125
|
+
selectedKeys: filteredSelectedButtonKeys
|
|
6126
|
+
};
|
|
6127
|
+
const tagConstraints = (_i = (_h = tagById.get(tagId)) == null ? void 0 : _h.constraints) != null ? _i : void 0;
|
|
5672
6128
|
const selectedOptionsByFieldId = getSelectedOptionsByFieldId(
|
|
5673
|
-
|
|
6129
|
+
effectiveSelection,
|
|
5674
6130
|
fieldById,
|
|
5675
|
-
mode
|
|
6131
|
+
mode,
|
|
6132
|
+
resolvedVisibility == null ? void 0 : resolvedVisibility.optionsByFieldId
|
|
5676
6133
|
);
|
|
5677
6134
|
const selectionFields = visibleFieldIds.map((fid) => fieldById.get(fid)).filter((f) => !!f).map((f) => {
|
|
5678
6135
|
var _a2;
|
|
@@ -5686,21 +6143,21 @@ function buildOrderSnapshot(props, builder, selection, services, settings = {})
|
|
|
5686
6143
|
const { formValues, selections } = buildInputs(
|
|
5687
6144
|
visibleFieldIds,
|
|
5688
6145
|
fieldById,
|
|
5689
|
-
|
|
6146
|
+
effectiveSelection,
|
|
5690
6147
|
selectedOptionsByFieldId
|
|
5691
6148
|
);
|
|
5692
6149
|
const qtyRes = resolveQuantity(
|
|
5693
6150
|
visibleFieldIds,
|
|
5694
6151
|
fieldById,
|
|
5695
6152
|
tagById,
|
|
5696
|
-
|
|
6153
|
+
effectiveSelection,
|
|
5697
6154
|
tagId,
|
|
5698
6155
|
hostDefaultQty
|
|
5699
6156
|
);
|
|
5700
6157
|
const { serviceMap, servicesList } = resolveServices(
|
|
5701
6158
|
tagId,
|
|
5702
6159
|
visibleFieldIds,
|
|
5703
|
-
|
|
6160
|
+
effectiveSelection,
|
|
5704
6161
|
tagById,
|
|
5705
6162
|
fieldById,
|
|
5706
6163
|
services
|
|
@@ -5722,7 +6179,7 @@ function buildOrderSnapshot(props, builder, selection, services, settings = {})
|
|
|
5722
6179
|
const utilities = collectUtilityLineItems(
|
|
5723
6180
|
visibleFieldIds,
|
|
5724
6181
|
fieldById,
|
|
5725
|
-
|
|
6182
|
+
effectiveSelection,
|
|
5726
6183
|
selectedOptionsByFieldId,
|
|
5727
6184
|
qtyRes.quantity
|
|
5728
6185
|
);
|
|
@@ -5732,7 +6189,7 @@ function buildOrderSnapshot(props, builder, selection, services, settings = {})
|
|
|
5732
6189
|
prunedFallbacks.original,
|
|
5733
6190
|
fieldById,
|
|
5734
6191
|
visibleFieldIds,
|
|
5735
|
-
|
|
6192
|
+
effectiveSelection
|
|
5736
6193
|
) : void 0;
|
|
5737
6194
|
const meta = {
|
|
5738
6195
|
schema_version: props.schema_version,
|
|
@@ -5745,7 +6202,7 @@ function buildOrderSnapshot(props, builder, selection, services, settings = {})
|
|
|
5745
6202
|
tagId,
|
|
5746
6203
|
visibleFieldIds,
|
|
5747
6204
|
fieldById,
|
|
5748
|
-
|
|
6205
|
+
effectiveSelection,
|
|
5749
6206
|
selectedOptionsByFieldId
|
|
5750
6207
|
),
|
|
5751
6208
|
policy: toSnapshotPolicy(fbSettings)
|
|
@@ -5757,7 +6214,7 @@ function buildOrderSnapshot(props, builder, selection, services, settings = {})
|
|
|
5757
6214
|
builtAt,
|
|
5758
6215
|
selection: {
|
|
5759
6216
|
tag: tagId,
|
|
5760
|
-
buttons:
|
|
6217
|
+
buttons: filteredSelectedButtonKeys,
|
|
5761
6218
|
fields: selectionFields
|
|
5762
6219
|
},
|
|
5763
6220
|
inputs: { form: formValues, selections },
|
|
@@ -5775,6 +6232,24 @@ function buildOrderSnapshot(props, builder, selection, services, settings = {})
|
|
|
5775
6232
|
meta
|
|
5776
6233
|
};
|
|
5777
6234
|
}
|
|
6235
|
+
function filterSelectedKeysByVisibility(selectedKeys, visibleFieldIds, optionsByFieldId, fieldById) {
|
|
6236
|
+
if (!optionsByFieldId) return selectedKeys;
|
|
6237
|
+
const visibleFields = new Set(visibleFieldIds);
|
|
6238
|
+
const out = [];
|
|
6239
|
+
for (const rawKey of selectedKeys) {
|
|
6240
|
+
const key = String(rawKey);
|
|
6241
|
+
if (fieldById.has(key)) {
|
|
6242
|
+
if (visibleFields.has(key)) out.push(key);
|
|
6243
|
+
continue;
|
|
6244
|
+
}
|
|
6245
|
+
const owner = findOptionOwnerField(fieldById.values(), key);
|
|
6246
|
+
if (!owner || !visibleFields.has(owner.id)) continue;
|
|
6247
|
+
const allowed = optionsByFieldId[owner.id];
|
|
6248
|
+
if (allowed && !allowed.includes(key)) continue;
|
|
6249
|
+
out.push(key);
|
|
6250
|
+
}
|
|
6251
|
+
return out;
|
|
6252
|
+
}
|
|
5778
6253
|
|
|
5779
6254
|
// src/core/fallback-editor.ts
|
|
5780
6255
|
function createFallbackEditor(options = {}) {
|
|
@@ -6254,6 +6729,97 @@ function bumpSuffix(old) {
|
|
|
6254
6729
|
return `${stem}${parseInt(m[2], 10) + 1}`;
|
|
6255
6730
|
}
|
|
6256
6731
|
|
|
6732
|
+
// src/react/canvas/editor/editor-utils.ts
|
|
6733
|
+
function ownerOfOption(props, optionId) {
|
|
6734
|
+
var _a;
|
|
6735
|
+
for (const f of (_a = props.fields) != null ? _a : []) {
|
|
6736
|
+
const found = findOptionLocationInField(f, optionId);
|
|
6737
|
+
if (found) return { fieldId: f.id, index: found.index };
|
|
6738
|
+
}
|
|
6739
|
+
return null;
|
|
6740
|
+
}
|
|
6741
|
+
function findMutableOption(props, optionId) {
|
|
6742
|
+
var _a;
|
|
6743
|
+
for (const field of (_a = props.fields) != null ? _a : []) {
|
|
6744
|
+
const found = findOptionLocationInField(field, optionId);
|
|
6745
|
+
if (found) return { field, ...found };
|
|
6746
|
+
}
|
|
6747
|
+
return void 0;
|
|
6748
|
+
}
|
|
6749
|
+
function collectFieldOptionIds(field) {
|
|
6750
|
+
const out = [];
|
|
6751
|
+
const visit = (options) => {
|
|
6752
|
+
for (const option of options != null ? options : []) {
|
|
6753
|
+
out.push(String(option.id));
|
|
6754
|
+
visit(option.children);
|
|
6755
|
+
}
|
|
6756
|
+
};
|
|
6757
|
+
visit(field == null ? void 0 : field.options);
|
|
6758
|
+
return out;
|
|
6759
|
+
}
|
|
6760
|
+
function findOptionLocationInField(field, optionId) {
|
|
6761
|
+
const visit = (siblings, parent) => {
|
|
6762
|
+
if (!siblings) return void 0;
|
|
6763
|
+
const index = siblings.findIndex((option) => option.id === optionId);
|
|
6764
|
+
if (index >= 0) {
|
|
6765
|
+
return {
|
|
6766
|
+
option: siblings[index],
|
|
6767
|
+
siblings,
|
|
6768
|
+
index,
|
|
6769
|
+
parent
|
|
6770
|
+
};
|
|
6771
|
+
}
|
|
6772
|
+
for (const option of siblings) {
|
|
6773
|
+
const found = visit(option.children, option);
|
|
6774
|
+
if (found) return found;
|
|
6775
|
+
}
|
|
6776
|
+
return void 0;
|
|
6777
|
+
};
|
|
6778
|
+
return visit(field.options);
|
|
6779
|
+
}
|
|
6780
|
+
function hasFieldOptions(field) {
|
|
6781
|
+
return Array.isArray(field == null ? void 0 : field.options) && field.options.length > 0;
|
|
6782
|
+
}
|
|
6783
|
+
function isActualButtonField(field) {
|
|
6784
|
+
return (field == null ? void 0 : field.button) === true && !hasFieldOptions(field);
|
|
6785
|
+
}
|
|
6786
|
+
function clearFieldButtonReceiverMaps(props, fieldId) {
|
|
6787
|
+
var _a, _b, _c;
|
|
6788
|
+
if ((_a = props.includes_for_buttons) == null ? void 0 : _a[fieldId]) {
|
|
6789
|
+
delete props.includes_for_buttons[fieldId];
|
|
6790
|
+
}
|
|
6791
|
+
if ((_b = props.excludes_for_buttons) == null ? void 0 : _b[fieldId]) {
|
|
6792
|
+
delete props.excludes_for_buttons[fieldId];
|
|
6793
|
+
}
|
|
6794
|
+
if (props.includes_for_buttons && Object.keys(props.includes_for_buttons).length === 0) {
|
|
6795
|
+
delete props.includes_for_buttons;
|
|
6796
|
+
}
|
|
6797
|
+
if (props.excludes_for_buttons && Object.keys(props.excludes_for_buttons).length === 0) {
|
|
6798
|
+
delete props.excludes_for_buttons;
|
|
6799
|
+
}
|
|
6800
|
+
if ((_c = props.option_effects_for_buttons) == null ? void 0 : _c[fieldId]) {
|
|
6801
|
+
delete props.option_effects_for_buttons[fieldId];
|
|
6802
|
+
}
|
|
6803
|
+
if (props.option_effects_for_buttons && Object.keys(props.option_effects_for_buttons).length === 0) {
|
|
6804
|
+
delete props.option_effects_for_buttons;
|
|
6805
|
+
}
|
|
6806
|
+
}
|
|
6807
|
+
function ensureServiceExists(opts, id) {
|
|
6808
|
+
if (typeof opts.serviceExists === "function") {
|
|
6809
|
+
if (!opts.serviceExists(id)) {
|
|
6810
|
+
throw new Error(`service_not_found:${String(id)}`);
|
|
6811
|
+
}
|
|
6812
|
+
return;
|
|
6813
|
+
}
|
|
6814
|
+
if (opts.serviceMap) {
|
|
6815
|
+
if (!Object.prototype.hasOwnProperty.call(opts.serviceMap, id)) {
|
|
6816
|
+
throw new Error(`service_not_found:${String(id)}`);
|
|
6817
|
+
}
|
|
6818
|
+
return;
|
|
6819
|
+
}
|
|
6820
|
+
throw new Error("service_checker_missing");
|
|
6821
|
+
}
|
|
6822
|
+
|
|
6257
6823
|
// src/react/canvas/editor/editor-duplicate.ts
|
|
6258
6824
|
function duplicate(ctx, ref, opts = {}) {
|
|
6259
6825
|
const snapBefore = ctx.makeSnapshot("duplicate:before");
|
|
@@ -6328,14 +6894,66 @@ function duplicateInPlace(ctx, ref, opts = {}) {
|
|
|
6328
6894
|
return duplicateOption(ctx, ref.fieldId, ref.id, opts);
|
|
6329
6895
|
}
|
|
6330
6896
|
function ownerFieldOfOption(props, optionId) {
|
|
6331
|
-
var _a
|
|
6897
|
+
var _a;
|
|
6332
6898
|
for (const field of (_a = props.fields) != null ? _a : []) {
|
|
6333
|
-
if ((
|
|
6899
|
+
if (findMutableOption({ ...props, fields: [field] }, optionId)) {
|
|
6334
6900
|
return { fieldId: field.id };
|
|
6335
6901
|
}
|
|
6336
6902
|
}
|
|
6337
6903
|
return null;
|
|
6338
6904
|
}
|
|
6905
|
+
function cloneOptionTree(ctx, fieldId, option, opts, optionIdMap) {
|
|
6906
|
+
var _a, _b, _c, _d;
|
|
6907
|
+
const newId = ctx.uniqueOptionId(
|
|
6908
|
+
fieldId,
|
|
6909
|
+
((_a = opts.optionIdStrategy) != null ? _a : defaultOptionIdStrategy)(option.id)
|
|
6910
|
+
);
|
|
6911
|
+
optionIdMap.set(option.id, newId);
|
|
6912
|
+
const children = (_b = option.children) == null ? void 0 : _b.map(
|
|
6913
|
+
(child) => cloneOptionTree(ctx, fieldId, child, opts, optionIdMap)
|
|
6914
|
+
);
|
|
6915
|
+
return {
|
|
6916
|
+
...option,
|
|
6917
|
+
id: newId,
|
|
6918
|
+
label: ((_c = opts.labelStrategy) != null ? _c : nextCopyLabel)((_d = option.label) != null ? _d : option.id),
|
|
6919
|
+
...(children == null ? void 0 : children.length) ? { children } : {}
|
|
6920
|
+
};
|
|
6921
|
+
}
|
|
6922
|
+
function remapEffect(effect, optionIdMap) {
|
|
6923
|
+
const remapList = (values) => values == null ? void 0 : values.map((value) => {
|
|
6924
|
+
var _a;
|
|
6925
|
+
return (_a = optionIdMap.get(value)) != null ? _a : value;
|
|
6926
|
+
});
|
|
6927
|
+
return {
|
|
6928
|
+
...effect,
|
|
6929
|
+
...effect.include ? { include: remapList(effect.include) } : {},
|
|
6930
|
+
...effect.exclude ? { exclude: remapList(effect.exclude) } : {}
|
|
6931
|
+
};
|
|
6932
|
+
}
|
|
6933
|
+
function copyOptionEffects(props, args) {
|
|
6934
|
+
var _a, _b, _c, _d, _e;
|
|
6935
|
+
const source = props.option_effects_for_buttons;
|
|
6936
|
+
if (!source) return;
|
|
6937
|
+
const next = {
|
|
6938
|
+
...source
|
|
6939
|
+
};
|
|
6940
|
+
const triggerIdMap = (_a = args.triggerIdMap) != null ? _a : /* @__PURE__ */ new Map();
|
|
6941
|
+
const targetFieldIdMap = (_b = args.targetFieldIdMap) != null ? _b : /* @__PURE__ */ new Map();
|
|
6942
|
+
const optionIdMap = (_c = args.optionIdMap) != null ? _c : /* @__PURE__ */ new Map();
|
|
6943
|
+
for (const [oldTriggerId, targetMap] of Object.entries(source)) {
|
|
6944
|
+
const newTriggerId = triggerIdMap.get(oldTriggerId);
|
|
6945
|
+
if (!newTriggerId) continue;
|
|
6946
|
+
const copiedTargets = {
|
|
6947
|
+
...(_d = next[newTriggerId]) != null ? _d : {}
|
|
6948
|
+
};
|
|
6949
|
+
for (const [oldTargetFieldId, effect] of Object.entries(targetMap != null ? targetMap : {})) {
|
|
6950
|
+
const newTargetFieldId = (_e = targetFieldIdMap.get(oldTargetFieldId)) != null ? _e : oldTargetFieldId;
|
|
6951
|
+
copiedTargets[newTargetFieldId] = remapEffect(effect, optionIdMap);
|
|
6952
|
+
}
|
|
6953
|
+
next[newTriggerId] = copiedTargets;
|
|
6954
|
+
}
|
|
6955
|
+
props.option_effects_for_buttons = next;
|
|
6956
|
+
}
|
|
6339
6957
|
function duplicateTag(ctx, tagId, opts) {
|
|
6340
6958
|
var _a, _b, _c, _d;
|
|
6341
6959
|
const props = ctx.getProps();
|
|
@@ -6391,7 +7009,7 @@ function duplicateTag(ctx, tagId, opts) {
|
|
|
6391
7009
|
return id;
|
|
6392
7010
|
}
|
|
6393
7011
|
function duplicateField(ctx, fieldId, opts) {
|
|
6394
|
-
var _a, _b, _c, _d, _e, _f
|
|
7012
|
+
var _a, _b, _c, _d, _e, _f;
|
|
6395
7013
|
const props = ctx.getProps();
|
|
6396
7014
|
const fields = (_a = props.fields) != null ? _a : [];
|
|
6397
7015
|
const src = fields.find((f) => f.id === fieldId);
|
|
@@ -6399,21 +7017,10 @@ function duplicateField(ctx, fieldId, opts) {
|
|
|
6399
7017
|
const id = (_b = opts.id) != null ? _b : ctx.uniqueId(src.id);
|
|
6400
7018
|
const label = ((_c = opts.labelStrategy) != null ? _c : nextCopyLabel)((_d = src.label) != null ? _d : id);
|
|
6401
7019
|
const name = opts.nameStrategy ? opts.nameStrategy(src.name) : nextCopyName(src.name);
|
|
6402
|
-
const
|
|
6403
|
-
|
|
6404
|
-
|
|
6405
|
-
|
|
6406
|
-
((_a2 = opts.optionIdStrategy) != null ? _a2 : defaultOptionIdStrategy)(old)
|
|
6407
|
-
);
|
|
6408
|
-
};
|
|
6409
|
-
const clonedOptions = ((_e = src.options) != null ? _e : []).map((o) => {
|
|
6410
|
-
var _a2, _b2;
|
|
6411
|
-
return {
|
|
6412
|
-
...o,
|
|
6413
|
-
id: optId(o.id),
|
|
6414
|
-
label: ((_a2 = opts.labelStrategy) != null ? _a2 : nextCopyLabel)((_b2 = o.label) != null ? _b2 : o.id)
|
|
6415
|
-
};
|
|
6416
|
-
});
|
|
7020
|
+
const optionIdMap = /* @__PURE__ */ new Map();
|
|
7021
|
+
const clonedOptions = ((_e = src.options) != null ? _e : []).map(
|
|
7022
|
+
(o) => cloneOptionTree(ctx, id, o, opts, optionIdMap)
|
|
7023
|
+
);
|
|
6417
7024
|
const cloned = {
|
|
6418
7025
|
...src,
|
|
6419
7026
|
id,
|
|
@@ -6422,14 +7029,8 @@ function duplicateField(ctx, fieldId, opts) {
|
|
|
6422
7029
|
bind_id: ((_f = opts.copyBindings) != null ? _f : true) ? src.bind_id : void 0,
|
|
6423
7030
|
options: clonedOptions
|
|
6424
7031
|
};
|
|
6425
|
-
const optionIdMap = /* @__PURE__ */ new Map();
|
|
6426
|
-
((_g = src.options) != null ? _g : []).forEach((o, i) => {
|
|
6427
|
-
var _a2, _b2;
|
|
6428
|
-
const newOptId = (_b2 = (_a2 = clonedOptions[i]) == null ? void 0 : _a2.id) != null ? _b2 : o.id;
|
|
6429
|
-
optionIdMap.set(o.id, newOptId);
|
|
6430
|
-
});
|
|
6431
7032
|
ctx.patchProps((p) => {
|
|
6432
|
-
var _a2, _b2, _c2, _d2, _e2, _f2,
|
|
7033
|
+
var _a2, _b2, _c2, _d2, _e2, _f2, _g;
|
|
6433
7034
|
const arr = (_a2 = p.fields) != null ? _a2 : [];
|
|
6434
7035
|
const idx = arr.findIndex((f) => f.id === fieldId);
|
|
6435
7036
|
arr.splice(idx + 1, 0, cloned);
|
|
@@ -6467,52 +7068,56 @@ function duplicateField(ctx, fieldId, opts) {
|
|
|
6467
7068
|
}
|
|
6468
7069
|
if (optionIdMap.has(key)) {
|
|
6469
7070
|
const newKey = optionIdMap.get(key);
|
|
6470
|
-
const merged = /* @__PURE__ */ new Set([...(
|
|
7071
|
+
const merged = /* @__PURE__ */ new Set([...(_g = nextMap[newKey]) != null ? _g : [], ...targets]);
|
|
6471
7072
|
nextMap[newKey] = Array.from(merged);
|
|
6472
7073
|
}
|
|
6473
7074
|
}
|
|
6474
7075
|
p[mapKey] = nextMap;
|
|
6475
7076
|
}
|
|
7077
|
+
copyOptionEffects(p, {
|
|
7078
|
+
triggerIdMap: new Map([
|
|
7079
|
+
[fieldId, id],
|
|
7080
|
+
...Array.from(optionIdMap.entries())
|
|
7081
|
+
]),
|
|
7082
|
+
targetFieldIdMap: /* @__PURE__ */ new Map([[fieldId, id]]),
|
|
7083
|
+
optionIdMap
|
|
7084
|
+
});
|
|
6476
7085
|
}
|
|
6477
7086
|
});
|
|
6478
7087
|
return id;
|
|
6479
7088
|
}
|
|
6480
7089
|
function duplicateOption(ctx, fieldId, optionId, opts) {
|
|
6481
|
-
var _a, _b, _c, _d, _e, _f;
|
|
6482
7090
|
const props = ctx.getProps();
|
|
6483
|
-
const
|
|
6484
|
-
|
|
6485
|
-
|
|
6486
|
-
const optIdx = ((_b = f.options) != null ? _b : []).findIndex((o) => o.id === optionId);
|
|
6487
|
-
if (optIdx < 0) {
|
|
6488
|
-
throw new Error(`Option not found: ${fieldId}::${optionId}`);
|
|
7091
|
+
const location = findMutableOption(props, optionId);
|
|
7092
|
+
if (!location || location.field.id !== fieldId) {
|
|
7093
|
+
throw new Error(`Option not found: ${fieldId}/${optionId}`);
|
|
6489
7094
|
}
|
|
6490
|
-
const src =
|
|
6491
|
-
const
|
|
6492
|
-
|
|
6493
|
-
|
|
6494
|
-
);
|
|
6495
|
-
const newLabel = ((_e = opts.labelStrategy) != null ? _e : nextCopyLabel)((_f = src.label) != null ? _f : src.id);
|
|
7095
|
+
const src = location.option;
|
|
7096
|
+
const optionIdMap = /* @__PURE__ */ new Map();
|
|
7097
|
+
const clone2 = cloneOptionTree(ctx, fieldId, src, opts, optionIdMap);
|
|
7098
|
+
const newId = clone2.id;
|
|
6496
7099
|
ctx.patchProps((p) => {
|
|
6497
|
-
var
|
|
6498
|
-
const
|
|
6499
|
-
|
|
6500
|
-
|
|
6501
|
-
arr.splice(optIdx + 1, 0, clone2);
|
|
6502
|
-
fld.options = arr;
|
|
7100
|
+
var _a;
|
|
7101
|
+
const current = findMutableOption(p, optionId);
|
|
7102
|
+
if (!current) return;
|
|
7103
|
+
current.siblings.splice(current.index + 1, 0, clone2);
|
|
6503
7104
|
if (opts.copyOptionMaps) {
|
|
6504
|
-
const oldKey = `${fieldId}::${optionId}`;
|
|
6505
|
-
const newKey = `${fieldId}::${newId}`;
|
|
6506
7105
|
for (const mapKey of [
|
|
6507
7106
|
"includes_for_buttons",
|
|
6508
7107
|
"excludes_for_buttons"
|
|
6509
7108
|
]) {
|
|
6510
|
-
const m = (
|
|
6511
|
-
|
|
6512
|
-
|
|
6513
|
-
|
|
7109
|
+
const m = (_a = p[mapKey]) != null ? _a : {};
|
|
7110
|
+
for (const [oldKey, newKey] of optionIdMap.entries()) {
|
|
7111
|
+
if (m[oldKey]) {
|
|
7112
|
+
m[newKey] = Array.from(new Set(m[oldKey]));
|
|
7113
|
+
p[mapKey] = m;
|
|
7114
|
+
}
|
|
6514
7115
|
}
|
|
6515
7116
|
}
|
|
7117
|
+
copyOptionEffects(p, {
|
|
7118
|
+
triggerIdMap: optionIdMap,
|
|
7119
|
+
optionIdMap
|
|
7120
|
+
});
|
|
6516
7121
|
}
|
|
6517
7122
|
});
|
|
6518
7123
|
return newId;
|
|
@@ -6574,54 +7179,6 @@ function removeNotice(ctx, id) {
|
|
|
6574
7179
|
|
|
6575
7180
|
// src/react/canvas/editor/editor-nodes.ts
|
|
6576
7181
|
var import_lodash_es3 = require("lodash-es");
|
|
6577
|
-
|
|
6578
|
-
// src/react/canvas/editor/editor-utils.ts
|
|
6579
|
-
function ownerOfOption(props, optionId) {
|
|
6580
|
-
var _a, _b;
|
|
6581
|
-
for (const f of (_a = props.fields) != null ? _a : []) {
|
|
6582
|
-
const idx = ((_b = f.options) != null ? _b : []).findIndex((o) => o.id === optionId);
|
|
6583
|
-
if (idx >= 0) return { fieldId: f.id, index: idx };
|
|
6584
|
-
}
|
|
6585
|
-
return null;
|
|
6586
|
-
}
|
|
6587
|
-
function hasFieldOptions(field) {
|
|
6588
|
-
return Array.isArray(field == null ? void 0 : field.options) && field.options.length > 0;
|
|
6589
|
-
}
|
|
6590
|
-
function isActualButtonField(field) {
|
|
6591
|
-
return (field == null ? void 0 : field.button) === true && !hasFieldOptions(field);
|
|
6592
|
-
}
|
|
6593
|
-
function clearFieldButtonReceiverMaps(props, fieldId) {
|
|
6594
|
-
var _a, _b;
|
|
6595
|
-
if ((_a = props.includes_for_buttons) == null ? void 0 : _a[fieldId]) {
|
|
6596
|
-
delete props.includes_for_buttons[fieldId];
|
|
6597
|
-
}
|
|
6598
|
-
if ((_b = props.excludes_for_buttons) == null ? void 0 : _b[fieldId]) {
|
|
6599
|
-
delete props.excludes_for_buttons[fieldId];
|
|
6600
|
-
}
|
|
6601
|
-
if (props.includes_for_buttons && Object.keys(props.includes_for_buttons).length === 0) {
|
|
6602
|
-
delete props.includes_for_buttons;
|
|
6603
|
-
}
|
|
6604
|
-
if (props.excludes_for_buttons && Object.keys(props.excludes_for_buttons).length === 0) {
|
|
6605
|
-
delete props.excludes_for_buttons;
|
|
6606
|
-
}
|
|
6607
|
-
}
|
|
6608
|
-
function ensureServiceExists(opts, id) {
|
|
6609
|
-
if (typeof opts.serviceExists === "function") {
|
|
6610
|
-
if (!opts.serviceExists(id)) {
|
|
6611
|
-
throw new Error(`service_not_found:${String(id)}`);
|
|
6612
|
-
}
|
|
6613
|
-
return;
|
|
6614
|
-
}
|
|
6615
|
-
if (opts.serviceMap) {
|
|
6616
|
-
if (!Object.prototype.hasOwnProperty.call(opts.serviceMap, id)) {
|
|
6617
|
-
throw new Error(`service_not_found:${String(id)}`);
|
|
6618
|
-
}
|
|
6619
|
-
return;
|
|
6620
|
-
}
|
|
6621
|
-
throw new Error("service_checker_missing");
|
|
6622
|
-
}
|
|
6623
|
-
|
|
6624
|
-
// src/react/canvas/editor/editor-nodes.ts
|
|
6625
7182
|
var RELATION_MAP_KEYS = [
|
|
6626
7183
|
"includes_for_buttons",
|
|
6627
7184
|
"excludes_for_buttons",
|
|
@@ -6672,14 +7229,51 @@ function cleanRelationMapsForDeleted(p, deleted) {
|
|
|
6672
7229
|
delete map[mapKey];
|
|
6673
7230
|
continue;
|
|
6674
7231
|
}
|
|
6675
|
-
const next = ((_a = map[mapKey]) != null ? _a : []).filter(
|
|
6676
|
-
(item) => !deleted.has(String(item))
|
|
6677
|
-
);
|
|
6678
|
-
if (next.length) map[mapKey] = next;
|
|
6679
|
-
else delete map[mapKey];
|
|
7232
|
+
const next = ((_a = map[mapKey]) != null ? _a : []).filter(
|
|
7233
|
+
(item) => !deleted.has(String(item))
|
|
7234
|
+
);
|
|
7235
|
+
if (next.length) map[mapKey] = next;
|
|
7236
|
+
else delete map[mapKey];
|
|
7237
|
+
}
|
|
7238
|
+
if (!Object.keys(map).length) delete p[key];
|
|
7239
|
+
}
|
|
7240
|
+
}
|
|
7241
|
+
function cleanOptionEffectsForDeleted(p, deleted) {
|
|
7242
|
+
var _a, _b;
|
|
7243
|
+
const map = p.option_effects_for_buttons;
|
|
7244
|
+
if (!map) return;
|
|
7245
|
+
for (const triggerId of Object.keys(map)) {
|
|
7246
|
+
if (deleted.has(String(triggerId))) {
|
|
7247
|
+
delete map[triggerId];
|
|
7248
|
+
continue;
|
|
7249
|
+
}
|
|
7250
|
+
const targets = map[triggerId];
|
|
7251
|
+
for (const targetFieldId of Object.keys(targets != null ? targets : {})) {
|
|
7252
|
+
if (deleted.has(String(targetFieldId))) {
|
|
7253
|
+
delete targets[targetFieldId];
|
|
7254
|
+
continue;
|
|
7255
|
+
}
|
|
7256
|
+
const effect = targets[targetFieldId];
|
|
7257
|
+
if (!effect) continue;
|
|
7258
|
+
if (effect.include) {
|
|
7259
|
+
effect.include = effect.include.filter(
|
|
7260
|
+
(optionId) => !deleted.has(String(optionId))
|
|
7261
|
+
);
|
|
7262
|
+
if (!effect.include.length) delete effect.include;
|
|
7263
|
+
}
|
|
7264
|
+
if (effect.exclude) {
|
|
7265
|
+
effect.exclude = effect.exclude.filter(
|
|
7266
|
+
(optionId) => !deleted.has(String(optionId))
|
|
7267
|
+
);
|
|
7268
|
+
if (!effect.exclude.length) delete effect.exclude;
|
|
7269
|
+
}
|
|
7270
|
+
if (effect.forceVisible !== true && !((_a = effect.include) == null ? void 0 : _a.length) && !((_b = effect.exclude) == null ? void 0 : _b.length)) {
|
|
7271
|
+
delete targets[targetFieldId];
|
|
7272
|
+
}
|
|
6680
7273
|
}
|
|
6681
|
-
if (!Object.keys(
|
|
7274
|
+
if (!Object.keys(targets != null ? targets : {}).length) delete map[triggerId];
|
|
6682
7275
|
}
|
|
7276
|
+
if (!Object.keys(map).length) delete p.option_effects_for_buttons;
|
|
6683
7277
|
}
|
|
6684
7278
|
function cleanOrderForTagsForDeleted(p, deleted) {
|
|
6685
7279
|
var _a, _b;
|
|
@@ -6716,28 +7310,37 @@ function applyDeleteCleanup(p, deleted) {
|
|
|
6716
7310
|
cleanTagRelationsForDeleted(p, deleted);
|
|
6717
7311
|
cleanFieldBindsForDeleted(p, deleted);
|
|
6718
7312
|
cleanRelationMapsForDeleted(p, deleted);
|
|
7313
|
+
cleanOptionEffectsForDeleted(p, deleted);
|
|
6719
7314
|
cleanOrderForTagsForDeleted(p, deleted);
|
|
6720
7315
|
cleanNoticesForDeleted(p, deleted);
|
|
6721
7316
|
}
|
|
7317
|
+
function collectOptionSubtreeIds(option) {
|
|
7318
|
+
var _a;
|
|
7319
|
+
return [
|
|
7320
|
+
String(option.id),
|
|
7321
|
+
...((_a = option.children) != null ? _a : []).flatMap((child) => collectOptionSubtreeIds(child))
|
|
7322
|
+
];
|
|
7323
|
+
}
|
|
6722
7324
|
function removeOptionInPlace(p, optionId) {
|
|
6723
7325
|
var _a;
|
|
6724
|
-
const
|
|
6725
|
-
if (!
|
|
6726
|
-
const
|
|
6727
|
-
|
|
6728
|
-
|
|
6729
|
-
|
|
6730
|
-
|
|
7326
|
+
const found = findMutableOption(p, optionId);
|
|
7327
|
+
if (!found) return [];
|
|
7328
|
+
const deleted = collectOptionSubtreeIds(found.option);
|
|
7329
|
+
found.siblings.splice(found.index, 1);
|
|
7330
|
+
if (found.parent && ((_a = found.parent.children) == null ? void 0 : _a.length) === 0) {
|
|
7331
|
+
delete found.parent.children;
|
|
7332
|
+
}
|
|
7333
|
+
return deleted;
|
|
6731
7334
|
}
|
|
6732
7335
|
function removeFieldInPlace(p, fieldId) {
|
|
6733
|
-
var _a, _b, _c, _d
|
|
7336
|
+
var _a, _b, _c, _d;
|
|
6734
7337
|
const field = ((_a = p.fields) != null ? _a : []).find((f) => f.id === fieldId);
|
|
6735
7338
|
if (!field) return [];
|
|
6736
|
-
const deleted = [fieldId, ...(
|
|
6737
|
-
const before = ((
|
|
6738
|
-
p.fields = ((
|
|
7339
|
+
const deleted = [fieldId, ...collectFieldOptionIds(field)];
|
|
7340
|
+
const before = ((_b = p.fields) != null ? _b : []).length;
|
|
7341
|
+
p.fields = ((_c = p.fields) != null ? _c : []).filter((f) => f.id !== fieldId);
|
|
6739
7342
|
clearFieldButtonReceiverMaps(p, fieldId);
|
|
6740
|
-
return ((
|
|
7343
|
+
return ((_d = p.fields) != null ? _d : []).length !== before ? deleted : [];
|
|
6741
7344
|
}
|
|
6742
7345
|
function removeTagInPlace(p, tagId) {
|
|
6743
7346
|
var _a, _b, _c;
|
|
@@ -6750,7 +7353,7 @@ function reLabel(ctx, id, nextLabel) {
|
|
|
6750
7353
|
ctx.exec({
|
|
6751
7354
|
name: "reLabel",
|
|
6752
7355
|
do: () => ctx.patchProps((p) => {
|
|
6753
|
-
var _a, _b, _c, _d, _e, _f
|
|
7356
|
+
var _a, _b, _c, _d, _e, _f;
|
|
6754
7357
|
if (ctx.isTagId(id)) {
|
|
6755
7358
|
const t = ((_a = p.filters) != null ? _a : []).find((x) => x.id === id);
|
|
6756
7359
|
if (!t) return;
|
|
@@ -6760,19 +7363,16 @@ function reLabel(ctx, id, nextLabel) {
|
|
|
6760
7363
|
return;
|
|
6761
7364
|
}
|
|
6762
7365
|
if (ctx.isOptionId(id)) {
|
|
6763
|
-
const
|
|
6764
|
-
if (!own) return;
|
|
6765
|
-
const f = ((_c = p.fields) != null ? _c : []).find((x) => x.id === own.fieldId);
|
|
6766
|
-
const o = (_d = f == null ? void 0 : f.options) == null ? void 0 : _d.find((x) => x.id === id);
|
|
7366
|
+
const o = (_c = findMutableOption(p, id)) == null ? void 0 : _c.option;
|
|
6767
7367
|
if (!o) return;
|
|
6768
|
-
if (((
|
|
7368
|
+
if (((_d = o.label) != null ? _d : "") === label) return;
|
|
6769
7369
|
o.label = label;
|
|
6770
7370
|
ctx.api.refreshGraph();
|
|
6771
7371
|
return;
|
|
6772
7372
|
}
|
|
6773
|
-
const fld = ((
|
|
7373
|
+
const fld = ((_e = p.fields) != null ? _e : []).find((x) => x.id === id);
|
|
6774
7374
|
if (!fld) return;
|
|
6775
|
-
if (((
|
|
7375
|
+
if (((_f = fld.label) != null ? _f : "") === label) return;
|
|
6776
7376
|
fld.label = label;
|
|
6777
7377
|
ctx.api.refreshGraph();
|
|
6778
7378
|
}),
|
|
@@ -6862,11 +7462,7 @@ function updateOption(ctx, optionId, patch) {
|
|
|
6862
7462
|
name: "updateOption",
|
|
6863
7463
|
do: () => ctx.patchProps((p) => {
|
|
6864
7464
|
var _a;
|
|
6865
|
-
const
|
|
6866
|
-
if (!owner) return;
|
|
6867
|
-
const f = ((_a = p.fields) != null ? _a : []).find((x) => x.id === owner.fieldId);
|
|
6868
|
-
if (!(f == null ? void 0 : f.options)) return;
|
|
6869
|
-
const o = f.options.find((x) => x.id === optionId);
|
|
7465
|
+
const o = (_a = findMutableOption(p, optionId)) == null ? void 0 : _a.option;
|
|
6870
7466
|
if (o) Object.assign(o, patch);
|
|
6871
7467
|
}),
|
|
6872
7468
|
undo: () => ctx.undo()
|
|
@@ -6879,9 +7475,9 @@ function removeOption(ctx, optionId) {
|
|
|
6879
7475
|
ctx.exec({
|
|
6880
7476
|
name: "removeOption",
|
|
6881
7477
|
do: () => ctx.patchProps((p) => {
|
|
6882
|
-
const
|
|
6883
|
-
if (!
|
|
6884
|
-
applyDeleteCleanup(p,
|
|
7478
|
+
const removedIds = removeOptionInPlace(p, optionId);
|
|
7479
|
+
if (!removedIds.length) return;
|
|
7480
|
+
applyDeleteCleanup(p, new Set(removedIds));
|
|
6885
7481
|
}),
|
|
6886
7482
|
undo: () => ctx.undo()
|
|
6887
7483
|
});
|
|
@@ -6892,7 +7488,7 @@ function editLabel(ctx, id, label) {
|
|
|
6892
7488
|
ctx.exec({
|
|
6893
7489
|
name: "editLabel",
|
|
6894
7490
|
do: () => ctx.patchProps((p) => {
|
|
6895
|
-
var _a, _b, _c
|
|
7491
|
+
var _a, _b, _c;
|
|
6896
7492
|
if (ctx.isTagId(id)) {
|
|
6897
7493
|
const t = ((_a = p.filters) != null ? _a : []).find((x) => x.id === id);
|
|
6898
7494
|
if (t) t.label = next;
|
|
@@ -6904,10 +7500,7 @@ function editLabel(ctx, id, label) {
|
|
|
6904
7500
|
return;
|
|
6905
7501
|
}
|
|
6906
7502
|
if (ctx.isOptionId(id)) {
|
|
6907
|
-
const
|
|
6908
|
-
if (!own) return;
|
|
6909
|
-
const f = ((_c = p.fields) != null ? _c : []).find((x) => x.id === own.fieldId);
|
|
6910
|
-
const o = (_d = f == null ? void 0 : f.options) == null ? void 0 : _d.find((x) => x.id === id);
|
|
7503
|
+
const o = (_c = findMutableOption(p, id)) == null ? void 0 : _c.option;
|
|
6911
7504
|
if (o) o.label = next;
|
|
6912
7505
|
return;
|
|
6913
7506
|
}
|
|
@@ -6932,7 +7525,7 @@ function setService(ctx, id, input) {
|
|
|
6932
7525
|
ctx.exec({
|
|
6933
7526
|
name: "setService",
|
|
6934
7527
|
do: () => ctx.patchProps((p) => {
|
|
6935
|
-
var _a, _b, _c, _d, _e
|
|
7528
|
+
var _a, _b, _c, _d, _e;
|
|
6936
7529
|
const hasSidKey = Object.prototype.hasOwnProperty.call(
|
|
6937
7530
|
input,
|
|
6938
7531
|
"service_id"
|
|
@@ -6950,12 +7543,9 @@ function setService(ctx, id, input) {
|
|
|
6950
7543
|
return;
|
|
6951
7544
|
}
|
|
6952
7545
|
if (ctx.isOptionId(id)) {
|
|
6953
|
-
const
|
|
6954
|
-
if (!own) return;
|
|
6955
|
-
const f2 = ((_b = p.fields) != null ? _b : []).find((x) => x.id === own.fieldId);
|
|
6956
|
-
const o = (_c = f2 == null ? void 0 : f2.options) == null ? void 0 : _c.find((x) => x.id === id);
|
|
7546
|
+
const o = (_b = findMutableOption(p, id)) == null ? void 0 : _b.option;
|
|
6957
7547
|
if (!o) return;
|
|
6958
|
-
const currentRole = (
|
|
7548
|
+
const currentRole = (_c = o.pricing_role) != null ? _c : "base";
|
|
6959
7549
|
const role = nextRole != null ? nextRole : currentRole;
|
|
6960
7550
|
if (role === "utility") {
|
|
6961
7551
|
if (hasSidKey && sid !== void 0) {
|
|
@@ -6976,7 +7566,7 @@ function setService(ctx, id, input) {
|
|
|
6976
7566
|
}
|
|
6977
7567
|
return;
|
|
6978
7568
|
}
|
|
6979
|
-
const f = ((
|
|
7569
|
+
const f = ((_d = p.fields) != null ? _d : []).find((x) => x.id === id);
|
|
6980
7570
|
if (!f) {
|
|
6981
7571
|
throw new Error(
|
|
6982
7572
|
'setService only supports tag ("t:*"), option ("o:*"), or field ("f:*") ids'
|
|
@@ -6987,7 +7577,7 @@ function setService(ctx, id, input) {
|
|
|
6987
7577
|
if (nextRole) {
|
|
6988
7578
|
f.pricing_role = nextRole;
|
|
6989
7579
|
}
|
|
6990
|
-
const effectiveRole = (
|
|
7580
|
+
const effectiveRole = (_e = f.pricing_role) != null ? _e : "base";
|
|
6991
7581
|
if (isOptionBased2) {
|
|
6992
7582
|
if (hasSidKey) {
|
|
6993
7583
|
ctx.api.emit("error", {
|
|
@@ -7099,13 +7689,15 @@ function updateField(ctx, id, patch) {
|
|
|
7099
7689
|
let prev;
|
|
7100
7690
|
let prevIncludesForButton;
|
|
7101
7691
|
let prevExcludesForButton;
|
|
7692
|
+
let prevOptionEffectsForButton;
|
|
7102
7693
|
ctx.exec({
|
|
7103
7694
|
name: "updateField",
|
|
7104
7695
|
do: () => ctx.patchProps((p) => {
|
|
7105
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
7696
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
7106
7697
|
prevIncludesForButton = ((_a = p.includes_for_buttons) == null ? void 0 : _a[id]) ? [...(_c = (_b = p.includes_for_buttons) == null ? void 0 : _b[id]) != null ? _c : []] : void 0;
|
|
7107
7698
|
prevExcludesForButton = ((_d = p.excludes_for_buttons) == null ? void 0 : _d[id]) ? [...(_f = (_e = p.excludes_for_buttons) == null ? void 0 : _e[id]) != null ? _f : []] : void 0;
|
|
7108
|
-
|
|
7699
|
+
prevOptionEffectsForButton = ((_g = p.option_effects_for_buttons) == null ? void 0 : _g[id]) ? (0, import_lodash_es3.cloneDeep)(p.option_effects_for_buttons[id]) : void 0;
|
|
7700
|
+
p.fields = ((_h = p.fields) != null ? _h : []).map((f) => {
|
|
7109
7701
|
if (f.id !== id) return f;
|
|
7110
7702
|
prev = (0, import_lodash_es3.cloneDeep)(f);
|
|
7111
7703
|
const nextField = { ...f, ...patch };
|
|
@@ -7116,7 +7708,7 @@ function updateField(ctx, id, patch) {
|
|
|
7116
7708
|
});
|
|
7117
7709
|
}),
|
|
7118
7710
|
undo: () => ctx.patchProps((p) => {
|
|
7119
|
-
var _a, _b, _c;
|
|
7711
|
+
var _a, _b, _c, _d;
|
|
7120
7712
|
p.fields = ((_a = p.fields) != null ? _a : []).map(
|
|
7121
7713
|
(f) => f.id === id && prev ? prev : f
|
|
7122
7714
|
);
|
|
@@ -7134,6 +7726,12 @@ function updateField(ctx, id, patch) {
|
|
|
7134
7726
|
[id]: [...prevExcludesForButton]
|
|
7135
7727
|
};
|
|
7136
7728
|
}
|
|
7729
|
+
if (prevOptionEffectsForButton) {
|
|
7730
|
+
p.option_effects_for_buttons = {
|
|
7731
|
+
...(_d = p.option_effects_for_buttons) != null ? _d : {},
|
|
7732
|
+
[id]: (0, import_lodash_es3.cloneDeep)(prevOptionEffectsForButton)
|
|
7733
|
+
};
|
|
7734
|
+
}
|
|
7137
7735
|
})
|
|
7138
7736
|
});
|
|
7139
7737
|
}
|
|
@@ -7180,9 +7778,9 @@ function remove(ctx, id) {
|
|
|
7180
7778
|
ctx.exec({
|
|
7181
7779
|
name: "removeOption",
|
|
7182
7780
|
do: () => ctx.patchProps((p) => {
|
|
7183
|
-
const
|
|
7184
|
-
if (!
|
|
7185
|
-
applyDeleteCleanup(p,
|
|
7781
|
+
const removedIds = removeOptionInPlace(p, key);
|
|
7782
|
+
if (!removedIds.length) return;
|
|
7783
|
+
applyDeleteCleanup(p, new Set(removedIds));
|
|
7186
7784
|
}),
|
|
7187
7785
|
undo: () => ctx.undo()
|
|
7188
7786
|
});
|
|
@@ -7199,10 +7797,7 @@ function removeMany(ctx, ids) {
|
|
|
7199
7797
|
const existingFieldIds = new Set(((_a = p.fields) != null ? _a : []).map((f) => String(f.id)));
|
|
7200
7798
|
const existingTagIds = new Set(((_b = p.filters) != null ? _b : []).map((t) => String(t.id)));
|
|
7201
7799
|
const existingOptionIds = new Set(
|
|
7202
|
-
((_c = p.fields) != null ? _c : []).flatMap((f) =>
|
|
7203
|
-
var _a2;
|
|
7204
|
-
return ((_a2 = f.options) != null ? _a2 : []).map((o) => String(o.id));
|
|
7205
|
-
})
|
|
7800
|
+
((_c = p.fields) != null ? _c : []).flatMap((f) => collectFieldOptionIds(f))
|
|
7206
7801
|
);
|
|
7207
7802
|
const fieldIds = ordered.filter((id) => ctx.isFieldId(id) && existingFieldIds.has(id));
|
|
7208
7803
|
const fieldIdSet = new Set(fieldIds);
|
|
@@ -7215,7 +7810,9 @@ function removeMany(ctx, ids) {
|
|
|
7215
7810
|
});
|
|
7216
7811
|
const deleted = /* @__PURE__ */ new Set();
|
|
7217
7812
|
for (const optionId of optionIds) {
|
|
7218
|
-
|
|
7813
|
+
for (const removedId of removeOptionInPlace(p, optionId)) {
|
|
7814
|
+
deleted.add(removedId);
|
|
7815
|
+
}
|
|
7219
7816
|
}
|
|
7220
7817
|
for (const fieldId of fieldIds) {
|
|
7221
7818
|
const removedIds = removeFieldInPlace(p, fieldId);
|
|
@@ -7230,7 +7827,7 @@ function removeMany(ctx, ids) {
|
|
|
7230
7827
|
});
|
|
7231
7828
|
}
|
|
7232
7829
|
function getNode(ctx, id) {
|
|
7233
|
-
var _a, _b, _c
|
|
7830
|
+
var _a, _b, _c;
|
|
7234
7831
|
const props = ctx.getProps();
|
|
7235
7832
|
if (ctx.isTagId(id)) {
|
|
7236
7833
|
const t = ((_a = props.filters) != null ? _a : []).find((x) => x.id === id);
|
|
@@ -7247,8 +7844,7 @@ function getNode(ctx, id) {
|
|
|
7247
7844
|
}
|
|
7248
7845
|
if (ctx.isOptionId(id)) {
|
|
7249
7846
|
const own = ownerOfOption(props, id);
|
|
7250
|
-
const
|
|
7251
|
-
const o = (_d = f == null ? void 0 : f.options) == null ? void 0 : _d.find((x) => x.id === id);
|
|
7847
|
+
const o = (_c = findMutableOption(props, id)) == null ? void 0 : _c.option;
|
|
7252
7848
|
return {
|
|
7253
7849
|
kind: "option",
|
|
7254
7850
|
data: o,
|
|
@@ -7785,7 +8381,7 @@ function connect(ctx, kind, fromId, toId2) {
|
|
|
7785
8381
|
ctx.exec({
|
|
7786
8382
|
name: `connect:${kind}`,
|
|
7787
8383
|
do: () => ctx.patchProps((p) => {
|
|
7788
|
-
var _a, _b, _c, _d, _e, _f, _g
|
|
8384
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
7789
8385
|
if (kind === "bind") {
|
|
7790
8386
|
if (ctx.isTagId(fromId) && ctx.isTagId(toId2)) {
|
|
7791
8387
|
if (wouldCreateTagCycle(ctx, p, fromId, toId2)) {
|
|
@@ -7865,12 +8461,10 @@ function connect(ctx, kind, fromId, toId2) {
|
|
|
7865
8461
|
return;
|
|
7866
8462
|
}
|
|
7867
8463
|
if (toId2.startsWith("o:")) {
|
|
7868
|
-
|
|
7869
|
-
|
|
7870
|
-
|
|
7871
|
-
|
|
7872
|
-
return;
|
|
7873
|
-
}
|
|
8464
|
+
const o = (_g = findMutableOption(p, toId2)) == null ? void 0 : _g.option;
|
|
8465
|
+
if (o) {
|
|
8466
|
+
o.service_id = fromId;
|
|
8467
|
+
return;
|
|
7874
8468
|
}
|
|
7875
8469
|
return;
|
|
7876
8470
|
}
|
|
@@ -7887,7 +8481,7 @@ function disconnect(ctx, kind, fromId, toId2) {
|
|
|
7887
8481
|
ctx.exec({
|
|
7888
8482
|
name: `disconnect:${kind}`,
|
|
7889
8483
|
do: () => ctx.patchProps((p) => {
|
|
7890
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i
|
|
8484
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
7891
8485
|
if (kind === "bind") {
|
|
7892
8486
|
if (ctx.isTagId(fromId) && ctx.isTagId(toId2)) {
|
|
7893
8487
|
const child = ((_a = p.filters) != null ? _a : []).find(
|
|
@@ -7963,12 +8557,10 @@ function disconnect(ctx, kind, fromId, toId2) {
|
|
|
7963
8557
|
return;
|
|
7964
8558
|
}
|
|
7965
8559
|
if (toId2.startsWith("o:")) {
|
|
7966
|
-
|
|
7967
|
-
|
|
7968
|
-
|
|
7969
|
-
|
|
7970
|
-
return;
|
|
7971
|
-
}
|
|
8560
|
+
const o = (_i = findMutableOption(p, toId2)) == null ? void 0 : _i.option;
|
|
8561
|
+
if (o) {
|
|
8562
|
+
delete o.service_id;
|
|
8563
|
+
return;
|
|
7972
8564
|
}
|
|
7973
8565
|
return;
|
|
7974
8566
|
}
|
|
@@ -7991,6 +8583,250 @@ function addMappedField(p, mapKey, fromId, toId2) {
|
|
|
7991
8583
|
p[mapKey] = maps;
|
|
7992
8584
|
}
|
|
7993
8585
|
|
|
8586
|
+
// src/react/canvas/editor/editor-option-effects.ts
|
|
8587
|
+
function assertCanonicalId(id, label) {
|
|
8588
|
+
if (!id || id.includes("::") || id.includes("/")) {
|
|
8589
|
+
throw new Error(
|
|
8590
|
+
`${label}: expected a raw field or option id, not a composite/path id`
|
|
8591
|
+
);
|
|
8592
|
+
}
|
|
8593
|
+
}
|
|
8594
|
+
function assertTrigger(ctx, triggerId) {
|
|
8595
|
+
assertCanonicalId(triggerId, "option effect trigger");
|
|
8596
|
+
const trigger = ctx.getNode(triggerId);
|
|
8597
|
+
if (trigger.kind === "option" && trigger.data) return;
|
|
8598
|
+
if (trigger.kind === "field" && trigger.data && isActualButtonField(trigger.data)) {
|
|
8599
|
+
return;
|
|
8600
|
+
}
|
|
8601
|
+
throw new Error(
|
|
8602
|
+
"option effect trigger must be an option id or button field id"
|
|
8603
|
+
);
|
|
8604
|
+
}
|
|
8605
|
+
function assertTargetField(props, targetFieldId) {
|
|
8606
|
+
var _a;
|
|
8607
|
+
assertCanonicalId(targetFieldId, "option effect target");
|
|
8608
|
+
const field = ((_a = props.fields) != null ? _a : []).find((item) => item.id === targetFieldId);
|
|
8609
|
+
if (!field) {
|
|
8610
|
+
throw new Error(`option effect target field not found: ${targetFieldId}`);
|
|
8611
|
+
}
|
|
8612
|
+
return field;
|
|
8613
|
+
}
|
|
8614
|
+
function dedupe2(values) {
|
|
8615
|
+
if (!values) return void 0;
|
|
8616
|
+
const out = [];
|
|
8617
|
+
for (const value of values) {
|
|
8618
|
+
const id = String(value);
|
|
8619
|
+
if (!id || out.includes(id)) continue;
|
|
8620
|
+
out.push(id);
|
|
8621
|
+
}
|
|
8622
|
+
return out.length ? out : void 0;
|
|
8623
|
+
}
|
|
8624
|
+
function assertTargetOptions(props, targetFieldId, ids, kind) {
|
|
8625
|
+
if (!(ids == null ? void 0 : ids.length)) return;
|
|
8626
|
+
const field = assertTargetField(props, targetFieldId);
|
|
8627
|
+
const valid = fieldOptionIdSet(field);
|
|
8628
|
+
for (const id of ids) {
|
|
8629
|
+
assertCanonicalId(String(id), `option effect ${kind} option`);
|
|
8630
|
+
if (!valid.has(String(id))) {
|
|
8631
|
+
throw new Error(
|
|
8632
|
+
`option effect ${kind} option not found under ${targetFieldId}: ${String(id)}`
|
|
8633
|
+
);
|
|
8634
|
+
}
|
|
8635
|
+
}
|
|
8636
|
+
}
|
|
8637
|
+
function normalizeEffect(effect) {
|
|
8638
|
+
var _a;
|
|
8639
|
+
if (!effect) return void 0;
|
|
8640
|
+
const exclude2 = dedupe2(effect.exclude);
|
|
8641
|
+
const excluded = new Set(exclude2 != null ? exclude2 : []);
|
|
8642
|
+
const include2 = (_a = dedupe2(effect.include)) == null ? void 0 : _a.filter((id) => !excluded.has(id));
|
|
8643
|
+
const out = {};
|
|
8644
|
+
if (effect.forceVisible === true) out.forceVisible = true;
|
|
8645
|
+
if (include2 == null ? void 0 : include2.length) out.include = include2;
|
|
8646
|
+
if (exclude2 == null ? void 0 : exclude2.length) out.exclude = exclude2;
|
|
8647
|
+
return Object.keys(out).length ? out : void 0;
|
|
8648
|
+
}
|
|
8649
|
+
function ensureTargetMap(props, triggerId) {
|
|
8650
|
+
var _a, _b, _c;
|
|
8651
|
+
(_a = props.option_effects_for_buttons) != null ? _a : props.option_effects_for_buttons = {};
|
|
8652
|
+
(_c = (_b = props.option_effects_for_buttons)[triggerId]) != null ? _c : _b[triggerId] = {};
|
|
8653
|
+
return props.option_effects_for_buttons[triggerId];
|
|
8654
|
+
}
|
|
8655
|
+
function pruneEffectMap(props, triggerId) {
|
|
8656
|
+
const map = props.option_effects_for_buttons;
|
|
8657
|
+
if (!map) return;
|
|
8658
|
+
const keys = triggerId ? [triggerId] : Object.keys(map);
|
|
8659
|
+
for (const key of keys) {
|
|
8660
|
+
const targets = map[key];
|
|
8661
|
+
if (!targets || Object.keys(targets).length === 0) delete map[key];
|
|
8662
|
+
}
|
|
8663
|
+
if (Object.keys(map).length === 0) delete props.option_effects_for_buttons;
|
|
8664
|
+
}
|
|
8665
|
+
function validateEffect(ctx, props, triggerId, targetFieldId, effect) {
|
|
8666
|
+
assertTrigger(ctx, triggerId);
|
|
8667
|
+
assertTargetField(props, targetFieldId);
|
|
8668
|
+
assertTargetOptions(props, targetFieldId, effect == null ? void 0 : effect.include, "include");
|
|
8669
|
+
assertTargetOptions(props, targetFieldId, effect == null ? void 0 : effect.exclude, "exclude");
|
|
8670
|
+
return normalizeEffect(effect);
|
|
8671
|
+
}
|
|
8672
|
+
function setOptionEffect(ctx, triggerId, targetFieldId, effect) {
|
|
8673
|
+
ctx.exec({
|
|
8674
|
+
name: "setOptionEffect",
|
|
8675
|
+
do: () => ctx.patchProps((props) => {
|
|
8676
|
+
var _a;
|
|
8677
|
+
const normalized = validateEffect(
|
|
8678
|
+
ctx,
|
|
8679
|
+
props,
|
|
8680
|
+
triggerId,
|
|
8681
|
+
targetFieldId,
|
|
8682
|
+
effect
|
|
8683
|
+
);
|
|
8684
|
+
if (!normalized) {
|
|
8685
|
+
const map = (_a = props.option_effects_for_buttons) == null ? void 0 : _a[triggerId];
|
|
8686
|
+
if (map) delete map[targetFieldId];
|
|
8687
|
+
pruneEffectMap(props, triggerId);
|
|
8688
|
+
return;
|
|
8689
|
+
}
|
|
8690
|
+
ensureTargetMap(props, triggerId)[targetFieldId] = normalized;
|
|
8691
|
+
}),
|
|
8692
|
+
undo: () => ctx.undo()
|
|
8693
|
+
});
|
|
8694
|
+
}
|
|
8695
|
+
function patchOptionEffect(ctx, triggerId, targetFieldId, patch) {
|
|
8696
|
+
ctx.exec({
|
|
8697
|
+
name: "patchOptionEffect",
|
|
8698
|
+
do: () => ctx.patchProps((props) => {
|
|
8699
|
+
var _a, _b, _c, _d;
|
|
8700
|
+
const current = (_c = (_b = (_a = props.option_effects_for_buttons) == null ? void 0 : _a[triggerId]) == null ? void 0 : _b[targetFieldId]) != null ? _c : {};
|
|
8701
|
+
const merged = {
|
|
8702
|
+
...current,
|
|
8703
|
+
...patch
|
|
8704
|
+
};
|
|
8705
|
+
const normalized = validateEffect(
|
|
8706
|
+
ctx,
|
|
8707
|
+
props,
|
|
8708
|
+
triggerId,
|
|
8709
|
+
targetFieldId,
|
|
8710
|
+
merged
|
|
8711
|
+
);
|
|
8712
|
+
if (!normalized) {
|
|
8713
|
+
const map = (_d = props.option_effects_for_buttons) == null ? void 0 : _d[triggerId];
|
|
8714
|
+
if (map) delete map[targetFieldId];
|
|
8715
|
+
pruneEffectMap(props, triggerId);
|
|
8716
|
+
return;
|
|
8717
|
+
}
|
|
8718
|
+
ensureTargetMap(props, triggerId)[targetFieldId] = normalized;
|
|
8719
|
+
}),
|
|
8720
|
+
undo: () => ctx.undo()
|
|
8721
|
+
});
|
|
8722
|
+
}
|
|
8723
|
+
function clearOptionEffect(ctx, triggerId, targetFieldId) {
|
|
8724
|
+
ctx.exec({
|
|
8725
|
+
name: "clearOptionEffect",
|
|
8726
|
+
do: () => ctx.patchProps((props) => {
|
|
8727
|
+
var _a;
|
|
8728
|
+
const map = (_a = props.option_effects_for_buttons) == null ? void 0 : _a[triggerId];
|
|
8729
|
+
if (!map) return;
|
|
8730
|
+
delete map[targetFieldId];
|
|
8731
|
+
pruneEffectMap(props, triggerId);
|
|
8732
|
+
}),
|
|
8733
|
+
undo: () => ctx.undo()
|
|
8734
|
+
});
|
|
8735
|
+
}
|
|
8736
|
+
function clearOptionEffectsForTrigger(ctx, triggerId) {
|
|
8737
|
+
ctx.exec({
|
|
8738
|
+
name: "clearOptionEffectsForTrigger",
|
|
8739
|
+
do: () => ctx.patchProps((props) => {
|
|
8740
|
+
if (!props.option_effects_for_buttons) return;
|
|
8741
|
+
delete props.option_effects_for_buttons[triggerId];
|
|
8742
|
+
pruneEffectMap(props);
|
|
8743
|
+
}),
|
|
8744
|
+
undo: () => ctx.undo()
|
|
8745
|
+
});
|
|
8746
|
+
}
|
|
8747
|
+
function clearOptionEffectsForTarget(ctx, targetFieldId) {
|
|
8748
|
+
ctx.exec({
|
|
8749
|
+
name: "clearOptionEffectsForTarget",
|
|
8750
|
+
do: () => ctx.patchProps((props) => {
|
|
8751
|
+
var _a;
|
|
8752
|
+
const map = props.option_effects_for_buttons;
|
|
8753
|
+
if (!map) return;
|
|
8754
|
+
for (const triggerId of Object.keys(map)) {
|
|
8755
|
+
(_a = map[triggerId]) == null ? true : delete _a[targetFieldId];
|
|
8756
|
+
}
|
|
8757
|
+
pruneEffectMap(props);
|
|
8758
|
+
}),
|
|
8759
|
+
undo: () => ctx.undo()
|
|
8760
|
+
});
|
|
8761
|
+
}
|
|
8762
|
+
function addOptionEffectOptions(ctx, triggerId, targetFieldId, kind, optionIds) {
|
|
8763
|
+
var _a;
|
|
8764
|
+
const additions = (_a = dedupe2(optionIds)) != null ? _a : [];
|
|
8765
|
+
if (!additions.length) return;
|
|
8766
|
+
ctx.exec({
|
|
8767
|
+
name: "addOptionEffectOptions",
|
|
8768
|
+
do: () => ctx.patchProps((props) => {
|
|
8769
|
+
var _a2, _b, _c, _d;
|
|
8770
|
+
const current = (_c = (_b = (_a2 = props.option_effects_for_buttons) == null ? void 0 : _a2[triggerId]) == null ? void 0 : _b[targetFieldId]) != null ? _c : {};
|
|
8771
|
+
const nextValues = dedupe2([
|
|
8772
|
+
...(_d = current[kind]) != null ? _d : [],
|
|
8773
|
+
...additions
|
|
8774
|
+
]);
|
|
8775
|
+
const normalized = validateEffect(
|
|
8776
|
+
ctx,
|
|
8777
|
+
props,
|
|
8778
|
+
triggerId,
|
|
8779
|
+
targetFieldId,
|
|
8780
|
+
{
|
|
8781
|
+
...current,
|
|
8782
|
+
[kind]: nextValues
|
|
8783
|
+
}
|
|
8784
|
+
);
|
|
8785
|
+
if (!normalized) return;
|
|
8786
|
+
ensureTargetMap(props, triggerId)[targetFieldId] = normalized;
|
|
8787
|
+
}),
|
|
8788
|
+
undo: () => ctx.undo()
|
|
8789
|
+
});
|
|
8790
|
+
}
|
|
8791
|
+
function removeOptionEffectOptions(ctx, triggerId, targetFieldId, kind, optionIds) {
|
|
8792
|
+
var _a;
|
|
8793
|
+
const removals = new Set((_a = dedupe2(optionIds)) != null ? _a : []);
|
|
8794
|
+
if (!removals.size) return;
|
|
8795
|
+
ctx.exec({
|
|
8796
|
+
name: "removeOptionEffectOptions",
|
|
8797
|
+
do: () => ctx.patchProps((props) => {
|
|
8798
|
+
var _a2, _b, _c, _d, _e;
|
|
8799
|
+
const current = (_b = (_a2 = props.option_effects_for_buttons) == null ? void 0 : _a2[triggerId]) == null ? void 0 : _b[targetFieldId];
|
|
8800
|
+
if (!current) return;
|
|
8801
|
+
const next = {
|
|
8802
|
+
...current,
|
|
8803
|
+
[kind]: ((_c = current[kind]) != null ? _c : []).filter(
|
|
8804
|
+
(optionId) => !removals.has(optionId)
|
|
8805
|
+
)
|
|
8806
|
+
};
|
|
8807
|
+
const normalized = validateEffect(
|
|
8808
|
+
ctx,
|
|
8809
|
+
props,
|
|
8810
|
+
triggerId,
|
|
8811
|
+
targetFieldId,
|
|
8812
|
+
next
|
|
8813
|
+
);
|
|
8814
|
+
if (!normalized) {
|
|
8815
|
+
(_e = (_d = props.option_effects_for_buttons) == null ? void 0 : _d[triggerId]) == null ? true : delete _e[targetFieldId];
|
|
8816
|
+
pruneEffectMap(props, triggerId);
|
|
8817
|
+
return;
|
|
8818
|
+
}
|
|
8819
|
+
ensureTargetMap(props, triggerId)[targetFieldId] = normalized;
|
|
8820
|
+
}),
|
|
8821
|
+
undo: () => ctx.undo()
|
|
8822
|
+
});
|
|
8823
|
+
}
|
|
8824
|
+
function setOptionEffectForceVisible(ctx, triggerId, targetFieldId, forceVisible) {
|
|
8825
|
+
patchOptionEffect(ctx, triggerId, targetFieldId, {
|
|
8826
|
+
forceVisible: forceVisible === true ? true : void 0
|
|
8827
|
+
});
|
|
8828
|
+
}
|
|
8829
|
+
|
|
7994
8830
|
// src/react/canvas/editor/editor-service-filter.ts
|
|
7995
8831
|
function filterServicesForVisibleGroup2(ctx, candidates, input) {
|
|
7996
8832
|
const coreInput = {
|
|
@@ -8577,7 +9413,7 @@ var Editor = class {
|
|
|
8577
9413
|
if (!ordered.length) return;
|
|
8578
9414
|
this.transact("clearServiceMany", () => {
|
|
8579
9415
|
this.patchProps((p) => {
|
|
8580
|
-
var _a, _b
|
|
9416
|
+
var _a, _b;
|
|
8581
9417
|
for (const id of ordered) {
|
|
8582
9418
|
if (this.isTagId(id)) {
|
|
8583
9419
|
const t = ((_a = p.filters) != null ? _a : []).find((x) => x.id === id);
|
|
@@ -8590,10 +9426,8 @@ var Editor = class {
|
|
|
8590
9426
|
continue;
|
|
8591
9427
|
}
|
|
8592
9428
|
if (this.isOptionId(id)) {
|
|
8593
|
-
const
|
|
8594
|
-
|
|
8595
|
-
const f = ((_c = p.fields) != null ? _c : []).find((x) => x.id === own.fieldId);
|
|
8596
|
-
const o = (_d = f == null ? void 0 : f.options) == null ? void 0 : _d.find((x) => x.id === id);
|
|
9429
|
+
const found = findMutableOption(p, id);
|
|
9430
|
+
const o = found == null ? void 0 : found.option;
|
|
8597
9431
|
if (o && "service_id" in o) delete o.service_id;
|
|
8598
9432
|
}
|
|
8599
9433
|
}
|
|
@@ -8642,7 +9476,7 @@ var Editor = class {
|
|
|
8642
9476
|
if (!selected.size) return;
|
|
8643
9477
|
this.transact("clearRelationsMany", () => {
|
|
8644
9478
|
this.patchProps((p) => {
|
|
8645
|
-
var _a, _b, _c;
|
|
9479
|
+
var _a, _b, _c, _d, _e;
|
|
8646
9480
|
const clearOwned = mode === "owned" || mode === "both";
|
|
8647
9481
|
const clearIncoming = mode === "incoming" || mode === "both";
|
|
8648
9482
|
for (const t of (_a = p.filters) != null ? _a : []) {
|
|
@@ -8682,6 +9516,44 @@ var Editor = class {
|
|
|
8682
9516
|
}
|
|
8683
9517
|
if (!Object.keys(map).length) delete p[k];
|
|
8684
9518
|
}
|
|
9519
|
+
const effectMap = p.option_effects_for_buttons;
|
|
9520
|
+
if (effectMap) {
|
|
9521
|
+
for (const triggerId of Object.keys(effectMap)) {
|
|
9522
|
+
if (clearOwned && selected.has(String(triggerId))) {
|
|
9523
|
+
delete effectMap[triggerId];
|
|
9524
|
+
continue;
|
|
9525
|
+
}
|
|
9526
|
+
const targets = effectMap[triggerId];
|
|
9527
|
+
if (!targets || !clearIncoming) continue;
|
|
9528
|
+
for (const targetFieldId of Object.keys(targets)) {
|
|
9529
|
+
if (selected.has(String(targetFieldId))) {
|
|
9530
|
+
delete targets[targetFieldId];
|
|
9531
|
+
continue;
|
|
9532
|
+
}
|
|
9533
|
+
const effect = targets[targetFieldId];
|
|
9534
|
+
if (!effect) continue;
|
|
9535
|
+
if (effect.include) {
|
|
9536
|
+
effect.include = effect.include.filter(
|
|
9537
|
+
(optionId) => !selected.has(String(optionId))
|
|
9538
|
+
);
|
|
9539
|
+
if (!effect.include.length) delete effect.include;
|
|
9540
|
+
}
|
|
9541
|
+
if (effect.exclude) {
|
|
9542
|
+
effect.exclude = effect.exclude.filter(
|
|
9543
|
+
(optionId) => !selected.has(String(optionId))
|
|
9544
|
+
);
|
|
9545
|
+
if (!effect.exclude.length) delete effect.exclude;
|
|
9546
|
+
}
|
|
9547
|
+
if (effect.forceVisible !== true && !((_d = effect.include) == null ? void 0 : _d.length) && !((_e = effect.exclude) == null ? void 0 : _e.length)) {
|
|
9548
|
+
delete targets[targetFieldId];
|
|
9549
|
+
}
|
|
9550
|
+
}
|
|
9551
|
+
if (!Object.keys(targets).length) delete effectMap[triggerId];
|
|
9552
|
+
}
|
|
9553
|
+
if (!Object.keys(effectMap).length) {
|
|
9554
|
+
delete p.option_effects_for_buttons;
|
|
9555
|
+
}
|
|
9556
|
+
}
|
|
8685
9557
|
});
|
|
8686
9558
|
});
|
|
8687
9559
|
}
|
|
@@ -8693,7 +9565,7 @@ var Editor = class {
|
|
|
8693
9565
|
const suffix = (_b = input.suffix) != null ? _b : "";
|
|
8694
9566
|
this.transact("renameLabelsMany", () => {
|
|
8695
9567
|
this.patchProps((p) => {
|
|
8696
|
-
var _a2, _b2, _c, _d, _e, _f
|
|
9568
|
+
var _a2, _b2, _c, _d, _e, _f;
|
|
8697
9569
|
for (const id of ordered) {
|
|
8698
9570
|
if (this.isTagId(id)) {
|
|
8699
9571
|
const t = ((_a2 = p.filters) != null ? _a2 : []).find((x) => x.id === id);
|
|
@@ -8706,11 +9578,8 @@ var Editor = class {
|
|
|
8706
9578
|
continue;
|
|
8707
9579
|
}
|
|
8708
9580
|
if (this.isOptionId(id)) {
|
|
8709
|
-
const
|
|
8710
|
-
if (
|
|
8711
|
-
const f = ((_e = p.fields) != null ? _e : []).find((x) => x.id === own.fieldId);
|
|
8712
|
-
const o = (_f = f == null ? void 0 : f.options) == null ? void 0 : _f.find((x) => x.id === id);
|
|
8713
|
-
if (o) o.label = `${prefix}${(_g = o.label) != null ? _g : ""}${suffix}`.trim();
|
|
9581
|
+
const o = (_e = findMutableOption(p, id)) == null ? void 0 : _e.option;
|
|
9582
|
+
if (o) o.label = `${prefix}${(_f = o.label) != null ? _f : ""}${suffix}`.trim();
|
|
8714
9583
|
}
|
|
8715
9584
|
}
|
|
8716
9585
|
});
|
|
@@ -8863,6 +9732,57 @@ var Editor = class {
|
|
|
8863
9732
|
exclude(receiverId, idOrIds) {
|
|
8864
9733
|
return exclude(this.moduleCtx(), receiverId, idOrIds);
|
|
8865
9734
|
}
|
|
9735
|
+
setOptionEffect(triggerId, targetFieldId, effect) {
|
|
9736
|
+
return setOptionEffect(
|
|
9737
|
+
this.moduleCtx(),
|
|
9738
|
+
triggerId,
|
|
9739
|
+
targetFieldId,
|
|
9740
|
+
effect
|
|
9741
|
+
);
|
|
9742
|
+
}
|
|
9743
|
+
patchOptionEffect(triggerId, targetFieldId, patch) {
|
|
9744
|
+
return patchOptionEffect(
|
|
9745
|
+
this.moduleCtx(),
|
|
9746
|
+
triggerId,
|
|
9747
|
+
targetFieldId,
|
|
9748
|
+
patch
|
|
9749
|
+
);
|
|
9750
|
+
}
|
|
9751
|
+
clearOptionEffect(triggerId, targetFieldId) {
|
|
9752
|
+
return clearOptionEffect(this.moduleCtx(), triggerId, targetFieldId);
|
|
9753
|
+
}
|
|
9754
|
+
clearOptionEffectsForTrigger(triggerId) {
|
|
9755
|
+
return clearOptionEffectsForTrigger(this.moduleCtx(), triggerId);
|
|
9756
|
+
}
|
|
9757
|
+
clearOptionEffectsForTarget(targetFieldId) {
|
|
9758
|
+
return clearOptionEffectsForTarget(this.moduleCtx(), targetFieldId);
|
|
9759
|
+
}
|
|
9760
|
+
addOptionEffectOptions(triggerId, targetFieldId, kind, optionIds) {
|
|
9761
|
+
return addOptionEffectOptions(
|
|
9762
|
+
this.moduleCtx(),
|
|
9763
|
+
triggerId,
|
|
9764
|
+
targetFieldId,
|
|
9765
|
+
kind,
|
|
9766
|
+
optionIds
|
|
9767
|
+
);
|
|
9768
|
+
}
|
|
9769
|
+
removeOptionEffectOptions(triggerId, targetFieldId, kind, optionIds) {
|
|
9770
|
+
return removeOptionEffectOptions(
|
|
9771
|
+
this.moduleCtx(),
|
|
9772
|
+
triggerId,
|
|
9773
|
+
targetFieldId,
|
|
9774
|
+
kind,
|
|
9775
|
+
optionIds
|
|
9776
|
+
);
|
|
9777
|
+
}
|
|
9778
|
+
setOptionEffectForceVisible(triggerId, targetFieldId, forceVisible) {
|
|
9779
|
+
return setOptionEffectForceVisible(
|
|
9780
|
+
this.moduleCtx(),
|
|
9781
|
+
triggerId,
|
|
9782
|
+
targetFieldId,
|
|
9783
|
+
forceVisible
|
|
9784
|
+
);
|
|
9785
|
+
}
|
|
8866
9786
|
connect(kind, fromId, toId2) {
|
|
8867
9787
|
return connect(this.moduleCtx(), kind, fromId, toId2);
|
|
8868
9788
|
}
|
|
@@ -9231,11 +10151,10 @@ var Selection = class {
|
|
|
9231
10151
|
* What counts as a "button selection" (trigger key):
|
|
9232
10152
|
* - field key where the field has button === true (e.g. "f:dripfeed")
|
|
9233
10153
|
* - option key (e.g. "o:fast")
|
|
9234
|
-
* - composite key "fieldId::optionId" (e.g. "f:speed::o:fast")
|
|
9235
10154
|
*
|
|
9236
10155
|
* Grouping:
|
|
9237
10156
|
* - button-field trigger groups under its own fieldId
|
|
9238
|
-
* - option
|
|
10157
|
+
* - option trigger groups under the option's owning fieldId (from nodeMap)
|
|
9239
10158
|
*
|
|
9240
10159
|
* Deterministic:
|
|
9241
10160
|
* - preserves selection insertion order
|
|
@@ -9252,15 +10171,6 @@ var Selection = class {
|
|
|
9252
10171
|
};
|
|
9253
10172
|
for (const key of this.set) {
|
|
9254
10173
|
if (!key) continue;
|
|
9255
|
-
const idx = key.indexOf("::");
|
|
9256
|
-
if (idx !== -1) {
|
|
9257
|
-
const optionId = key.slice(idx + 2);
|
|
9258
|
-
const optRef = nodeMap.get(optionId);
|
|
9259
|
-
if ((optRef == null ? void 0 : optRef.kind) === "option" && typeof optRef.fieldId === "string") {
|
|
9260
|
-
push(optRef.fieldId, key);
|
|
9261
|
-
}
|
|
9262
|
-
continue;
|
|
9263
|
-
}
|
|
9264
10174
|
const ref = nodeMap.get(key);
|
|
9265
10175
|
if (!ref) continue;
|
|
9266
10176
|
if (ref.kind === "option" && typeof ref.fieldId === "string") {
|
|
@@ -9281,7 +10191,6 @@ var Selection = class {
|
|
|
9281
10191
|
* Returns only selection keys that are valid "trigger buttons":
|
|
9282
10192
|
* - field keys where field.button === true
|
|
9283
10193
|
* - option keys
|
|
9284
|
-
* - composite keys "fieldId::optionId" (validated by optionId)
|
|
9285
10194
|
* Excludes tags and non-button fields.
|
|
9286
10195
|
*/
|
|
9287
10196
|
selectedButtons() {
|
|
@@ -9297,13 +10206,6 @@ var Selection = class {
|
|
|
9297
10206
|
};
|
|
9298
10207
|
for (const key of this.set) {
|
|
9299
10208
|
if (!key) continue;
|
|
9300
|
-
const idx = key.indexOf("::");
|
|
9301
|
-
if (idx !== -1) {
|
|
9302
|
-
const optionId = key.slice(idx + 2);
|
|
9303
|
-
const optRef = nodeMap.get(optionId);
|
|
9304
|
-
if ((optRef == null ? void 0 : optRef.kind) === "option") push(key);
|
|
9305
|
-
continue;
|
|
9306
|
-
}
|
|
9307
10209
|
const ref = nodeMap.get(key);
|
|
9308
10210
|
if (!ref) continue;
|
|
9309
10211
|
if (ref.kind === "option") {
|
|
@@ -9342,17 +10244,7 @@ var Selection = class {
|
|
|
9342
10244
|
const direct = fields.find((x) => x.id === id);
|
|
9343
10245
|
if (direct) return direct;
|
|
9344
10246
|
if (this.builder.isOptionId(id)) {
|
|
9345
|
-
return fields
|
|
9346
|
-
(x) => {
|
|
9347
|
-
var _a2;
|
|
9348
|
-
return ((_a2 = x.options) != null ? _a2 : []).some((o) => o.id === id);
|
|
9349
|
-
}
|
|
9350
|
-
);
|
|
9351
|
-
}
|
|
9352
|
-
if (id.includes("::")) {
|
|
9353
|
-
const [fieldId] = id.split("::");
|
|
9354
|
-
if (!fieldId) return void 0;
|
|
9355
|
-
return fields.find((x) => x.id === fieldId);
|
|
10247
|
+
return findOptionOwnerField(fields, id);
|
|
9356
10248
|
}
|
|
9357
10249
|
return void 0;
|
|
9358
10250
|
};
|
|
@@ -9383,18 +10275,7 @@ var Selection = class {
|
|
|
9383
10275
|
}
|
|
9384
10276
|
for (const id of this.set) {
|
|
9385
10277
|
if (this.builder.isOptionId(id)) {
|
|
9386
|
-
const host = fields
|
|
9387
|
-
(x) => {
|
|
9388
|
-
var _a2;
|
|
9389
|
-
return ((_a2 = x.options) != null ? _a2 : []).some((o) => o.id === id);
|
|
9390
|
-
}
|
|
9391
|
-
);
|
|
9392
|
-
if (host == null ? void 0 : host.bind_id)
|
|
9393
|
-
return Array.isArray(host.bind_id) ? host.bind_id[0] : host.bind_id;
|
|
9394
|
-
}
|
|
9395
|
-
if (id.includes("::")) {
|
|
9396
|
-
const [fid] = id.split("::");
|
|
9397
|
-
const host = fields.find((x) => x.id === fid);
|
|
10278
|
+
const host = findOptionOwnerField(fields, id);
|
|
9398
10279
|
if (host == null ? void 0 : host.bind_id)
|
|
9399
10280
|
return Array.isArray(host.bind_id) ? host.bind_id[0] : host.bind_id;
|
|
9400
10281
|
}
|
|
@@ -9408,7 +10289,11 @@ var Selection = class {
|
|
|
9408
10289
|
const tagById = new Map(tags.map((t) => [t.id, t]));
|
|
9409
10290
|
const tag = tagById.get(tagId);
|
|
9410
10291
|
const selectedTriggerIds = this.selectedButtons();
|
|
9411
|
-
const
|
|
10292
|
+
const visibility = this.builder.resolveVisibility(
|
|
10293
|
+
tagId,
|
|
10294
|
+
selectedTriggerIds
|
|
10295
|
+
);
|
|
10296
|
+
const fieldIds = visibility.fieldIds;
|
|
9412
10297
|
const fieldById = new Map(fields.map((f) => [f.id, f]));
|
|
9413
10298
|
const visible = fieldIds.map((id) => fieldById.get(id)).filter(Boolean);
|
|
9414
10299
|
const parentTags = [];
|
|
@@ -9434,6 +10319,14 @@ var Selection = class {
|
|
|
9434
10319
|
let baseOverridden = false;
|
|
9435
10320
|
for (const selId of this.set) {
|
|
9436
10321
|
const opt = this.findOptionById(fields, selId);
|
|
10322
|
+
if (opt && !this.isSelectedOptionVisible(
|
|
10323
|
+
fields,
|
|
10324
|
+
selId,
|
|
10325
|
+
fieldIds,
|
|
10326
|
+
visibility.optionsByFieldId
|
|
10327
|
+
)) {
|
|
10328
|
+
continue;
|
|
10329
|
+
}
|
|
9437
10330
|
if ((opt == null ? void 0 : opt.service_id) != null) {
|
|
9438
10331
|
const role = (_d = opt.pricing_role) != null ? _d : "base";
|
|
9439
10332
|
const cap = (_e = resolve == null ? void 0 : resolve(opt.service_id)) != null ? _e : { id: opt.service_id };
|
|
@@ -9464,6 +10357,8 @@ var Selection = class {
|
|
|
9464
10357
|
tag,
|
|
9465
10358
|
fields: visible,
|
|
9466
10359
|
fieldIds,
|
|
10360
|
+
optionsByFieldId: visibility.optionsByFieldId,
|
|
10361
|
+
forcedFieldIds: visibility.forcedFieldIds,
|
|
9467
10362
|
parentTags,
|
|
9468
10363
|
childrenTags,
|
|
9469
10364
|
services
|
|
@@ -9487,21 +10382,19 @@ var Selection = class {
|
|
|
9487
10382
|
return baseOverridden;
|
|
9488
10383
|
}
|
|
9489
10384
|
findOptionById(fields, selId) {
|
|
9490
|
-
var _a, _b;
|
|
9491
10385
|
if (this.builder.isOptionId(selId)) {
|
|
9492
|
-
|
|
9493
|
-
|
|
9494
|
-
if (o) return o;
|
|
9495
|
-
}
|
|
9496
|
-
}
|
|
9497
|
-
if (selId.includes("::")) {
|
|
9498
|
-
const [fid, oid] = selId.split("::");
|
|
9499
|
-
const f = fields.find((x) => x.id === fid);
|
|
9500
|
-
const o = (_b = f == null ? void 0 : f.options) == null ? void 0 : _b.find((x) => x.id === oid || x.id === selId);
|
|
9501
|
-
if (o) return o;
|
|
10386
|
+
const field = findOptionOwnerField(fields, selId);
|
|
10387
|
+
return findFieldOption(field, selId);
|
|
9502
10388
|
}
|
|
9503
10389
|
return void 0;
|
|
9504
10390
|
}
|
|
10391
|
+
isSelectedOptionVisible(fields, selId, visibleFieldIds, optionsByFieldId) {
|
|
10392
|
+
const visibleFields = new Set(visibleFieldIds);
|
|
10393
|
+
const field = findOptionOwnerField(fields, selId);
|
|
10394
|
+
if (!field || !visibleFields.has(field.id)) return false;
|
|
10395
|
+
const allowed = optionsByFieldId[field.id];
|
|
10396
|
+
return !allowed || allowed.includes(selId);
|
|
10397
|
+
}
|
|
9505
10398
|
};
|
|
9506
10399
|
|
|
9507
10400
|
// src/react/canvas/api.ts
|
|
@@ -10404,11 +11297,83 @@ function useOrderFlow() {
|
|
|
10404
11297
|
if (!ready) return void 0;
|
|
10405
11298
|
return (_c2 = (_b2 = (_a2 = ctx.selection) == null ? void 0 : _a2.currentTag) == null ? void 0 : _b2.call(_a2)) != null ? _c2 : ctx.activeTagId;
|
|
10406
11299
|
}, [ready, ctx.selection, ctx.activeTagId, selTick]);
|
|
11300
|
+
const visibleOptionsByFieldId = (0, import_react6.useMemo)(
|
|
11301
|
+
() => {
|
|
11302
|
+
var _a2;
|
|
11303
|
+
return (_a2 = visibleGroup == null ? void 0 : visibleGroup.optionsByFieldId) != null ? _a2 : {};
|
|
11304
|
+
},
|
|
11305
|
+
[visibleGroup]
|
|
11306
|
+
);
|
|
11307
|
+
const forcedFieldIds = (0, import_react6.useMemo)(
|
|
11308
|
+
() => {
|
|
11309
|
+
var _a2;
|
|
11310
|
+
return (_a2 = visibleGroup == null ? void 0 : visibleGroup.forcedFieldIds) != null ? _a2 : [];
|
|
11311
|
+
},
|
|
11312
|
+
[visibleGroup]
|
|
11313
|
+
);
|
|
10407
11314
|
const formValuesByFieldId = (0, import_react6.useMemo)(() => {
|
|
10408
11315
|
var _a2, _b2, _c2;
|
|
10409
11316
|
const values = (_c2 = (_b2 = (_a2 = ctx.formApi).snapshot) == null ? void 0 : _b2.call(_a2)) != null ? _c2 : {};
|
|
10410
11317
|
return values;
|
|
10411
11318
|
}, [ctx.formApi, formTick]);
|
|
11319
|
+
(0, import_react6.useEffect)(() => {
|
|
11320
|
+
var _a2, _b2, _c2, _d;
|
|
11321
|
+
if (!ready || !ctx.selection) return;
|
|
11322
|
+
const { builder, selection } = ctx.ensureReady("pruneHiddenOptions");
|
|
11323
|
+
const fields = (_a2 = builder.getProps().fields) != null ? _a2 : [];
|
|
11324
|
+
const visibleOptionEntries = Object.entries(visibleOptionsByFieldId);
|
|
11325
|
+
if (!visibleOptionEntries.length) return;
|
|
11326
|
+
const visibleOptionSets = new Map(
|
|
11327
|
+
visibleOptionEntries.map(([fieldId, optionIds]) => [
|
|
11328
|
+
fieldId,
|
|
11329
|
+
new Set(optionIds)
|
|
11330
|
+
])
|
|
11331
|
+
);
|
|
11332
|
+
const changedFieldIds = /* @__PURE__ */ new Set();
|
|
11333
|
+
const ownerForToken = (token) => {
|
|
11334
|
+
if (!token) return void 0;
|
|
11335
|
+
const owner = findOptionOwnerField(fields, token);
|
|
11336
|
+
return owner == null ? void 0 : owner.id;
|
|
11337
|
+
};
|
|
11338
|
+
const retained = [];
|
|
11339
|
+
let changed = false;
|
|
11340
|
+
for (const token of selection.all()) {
|
|
11341
|
+
const ownerFieldId = ownerForToken(token);
|
|
11342
|
+
if (!ownerFieldId) {
|
|
11343
|
+
retained.push(token);
|
|
11344
|
+
continue;
|
|
11345
|
+
}
|
|
11346
|
+
const allowed = visibleOptionSets.get(ownerFieldId);
|
|
11347
|
+
if (!allowed) {
|
|
11348
|
+
retained.push(token);
|
|
11349
|
+
continue;
|
|
11350
|
+
}
|
|
11351
|
+
if (allowed.has(token)) {
|
|
11352
|
+
retained.push(token);
|
|
11353
|
+
continue;
|
|
11354
|
+
}
|
|
11355
|
+
changed = true;
|
|
11356
|
+
changedFieldIds.add(ownerFieldId);
|
|
11357
|
+
}
|
|
11358
|
+
if (!changed) return;
|
|
11359
|
+
for (const fieldId of changedFieldIds) {
|
|
11360
|
+
const allowed = visibleOptionSets.get(fieldId);
|
|
11361
|
+
const currentValue = ((_d = (_c2 = (_b2 = ctx.formApi).snapshot) == null ? void 0 : _c2.call(_b2)) != null ? _d : {})[fieldId];
|
|
11362
|
+
if (Array.isArray(currentValue)) {
|
|
11363
|
+
const next = currentValue.filter(
|
|
11364
|
+
(value) => allowed == null ? void 0 : allowed.has(String(value))
|
|
11365
|
+
);
|
|
11366
|
+
if (next.length !== currentValue.length) {
|
|
11367
|
+
ctx.formApi.set(fieldId, next.length ? next : void 0);
|
|
11368
|
+
}
|
|
11369
|
+
continue;
|
|
11370
|
+
}
|
|
11371
|
+
if (currentValue !== void 0 && allowed && !allowed.has(String(currentValue))) {
|
|
11372
|
+
ctx.formApi.set(fieldId, void 0);
|
|
11373
|
+
}
|
|
11374
|
+
}
|
|
11375
|
+
selection.many(retained, retained[retained.length - 1]);
|
|
11376
|
+
}, [ctx, ready, selTick, visibleOptionsByFieldId]);
|
|
10412
11377
|
const optionSelectionsByFieldId = (0, import_react6.useMemo)(
|
|
10413
11378
|
() => ({}),
|
|
10414
11379
|
[]
|
|
@@ -10556,7 +11521,7 @@ function useOrderFlow() {
|
|
|
10556
11521
|
);
|
|
10557
11522
|
const setFieldOptions = (0, import_react6.useCallback)(
|
|
10558
11523
|
(fieldId, optionIds) => {
|
|
10559
|
-
var _a2, _b2, _c2
|
|
11524
|
+
var _a2, _b2, _c2;
|
|
10560
11525
|
const { builder, selection, init } = ctx.ensureReady(
|
|
10561
11526
|
"setFieldOptions"
|
|
10562
11527
|
);
|
|
@@ -10564,7 +11529,9 @@ function useOrderFlow() {
|
|
|
10564
11529
|
const field = fields.find((f) => f.id === fieldId);
|
|
10565
11530
|
if (!field) return;
|
|
10566
11531
|
const validOptionIds = new Set(
|
|
10567
|
-
((
|
|
11532
|
+
Array.from(fieldOptionIdSet(field)).map(
|
|
11533
|
+
(optionId) => String(optionId)
|
|
11534
|
+
)
|
|
10568
11535
|
);
|
|
10569
11536
|
const dedupedValid = [];
|
|
10570
11537
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -10575,36 +11542,18 @@ function useOrderFlow() {
|
|
|
10575
11542
|
seen.add(optionId);
|
|
10576
11543
|
dedupedValid.push(optionId);
|
|
10577
11544
|
}
|
|
10578
|
-
const mode = (
|
|
10579
|
-
const isMulti = ((
|
|
11545
|
+
const mode = (_b2 = init.mode) != null ? _b2 : "prod";
|
|
11546
|
+
const isMulti = ((_c2 = field.meta) == null ? void 0 : _c2.multi) === true;
|
|
10580
11547
|
const normalized = mode === "prod" && !isMulti ? dedupedValid.length ? [dedupedValid[dedupedValid.length - 1]] : [] : dedupedValid;
|
|
10581
|
-
const fieldById = new Map(fields.map((f) => [f.id, f]));
|
|
10582
11548
|
const nodeMap = builder.getNodeMap();
|
|
10583
11549
|
const resolveOptionOwnerFieldId = (token) => {
|
|
10584
11550
|
var _a3;
|
|
10585
11551
|
if (!token) return void 0;
|
|
10586
|
-
if (token.includes("::")) {
|
|
10587
|
-
const [legacyFieldId, optionId] = token.split("::", 2);
|
|
10588
|
-
if (!optionId) return void 0;
|
|
10589
|
-
const optionRef2 = nodeMap.get(optionId);
|
|
10590
|
-
if ((optionRef2 == null ? void 0 : optionRef2.kind) === "option" && typeof optionRef2.fieldId === "string") {
|
|
10591
|
-
return optionRef2.fieldId;
|
|
10592
|
-
}
|
|
10593
|
-
if (legacyFieldId && fieldById.has(legacyFieldId)) {
|
|
10594
|
-
return legacyFieldId;
|
|
10595
|
-
}
|
|
10596
|
-
return void 0;
|
|
10597
|
-
}
|
|
10598
11552
|
const optionRef = nodeMap.get(token);
|
|
10599
11553
|
if ((optionRef == null ? void 0 : optionRef.kind) === "option" && typeof optionRef.fieldId === "string") {
|
|
10600
11554
|
return optionRef.fieldId;
|
|
10601
11555
|
}
|
|
10602
|
-
|
|
10603
|
-
if ((_a3 = f.options) == null ? void 0 : _a3.some((option) => option.id === token)) {
|
|
10604
|
-
return f.id;
|
|
10605
|
-
}
|
|
10606
|
-
}
|
|
10607
|
-
return void 0;
|
|
11556
|
+
return (_a3 = findOptionOwnerField(fields, token)) == null ? void 0 : _a3.id;
|
|
10608
11557
|
};
|
|
10609
11558
|
const retained = Array.from(selection.all()).filter(
|
|
10610
11559
|
(token) => resolveOptionOwnerFieldId(token) !== fieldId
|
|
@@ -10708,6 +11657,8 @@ function useOrderFlow() {
|
|
|
10708
11657
|
raw,
|
|
10709
11658
|
notices,
|
|
10710
11659
|
visibleGroup,
|
|
11660
|
+
visibleOptionsByFieldId,
|
|
11661
|
+
forcedFieldIds,
|
|
10711
11662
|
formValuesByFieldId,
|
|
10712
11663
|
optionSelectionsByFieldId,
|
|
10713
11664
|
quantityPreview: previewSnapshot.quantity,
|
|
@@ -10814,6 +11765,18 @@ function Wrapper({
|
|
|
10814
11765
|
const flow = useOrderFlow();
|
|
10815
11766
|
const kind = toKind(field);
|
|
10816
11767
|
const variant = toVariant(field);
|
|
11768
|
+
const renderedField = React4.useMemo(() => {
|
|
11769
|
+
var _a2;
|
|
11770
|
+
const visibleOptionIds = flow.visibleOptionsByFieldId[field.id];
|
|
11771
|
+
if (!visibleOptionIds) return field;
|
|
11772
|
+
return {
|
|
11773
|
+
...field,
|
|
11774
|
+
options: (_a2 = filterFieldOptionsById(
|
|
11775
|
+
field.options,
|
|
11776
|
+
new Set(visibleOptionIds)
|
|
11777
|
+
)) != null ? _a2 : []
|
|
11778
|
+
};
|
|
11779
|
+
}, [field, flow.visibleOptionsByFieldId]);
|
|
10817
11780
|
const descriptor = React4.useMemo(
|
|
10818
11781
|
() => resolveInputDescriptor(registry, kind, variant),
|
|
10819
11782
|
[kind, registry, variant]
|
|
@@ -10827,8 +11790,8 @@ function Wrapper({
|
|
|
10827
11790
|
const baseProps = (_b = descriptor.defaultProps) != null ? _b : {};
|
|
10828
11791
|
const defaultProps = (0, import_react7.useMemo)(() => {
|
|
10829
11792
|
var _a2;
|
|
10830
|
-
return { ...baseProps, ...(_a2 =
|
|
10831
|
-
}, [baseProps,
|
|
11793
|
+
return { ...baseProps, ...(_a2 = renderedField.defaults) != null ? _a2 : {} };
|
|
11794
|
+
}, [baseProps, renderedField.defaults]);
|
|
10832
11795
|
const valueProp = (_c = adapter.valueProp) != null ? _c : "value";
|
|
10833
11796
|
const changeProp = (_d = adapter.changeProp) != null ? _d : "onChange";
|
|
10834
11797
|
const errorProp = (_e = adapter.errorProp) != null ? _e : "errorText";
|
|
@@ -10842,13 +11805,14 @@ function Wrapper({
|
|
|
10842
11805
|
disabled: !!disabled
|
|
10843
11806
|
});
|
|
10844
11807
|
const optionIds = React4.useMemo(() => {
|
|
10845
|
-
var _a2;
|
|
10846
11808
|
if (!isOptionBased2) return /* @__PURE__ */ new Set();
|
|
10847
|
-
return new Set(
|
|
10848
|
-
|
|
11809
|
+
return new Set(
|
|
11810
|
+
Array.from(fieldOptionIdSet(renderedField)).map(String)
|
|
11811
|
+
);
|
|
11812
|
+
}, [isOptionBased2, renderedField]);
|
|
10849
11813
|
const adapterCtx = React4.useMemo(
|
|
10850
|
-
() => ({ field, props: flow.raw }),
|
|
10851
|
-
[
|
|
11814
|
+
() => ({ field: renderedField, props: flow.raw }),
|
|
11815
|
+
[renderedField, flow.raw]
|
|
10852
11816
|
);
|
|
10853
11817
|
const onHostChange = React4.useCallback(
|
|
10854
11818
|
(next) => {
|
|
@@ -10859,7 +11823,7 @@ function Wrapper({
|
|
|
10859
11823
|
if (isOptionBased2) {
|
|
10860
11824
|
if (!adapter.getSelectedOptions) {
|
|
10861
11825
|
throw new Error(
|
|
10862
|
-
`[Wrapper] Adapter for "${
|
|
11826
|
+
`[Wrapper] Adapter for "${renderedField.id}" (${renderedField.type}) must implement getSelectedOptions() because this field has options.`
|
|
10863
11827
|
);
|
|
10864
11828
|
}
|
|
10865
11829
|
const rawIds = adapter.getSelectedOptions(
|
|
@@ -10872,20 +11836,20 @@ function Wrapper({
|
|
|
10872
11836
|
(rawIds != null ? rawIds : []).map(String).filter((id) => optionIds.has(id))
|
|
10873
11837
|
)
|
|
10874
11838
|
);
|
|
10875
|
-
flow.setFieldOptions(
|
|
11839
|
+
flow.setFieldOptions(renderedField.id, nextIds);
|
|
10876
11840
|
return;
|
|
10877
11841
|
}
|
|
10878
11842
|
if (isActionButton) {
|
|
10879
11843
|
const isActive = (_e2 = (_d2 = adapter.isActive) == null ? void 0 : _d2.call(adapter, stored, adapterCtx)) != null ? _e2 : Boolean(stored);
|
|
10880
|
-
if (isActive) flow.toggleOption(
|
|
10881
|
-
else flow.clearField(
|
|
11844
|
+
if (isActive) flow.toggleOption(renderedField.id);
|
|
11845
|
+
else flow.clearField(renderedField.id);
|
|
10882
11846
|
}
|
|
10883
11847
|
},
|
|
10884
11848
|
[
|
|
10885
11849
|
adapter,
|
|
10886
11850
|
adapterCtx,
|
|
10887
|
-
|
|
10888
|
-
|
|
11851
|
+
renderedField.id,
|
|
11852
|
+
renderedField.type,
|
|
10889
11853
|
flow,
|
|
10890
11854
|
fp,
|
|
10891
11855
|
isActionButton,
|
|
@@ -10899,12 +11863,12 @@ function Wrapper({
|
|
|
10899
11863
|
const ctx = ctxOverrides && typeof ctxOverrides === "object" ? { ...ctxFromInit, ...ctxOverrides } : ctxFromInit;
|
|
10900
11864
|
return {
|
|
10901
11865
|
...ctx,
|
|
10902
|
-
field,
|
|
11866
|
+
field: renderedField,
|
|
10903
11867
|
flow,
|
|
10904
11868
|
value: fp.value,
|
|
10905
11869
|
error: fp.error
|
|
10906
11870
|
};
|
|
10907
|
-
}, [ctxOverrides,
|
|
11871
|
+
}, [ctxOverrides, renderedField, flow, fp.error, fp.value]);
|
|
10908
11872
|
const templatedDefaultProps = React4.useMemo(() => {
|
|
10909
11873
|
if (!templateStrings) return defaultProps;
|
|
10910
11874
|
return templateDeep(defaultProps, templateCtx);
|
|
@@ -10914,14 +11878,14 @@ function Wrapper({
|
|
|
10914
11878
|
return extraProps != null ? extraProps : {};
|
|
10915
11879
|
return templateDeep(extraProps != null ? extraProps : {}, templateCtx);
|
|
10916
11880
|
}, [extraProps, templateCtx, templateStrings]);
|
|
10917
|
-
const fieldProps = (_h = (_g = adapter == null ? void 0 : adapter.getInputPropsFromField) == null ? void 0 : _g.call(adapter, { field, props: flow.raw })) != null ? _h : {};
|
|
11881
|
+
const fieldProps = (_h = (_g = adapter == null ? void 0 : adapter.getInputPropsFromField) == null ? void 0 : _g.call(adapter, { field: renderedField, props: flow.raw })) != null ? _h : {};
|
|
10918
11882
|
const hostProps = {
|
|
10919
|
-
id:
|
|
10920
|
-
field,
|
|
11883
|
+
id: renderedField.id,
|
|
11884
|
+
field: renderedField,
|
|
10921
11885
|
disabled: !!disabled || !!fp.disabled,
|
|
10922
11886
|
required: field.required,
|
|
10923
11887
|
// DO NOT pass `name` to InputField/entries
|
|
10924
|
-
fieldKey:
|
|
11888
|
+
fieldKey: renderedField.id,
|
|
10925
11889
|
...fieldProps != null ? fieldProps : {},
|
|
10926
11890
|
// error channel
|
|
10927
11891
|
error: fp.error,
|
|
@@ -11927,7 +12891,10 @@ var treeSelectDescriptor = {
|
|
|
11927
12891
|
supported: true,
|
|
11928
12892
|
autoCreate: true,
|
|
11929
12893
|
defaultLabel: "Option label",
|
|
11930
|
-
defaultValue: "option"
|
|
12894
|
+
defaultValue: "option",
|
|
12895
|
+
children: {
|
|
12896
|
+
supported: true
|
|
12897
|
+
}
|
|
11931
12898
|
},
|
|
11932
12899
|
multi: {
|
|
11933
12900
|
supported: true,
|
|
@@ -13118,20 +14085,29 @@ function withInputFieldUi(desc) {
|
|
|
13118
14085
|
const fieldNotices = notices.filter(
|
|
13119
14086
|
(notice) => matchesNotice(field, notice)
|
|
13120
14087
|
);
|
|
14088
|
+
const mapOptionForInputField = (item) => {
|
|
14089
|
+
var _a3;
|
|
14090
|
+
const optionNotices = notices.filter(
|
|
14091
|
+
(notice) => matchesNotice(item, notice)
|
|
14092
|
+
);
|
|
14093
|
+
return {
|
|
14094
|
+
...item,
|
|
14095
|
+
tags: optionNotices.map(toTagPill),
|
|
14096
|
+
...((_a3 = item.children) == null ? void 0 : _a3.length) ? {
|
|
14097
|
+
children: item.children.map(
|
|
14098
|
+
mapOptionForInputField
|
|
14099
|
+
)
|
|
14100
|
+
} : {}
|
|
14101
|
+
};
|
|
14102
|
+
};
|
|
13121
14103
|
return {
|
|
13122
14104
|
label: field.label,
|
|
13123
14105
|
tags: fieldNotices.map(toTagPill),
|
|
13124
14106
|
required: field.required,
|
|
13125
14107
|
...((_b = field.options) == null ? void 0 : _b.length) ? {
|
|
13126
|
-
options: field.options.map(
|
|
13127
|
-
|
|
13128
|
-
|
|
13129
|
-
);
|
|
13130
|
-
return {
|
|
13131
|
-
...item,
|
|
13132
|
-
tags: optionNotices.map(toTagPill)
|
|
13133
|
-
};
|
|
13134
|
-
})
|
|
14108
|
+
options: field.options.map(
|
|
14109
|
+
mapOptionForInputField
|
|
14110
|
+
)
|
|
13135
14111
|
} : {}
|
|
13136
14112
|
};
|
|
13137
14113
|
},
|