@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.js
CHANGED
|
@@ -666,6 +666,9 @@ function normalise(input, opts = {}) {
|
|
|
666
666
|
const excludes_for_buttons = toStringArrayMap(
|
|
667
667
|
obj.excludes_for_buttons
|
|
668
668
|
);
|
|
669
|
+
const option_effects_for_buttons = toOptionEffectMap(
|
|
670
|
+
obj.option_effects_for_buttons
|
|
671
|
+
);
|
|
669
672
|
const orderKinds = toStringMap(obj.orderKinds);
|
|
670
673
|
const notices = toNoticeArray(obj.notices);
|
|
671
674
|
let filters = rawFilters.map((t) => coerceTag(t, constraints));
|
|
@@ -681,6 +684,9 @@ function normalise(input, opts = {}) {
|
|
|
681
684
|
...isNonEmpty(orderKinds) && { orderKinds },
|
|
682
685
|
...isNonEmpty(includes_for_buttons) && { includes_for_buttons },
|
|
683
686
|
...isNonEmpty(excludes_for_buttons) && { excludes_for_buttons },
|
|
687
|
+
...isNonEmpty(option_effects_for_buttons) && {
|
|
688
|
+
option_effects_for_buttons
|
|
689
|
+
},
|
|
684
690
|
...fallbacks && (isNonEmpty(fallbacks.nodes) || isNonEmpty(fallbacks.global)) && {
|
|
685
691
|
fallbacks
|
|
686
692
|
},
|
|
@@ -835,6 +841,7 @@ function coerceOption(src, inheritRole) {
|
|
|
835
841
|
const value = typeof src.value === "string" || typeof src.value === "number" ? src.value : void 0;
|
|
836
842
|
const pricing_role = src.pricing_role === "utility" || src.pricing_role === "base" ? src.pricing_role : inheritRole;
|
|
837
843
|
const meta = src.meta && typeof src.meta === "object" ? src.meta : void 0;
|
|
844
|
+
const children = Array.isArray(src.children) ? src.children.map((child) => coerceOption(child, pricing_role)) : void 0;
|
|
838
845
|
const option = {
|
|
839
846
|
id: "",
|
|
840
847
|
label: "",
|
|
@@ -843,7 +850,8 @@ function coerceOption(src, inheritRole) {
|
|
|
843
850
|
...value !== void 0 && { value },
|
|
844
851
|
...service_id !== void 0 && { service_id },
|
|
845
852
|
pricing_role,
|
|
846
|
-
...meta && { meta }
|
|
853
|
+
...meta && { meta },
|
|
854
|
+
...children && children.length && { children }
|
|
847
855
|
};
|
|
848
856
|
return option;
|
|
849
857
|
}
|
|
@@ -908,6 +916,35 @@ function toStringArrayMap(src) {
|
|
|
908
916
|
}
|
|
909
917
|
return Object.keys(out).length ? out : void 0;
|
|
910
918
|
}
|
|
919
|
+
function toOptionEffectMap(src) {
|
|
920
|
+
var _a, _b;
|
|
921
|
+
if (!src || typeof src !== "object") return void 0;
|
|
922
|
+
const out = {};
|
|
923
|
+
for (const [triggerId, rawTargets] of Object.entries(src)) {
|
|
924
|
+
if (!triggerId || !rawTargets || typeof rawTargets !== "object") {
|
|
925
|
+
continue;
|
|
926
|
+
}
|
|
927
|
+
const targets = {};
|
|
928
|
+
for (const [fieldId, rawEffect] of Object.entries(rawTargets)) {
|
|
929
|
+
if (!fieldId || !rawEffect || typeof rawEffect !== "object") {
|
|
930
|
+
continue;
|
|
931
|
+
}
|
|
932
|
+
const effect = rawEffect;
|
|
933
|
+
const include2 = toStringArray(effect.include);
|
|
934
|
+
const exclude2 = toStringArray(effect.exclude);
|
|
935
|
+
const next = {
|
|
936
|
+
...effect.forceVisible === true ? { forceVisible: true } : {},
|
|
937
|
+
...include2.length ? { include: dedupe(include2) } : {},
|
|
938
|
+
...exclude2.length ? { exclude: dedupe(exclude2) } : {}
|
|
939
|
+
};
|
|
940
|
+
if (next.forceVisible === true || ((_a = next.include) == null ? void 0 : _a.length) || ((_b = next.exclude) == null ? void 0 : _b.length)) {
|
|
941
|
+
targets[fieldId] = next;
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
if (Object.keys(targets).length) out[triggerId] = targets;
|
|
945
|
+
}
|
|
946
|
+
return Object.keys(out).length ? out : void 0;
|
|
947
|
+
}
|
|
911
948
|
function toStringArray(v) {
|
|
912
949
|
if (!Array.isArray(v)) return [];
|
|
913
950
|
return v.map((x) => String(x)).filter((s) => !!s && s.trim().length > 0);
|
|
@@ -982,6 +1019,72 @@ function normalizeFieldValidation(input) {
|
|
|
982
1019
|
return one ? [one] : void 0;
|
|
983
1020
|
}
|
|
984
1021
|
|
|
1022
|
+
// src/core/options.ts
|
|
1023
|
+
function walkFieldOptions(field) {
|
|
1024
|
+
const out = [];
|
|
1025
|
+
const visit = (options, depth, parentId) => {
|
|
1026
|
+
for (const option of options != null ? options : []) {
|
|
1027
|
+
out.push({
|
|
1028
|
+
field,
|
|
1029
|
+
fieldId: field.id,
|
|
1030
|
+
option,
|
|
1031
|
+
optionId: option.id,
|
|
1032
|
+
depth,
|
|
1033
|
+
parentId
|
|
1034
|
+
});
|
|
1035
|
+
visit(option.children, depth + 1, option.id);
|
|
1036
|
+
}
|
|
1037
|
+
};
|
|
1038
|
+
visit(field.options, 0);
|
|
1039
|
+
return out;
|
|
1040
|
+
}
|
|
1041
|
+
function fieldOptionIds(field) {
|
|
1042
|
+
return walkFieldOptions(field).map((visit) => visit.optionId);
|
|
1043
|
+
}
|
|
1044
|
+
function fieldOptionIdSet(field) {
|
|
1045
|
+
return new Set(fieldOptionIds(field));
|
|
1046
|
+
}
|
|
1047
|
+
function findFieldOption(field, optionId) {
|
|
1048
|
+
var _a;
|
|
1049
|
+
if (!field) return void 0;
|
|
1050
|
+
return (_a = walkFieldOptions(field).find((visit) => visit.optionId === optionId)) == null ? void 0 : _a.option;
|
|
1051
|
+
}
|
|
1052
|
+
function findOptionOwnerField(fields, optionId) {
|
|
1053
|
+
for (const field of fields) {
|
|
1054
|
+
if (findFieldOption(field, optionId)) return field;
|
|
1055
|
+
}
|
|
1056
|
+
return void 0;
|
|
1057
|
+
}
|
|
1058
|
+
function optionOwnerMap(fields) {
|
|
1059
|
+
const out = /* @__PURE__ */ new Map();
|
|
1060
|
+
for (const field of fields) {
|
|
1061
|
+
for (const visit of walkFieldOptions(field)) {
|
|
1062
|
+
if (!out.has(visit.optionId)) {
|
|
1063
|
+
out.set(visit.optionId, {
|
|
1064
|
+
fieldId: field.id,
|
|
1065
|
+
option: visit.option
|
|
1066
|
+
});
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
return out;
|
|
1071
|
+
}
|
|
1072
|
+
function filterFieldOptionsById(options, allowed) {
|
|
1073
|
+
if (!Array.isArray(options)) return void 0;
|
|
1074
|
+
const out = [];
|
|
1075
|
+
for (const option of options) {
|
|
1076
|
+
const children = filterFieldOptionsById(option.children, allowed);
|
|
1077
|
+
if (!allowed.has(option.id) && (!children || children.length === 0)) {
|
|
1078
|
+
continue;
|
|
1079
|
+
}
|
|
1080
|
+
out.push({
|
|
1081
|
+
...option,
|
|
1082
|
+
...children ? { children } : {}
|
|
1083
|
+
});
|
|
1084
|
+
}
|
|
1085
|
+
return out;
|
|
1086
|
+
}
|
|
1087
|
+
|
|
985
1088
|
// src/core/validate/shared.ts
|
|
986
1089
|
function isFiniteNumber(v) {
|
|
987
1090
|
return typeof v === "number" && Number.isFinite(v);
|
|
@@ -990,8 +1093,9 @@ function isServiceIdRef(v) {
|
|
|
990
1093
|
return typeof v === "string" && v.trim().length > 0 || typeof v === "number" && Number.isFinite(v);
|
|
991
1094
|
}
|
|
992
1095
|
function hasAnyServiceOption(f) {
|
|
993
|
-
|
|
994
|
-
|
|
1096
|
+
return walkFieldOptions(f).some(
|
|
1097
|
+
(visit) => isServiceIdRef(visit.option.service_id)
|
|
1098
|
+
);
|
|
995
1099
|
}
|
|
996
1100
|
function getByPath(obj, path) {
|
|
997
1101
|
if (!path) return void 0;
|
|
@@ -1080,14 +1184,14 @@ function withAffected(details, ids) {
|
|
|
1080
1184
|
|
|
1081
1185
|
// src/core/node-map.ts
|
|
1082
1186
|
function buildNodeMap(props) {
|
|
1083
|
-
var _a, _b
|
|
1187
|
+
var _a, _b;
|
|
1084
1188
|
const map = /* @__PURE__ */ new Map();
|
|
1085
1189
|
for (const t of (_a = props.filters) != null ? _a : []) {
|
|
1086
1190
|
if (!map.has(t.id)) map.set(t.id, { kind: "tag", id: t.id, node: t });
|
|
1087
1191
|
}
|
|
1088
1192
|
for (const f of (_b = props.fields) != null ? _b : []) {
|
|
1089
1193
|
if (!map.has(f.id)) map.set(f.id, { kind: "field", id: f.id, node: f });
|
|
1090
|
-
for (const o of (
|
|
1194
|
+
for (const { option: o } of walkFieldOptions(f)) {
|
|
1091
1195
|
if (!map.has(o.id))
|
|
1092
1196
|
map.set(o.id, {
|
|
1093
1197
|
kind: "option",
|
|
@@ -1100,12 +1204,6 @@ function buildNodeMap(props) {
|
|
|
1100
1204
|
return map;
|
|
1101
1205
|
}
|
|
1102
1206
|
function resolveTrigger(trigger, nodeMap) {
|
|
1103
|
-
const idx = trigger.indexOf("::");
|
|
1104
|
-
if (idx !== -1) {
|
|
1105
|
-
const fieldId = trigger.slice(0, idx);
|
|
1106
|
-
const optionId = trigger.slice(idx + 2);
|
|
1107
|
-
return { kind: "composite", triggerKey: trigger, fieldId, optionId };
|
|
1108
|
-
}
|
|
1109
1207
|
const direct = nodeMap.get(trigger);
|
|
1110
1208
|
if (!direct) return void 0;
|
|
1111
1209
|
if (direct.kind === "option") {
|
|
@@ -1157,11 +1255,6 @@ function visibleFieldIdsUnder(props, tagId, opts = {}) {
|
|
|
1157
1255
|
const ownerDepthForTriggerKey = (triggerKey) => {
|
|
1158
1256
|
const t = resolveTrigger(triggerKey, nodeMap);
|
|
1159
1257
|
if (!t) return void 0;
|
|
1160
|
-
if (t.kind === "composite") {
|
|
1161
|
-
const f = fieldById.get(t.fieldId);
|
|
1162
|
-
if (!f) return void 0;
|
|
1163
|
-
return ownerDepthForField(f);
|
|
1164
|
-
}
|
|
1165
1258
|
if (t.kind === "field") {
|
|
1166
1259
|
const f = fieldById.get(t.id);
|
|
1167
1260
|
if (!f || f.button !== true) return void 0;
|
|
@@ -1244,6 +1337,84 @@ function visibleFieldsUnder(props, tagId, opts = {}) {
|
|
|
1244
1337
|
const fieldById = new Map(((_a = props.fields) != null ? _a : []).map((f) => [f.id, f]));
|
|
1245
1338
|
return ids.map((id) => fieldById.get(id)).filter(Boolean);
|
|
1246
1339
|
}
|
|
1340
|
+
function resolveVisibility(props, tagId, selectedKeys) {
|
|
1341
|
+
var _a, _b, _c, _d;
|
|
1342
|
+
const selected = new Set(selectedKeys != null ? selectedKeys : []);
|
|
1343
|
+
const baseFieldIds = visibleFieldIdsUnder(props, tagId, { selectedKeys: selected });
|
|
1344
|
+
const fieldById = new Map(((_a = props.fields) != null ? _a : []).map((field) => [field.id, field]));
|
|
1345
|
+
const visible = new Set(baseFieldIds);
|
|
1346
|
+
const forced = /* @__PURE__ */ new Set();
|
|
1347
|
+
const optionsByFieldId = {};
|
|
1348
|
+
const optionIdsByFieldId = /* @__PURE__ */ new Map();
|
|
1349
|
+
const getOptionIds = (field) => {
|
|
1350
|
+
let ids = optionIdsByFieldId.get(field.id);
|
|
1351
|
+
if (!ids) {
|
|
1352
|
+
ids = fieldOptionIds(field);
|
|
1353
|
+
optionIdsByFieldId.set(field.id, ids);
|
|
1354
|
+
}
|
|
1355
|
+
return ids;
|
|
1356
|
+
};
|
|
1357
|
+
const ensureOptions = (field) => {
|
|
1358
|
+
const ids = getOptionIds(field);
|
|
1359
|
+
if (!ids.length) return void 0;
|
|
1360
|
+
if (!optionsByFieldId[field.id]) optionsByFieldId[field.id] = [...ids];
|
|
1361
|
+
return optionsByFieldId[field.id];
|
|
1362
|
+
};
|
|
1363
|
+
for (const fieldId of baseFieldIds) {
|
|
1364
|
+
const field = fieldById.get(fieldId);
|
|
1365
|
+
if (field) ensureOptions(field);
|
|
1366
|
+
}
|
|
1367
|
+
const effects = (_b = props.option_effects_for_buttons) != null ? _b : {};
|
|
1368
|
+
for (const triggerId of selected) {
|
|
1369
|
+
const targetRules = effects[triggerId];
|
|
1370
|
+
if (!targetRules) continue;
|
|
1371
|
+
for (const [targetFieldId, rule] of Object.entries(targetRules)) {
|
|
1372
|
+
const field = fieldById.get(targetFieldId);
|
|
1373
|
+
if (!field) continue;
|
|
1374
|
+
const isVisible = visible.has(targetFieldId);
|
|
1375
|
+
if (!isVisible && rule.forceVisible !== true) continue;
|
|
1376
|
+
if (!isVisible && rule.forceVisible === true) {
|
|
1377
|
+
visible.add(targetFieldId);
|
|
1378
|
+
forced.add(targetFieldId);
|
|
1379
|
+
}
|
|
1380
|
+
const orderedOptionIds = getOptionIds(field);
|
|
1381
|
+
if (!orderedOptionIds.length) continue;
|
|
1382
|
+
const known = new Set(orderedOptionIds);
|
|
1383
|
+
let allowed = (_c = optionsByFieldId[targetFieldId]) != null ? _c : [...orderedOptionIds];
|
|
1384
|
+
if (Array.isArray(rule.include) && rule.include.length) {
|
|
1385
|
+
const include2 = new Set(
|
|
1386
|
+
rule.include.filter((optionId) => known.has(optionId))
|
|
1387
|
+
);
|
|
1388
|
+
allowed = orderedOptionIds.filter(
|
|
1389
|
+
(optionId) => include2.has(optionId) && allowed.includes(optionId)
|
|
1390
|
+
);
|
|
1391
|
+
}
|
|
1392
|
+
if (Array.isArray(rule.exclude) && rule.exclude.length) {
|
|
1393
|
+
const exclude2 = new Set(
|
|
1394
|
+
rule.exclude.filter((optionId) => known.has(optionId))
|
|
1395
|
+
);
|
|
1396
|
+
allowed = allowed.filter((optionId) => !exclude2.has(optionId));
|
|
1397
|
+
}
|
|
1398
|
+
optionsByFieldId[targetFieldId] = allowed;
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1401
|
+
const visibleFieldIds = baseFieldIds.filter((fieldId) => visible.has(fieldId));
|
|
1402
|
+
const seen = new Set(visibleFieldIds);
|
|
1403
|
+
for (const field of (_d = props.fields) != null ? _d : []) {
|
|
1404
|
+
if (!visible.has(field.id) || seen.has(field.id)) continue;
|
|
1405
|
+
seen.add(field.id);
|
|
1406
|
+
visibleFieldIds.push(field.id);
|
|
1407
|
+
ensureOptions(field);
|
|
1408
|
+
}
|
|
1409
|
+
for (const fieldId of Object.keys(optionsByFieldId)) {
|
|
1410
|
+
if (!visible.has(fieldId)) delete optionsByFieldId[fieldId];
|
|
1411
|
+
}
|
|
1412
|
+
return {
|
|
1413
|
+
fieldIds: visibleFieldIds,
|
|
1414
|
+
optionsByFieldId,
|
|
1415
|
+
forcedFieldIds: visibleFieldIds.filter((fieldId) => forced.has(fieldId))
|
|
1416
|
+
};
|
|
1417
|
+
}
|
|
1247
1418
|
|
|
1248
1419
|
// src/core/validate/steps/visibility.ts
|
|
1249
1420
|
function createFieldsVisibleUnder(v) {
|
|
@@ -1261,7 +1432,6 @@ function resolveRootTags(tags) {
|
|
|
1261
1432
|
return roots.length ? roots : tags.slice(0, 1);
|
|
1262
1433
|
}
|
|
1263
1434
|
function collectSelectableTriggersInContext(v, tagId, selectedKeys, effectfulKeys) {
|
|
1264
|
-
var _a;
|
|
1265
1435
|
const visible = visibleFieldsUnder(v.props, tagId, {
|
|
1266
1436
|
selectedKeys
|
|
1267
1437
|
});
|
|
@@ -1271,7 +1441,7 @@ function collectSelectableTriggersInContext(v, tagId, selectedKeys, effectfulKey
|
|
|
1271
1441
|
const t = f.id;
|
|
1272
1442
|
if (effectfulKeys.has(t)) triggers.push(t);
|
|
1273
1443
|
}
|
|
1274
|
-
for (const o of (
|
|
1444
|
+
for (const { option: o } of walkFieldOptions(f)) {
|
|
1275
1445
|
const t = o.id;
|
|
1276
1446
|
if (effectfulKeys.has(t)) triggers.push(t);
|
|
1277
1447
|
}
|
|
@@ -1280,7 +1450,7 @@ function collectSelectableTriggersInContext(v, tagId, selectedKeys, effectfulKey
|
|
|
1280
1450
|
return triggers;
|
|
1281
1451
|
}
|
|
1282
1452
|
function runVisibilityRulesOnce(v) {
|
|
1283
|
-
var _a, _b, _c, _d
|
|
1453
|
+
var _a, _b, _c, _d;
|
|
1284
1454
|
for (const t of v.tags) {
|
|
1285
1455
|
const visible = v.fieldsVisibleUnder(t.id);
|
|
1286
1456
|
const seen = /* @__PURE__ */ new Map();
|
|
@@ -1330,9 +1500,9 @@ function runVisibilityRulesOnce(v) {
|
|
|
1330
1500
|
let hasUtility = false;
|
|
1331
1501
|
const utilityOptionIds = [];
|
|
1332
1502
|
for (const f of visible) {
|
|
1333
|
-
for (const o of (
|
|
1503
|
+
for (const { option: o } of walkFieldOptions(f)) {
|
|
1334
1504
|
if (!isServiceIdRef(o.service_id)) continue;
|
|
1335
|
-
const role = (
|
|
1505
|
+
const role = (_d = (_c = o.pricing_role) != null ? _c : f.pricing_role) != null ? _d : "base";
|
|
1336
1506
|
if (role === "base") hasBase = true;
|
|
1337
1507
|
else if (role === "utility") {
|
|
1338
1508
|
hasUtility = true;
|
|
@@ -1373,7 +1543,7 @@ function dedupeErrorsInPlace(v, startIndex) {
|
|
|
1373
1543
|
v.errors.splice(startIndex, v.errors.length - startIndex, ...kept);
|
|
1374
1544
|
}
|
|
1375
1545
|
function validateVisibility(v, options = {}) {
|
|
1376
|
-
var _a, _b, _c, _d, _e;
|
|
1546
|
+
var _a, _b, _c, _d, _e, _f;
|
|
1377
1547
|
v.simulatedVisibilityContexts = [];
|
|
1378
1548
|
const simulate = options.simulate === true;
|
|
1379
1549
|
if (!simulate) {
|
|
@@ -1398,10 +1568,13 @@ function validateVisibility(v, options = {}) {
|
|
|
1398
1568
|
for (const key of Object.keys((_d = v.props.excludes_for_buttons) != null ? _d : {})) {
|
|
1399
1569
|
effectfulKeys.add(key);
|
|
1400
1570
|
}
|
|
1571
|
+
for (const key of Object.keys((_e = v.props.option_effects_for_buttons) != null ? _e : {})) {
|
|
1572
|
+
effectfulKeys.add(key);
|
|
1573
|
+
}
|
|
1401
1574
|
}
|
|
1402
1575
|
const roots = resolveRootTags(v.tags);
|
|
1403
1576
|
const rootTags = options.simulateAllRoots ? roots : roots.slice(0, 1);
|
|
1404
|
-
const originalSelected = new Set((
|
|
1577
|
+
const originalSelected = new Set((_f = v.selectedKeys) != null ? _f : []);
|
|
1405
1578
|
const errorsStart = v.errors.length;
|
|
1406
1579
|
const visited = /* @__PURE__ */ new Set();
|
|
1407
1580
|
const seenContexts = /* @__PURE__ */ new Set();
|
|
@@ -1542,7 +1715,7 @@ function validateStructure(v) {
|
|
|
1542
1715
|
|
|
1543
1716
|
// src/core/validate/steps/identity.ts
|
|
1544
1717
|
function validateIdentity(v) {
|
|
1545
|
-
var _a
|
|
1718
|
+
var _a;
|
|
1546
1719
|
const tags = v.tags;
|
|
1547
1720
|
const fields = v.fields;
|
|
1548
1721
|
{
|
|
@@ -1642,7 +1815,7 @@ function validateIdentity(v) {
|
|
|
1642
1815
|
}
|
|
1643
1816
|
}
|
|
1644
1817
|
for (const f of fields) {
|
|
1645
|
-
for (const o of (
|
|
1818
|
+
for (const { option: o } of walkFieldOptions(f)) {
|
|
1646
1819
|
if (!o.label || !o.label.trim()) {
|
|
1647
1820
|
v.errors.push({
|
|
1648
1821
|
code: "label_missing",
|
|
@@ -1657,25 +1830,11 @@ function validateIdentity(v) {
|
|
|
1657
1830
|
}
|
|
1658
1831
|
|
|
1659
1832
|
// src/core/validate/steps/option-maps.ts
|
|
1660
|
-
function parseFieldOptionKey(key) {
|
|
1661
|
-
const idx = key.indexOf("::");
|
|
1662
|
-
if (idx === -1) return null;
|
|
1663
|
-
const fieldId = key.slice(0, idx).trim();
|
|
1664
|
-
const optionId = key.slice(idx + 2).trim();
|
|
1665
|
-
if (!fieldId || !optionId) return null;
|
|
1666
|
-
return { fieldId, optionId };
|
|
1667
|
-
}
|
|
1668
|
-
function hasOption(v, fid, oid) {
|
|
1669
|
-
var _a;
|
|
1670
|
-
const f = v.fieldById.get(fid);
|
|
1671
|
-
if (!f) return false;
|
|
1672
|
-
return !!((_a = f.options) != null ? _a : []).find((o) => o.id === oid);
|
|
1673
|
-
}
|
|
1674
1833
|
function validateOptionMaps(v) {
|
|
1675
|
-
var _a, _b;
|
|
1834
|
+
var _a, _b, _c;
|
|
1676
1835
|
const incMap = (_a = v.props.includes_for_buttons) != null ? _a : {};
|
|
1677
1836
|
const excMap = (_b = v.props.excludes_for_buttons) != null ? _b : {};
|
|
1678
|
-
const badKeyMessage = (key) => `Invalid trigger-map key "${key}". Expected a known
|
|
1837
|
+
const badKeyMessage = (key) => `Invalid trigger-map key "${key}". Expected a known option id or button-field id.`;
|
|
1679
1838
|
const validateTriggerKey = (key) => {
|
|
1680
1839
|
const ref = v.nodeMap.get(key);
|
|
1681
1840
|
if (ref) {
|
|
@@ -1694,19 +1853,7 @@ function validateOptionMaps(v) {
|
|
|
1694
1853
|
}
|
|
1695
1854
|
return { ok: false, nodeId: ref.id, affected: [ref.id] };
|
|
1696
1855
|
}
|
|
1697
|
-
|
|
1698
|
-
if (!p) return { ok: false };
|
|
1699
|
-
if (!hasOption(v, p.fieldId, p.optionId))
|
|
1700
|
-
return {
|
|
1701
|
-
ok: false,
|
|
1702
|
-
nodeId: p.fieldId,
|
|
1703
|
-
affected: [p.fieldId, p.optionId]
|
|
1704
|
-
};
|
|
1705
|
-
return {
|
|
1706
|
-
ok: true,
|
|
1707
|
-
nodeId: p.fieldId,
|
|
1708
|
-
affected: [p.fieldId, p.optionId]
|
|
1709
|
-
};
|
|
1856
|
+
return { ok: false };
|
|
1710
1857
|
};
|
|
1711
1858
|
for (const k of Object.keys(incMap)) {
|
|
1712
1859
|
const r = validateTriggerKey(k);
|
|
@@ -1732,6 +1879,57 @@ function validateOptionMaps(v) {
|
|
|
1732
1879
|
});
|
|
1733
1880
|
}
|
|
1734
1881
|
}
|
|
1882
|
+
const effectMap = (_c = v.props.option_effects_for_buttons) != null ? _c : {};
|
|
1883
|
+
for (const [triggerKey, targets] of Object.entries(effectMap)) {
|
|
1884
|
+
const trigger = validateTriggerKey(triggerKey);
|
|
1885
|
+
if (!trigger.ok) {
|
|
1886
|
+
v.errors.push({
|
|
1887
|
+
code: "bad_option_effect_key",
|
|
1888
|
+
severity: "error",
|
|
1889
|
+
message: badKeyMessage(triggerKey),
|
|
1890
|
+
nodeId: trigger.nodeId,
|
|
1891
|
+
details: withAffected({ key: triggerKey }, trigger.affected)
|
|
1892
|
+
});
|
|
1893
|
+
}
|
|
1894
|
+
for (const [targetFieldId, effect] of Object.entries(targets != null ? targets : {})) {
|
|
1895
|
+
const field = v.fieldById.get(targetFieldId);
|
|
1896
|
+
if (!field) {
|
|
1897
|
+
v.errors.push({
|
|
1898
|
+
code: "bad_option_effect_target",
|
|
1899
|
+
severity: "error",
|
|
1900
|
+
message: `Option effect trigger "${triggerKey}" targets unknown field "${targetFieldId}".`,
|
|
1901
|
+
details: withAffected(
|
|
1902
|
+
{ key: triggerKey, targetFieldId },
|
|
1903
|
+
trigger.affected
|
|
1904
|
+
)
|
|
1905
|
+
});
|
|
1906
|
+
continue;
|
|
1907
|
+
}
|
|
1908
|
+
const validOptionIds = fieldOptionIdSet(field);
|
|
1909
|
+
const checkTargetOptions = (kind, optionIds) => {
|
|
1910
|
+
for (const optionId of optionIds != null ? optionIds : []) {
|
|
1911
|
+
if (validOptionIds.has(optionId)) continue;
|
|
1912
|
+
v.errors.push({
|
|
1913
|
+
code: "bad_option_effect_option",
|
|
1914
|
+
severity: "error",
|
|
1915
|
+
message: `Option effect trigger "${triggerKey}" references unknown ${kind} option "${optionId}" for field "${targetFieldId}".`,
|
|
1916
|
+
nodeId: targetFieldId,
|
|
1917
|
+
details: withAffected(
|
|
1918
|
+
{
|
|
1919
|
+
key: triggerKey,
|
|
1920
|
+
targetFieldId,
|
|
1921
|
+
optionId,
|
|
1922
|
+
kind
|
|
1923
|
+
},
|
|
1924
|
+
[targetFieldId, optionId]
|
|
1925
|
+
)
|
|
1926
|
+
});
|
|
1927
|
+
}
|
|
1928
|
+
};
|
|
1929
|
+
checkTargetOptions("include", effect == null ? void 0 : effect.include);
|
|
1930
|
+
checkTargetOptions("exclude", effect == null ? void 0 : effect.exclude);
|
|
1931
|
+
}
|
|
1932
|
+
}
|
|
1735
1933
|
for (const k of Object.keys(incMap)) {
|
|
1736
1934
|
if (!(k in excMap)) continue;
|
|
1737
1935
|
const r = validateTriggerKey(k);
|
|
@@ -1745,27 +1943,231 @@ function validateOptionMaps(v) {
|
|
|
1745
1943
|
}
|
|
1746
1944
|
}
|
|
1747
1945
|
|
|
1748
|
-
// src/
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
const
|
|
1752
|
-
if (
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1946
|
+
// src/core/validate/steps/visibility-cycles.ts
|
|
1947
|
+
var MAX_VISIBILITY_CYCLE_DEPTH = 20;
|
|
1948
|
+
function validateVisibilityCycles(v) {
|
|
1949
|
+
const triggerById = buildTriggerIndex(v.fields);
|
|
1950
|
+
if (!triggerById.size) return;
|
|
1951
|
+
const fieldTriggers = buildFieldTriggerIndex(v.fields);
|
|
1952
|
+
const revealTargetsByTrigger = buildRevealIndex(v, triggerById);
|
|
1953
|
+
const reported = /* @__PURE__ */ new Set();
|
|
1954
|
+
for (const rootTriggerId of Array.from(triggerById.keys()).sort()) {
|
|
1955
|
+
const required = makeRequiredState(triggerById, [rootTriggerId]);
|
|
1956
|
+
walkFromTrigger({
|
|
1957
|
+
v,
|
|
1958
|
+
triggerById,
|
|
1959
|
+
fieldTriggers,
|
|
1960
|
+
revealTargetsByTrigger,
|
|
1961
|
+
rootTriggerId,
|
|
1962
|
+
currentTriggerId: rootTriggerId,
|
|
1963
|
+
required,
|
|
1964
|
+
path: [rootTriggerId],
|
|
1965
|
+
visited: /* @__PURE__ */ new Set(),
|
|
1966
|
+
reported,
|
|
1967
|
+
depth: 0
|
|
1968
|
+
});
|
|
1969
|
+
}
|
|
1970
|
+
}
|
|
1971
|
+
function buildTriggerIndex(fields) {
|
|
1972
|
+
const out = /* @__PURE__ */ new Map();
|
|
1973
|
+
const owners = optionOwnerMap(fields);
|
|
1974
|
+
for (const field of fields) {
|
|
1975
|
+
if (field.button === true) {
|
|
1976
|
+
out.set(field.id, {
|
|
1977
|
+
kind: "field",
|
|
1978
|
+
id: field.id,
|
|
1979
|
+
ownerFieldId: field.id
|
|
1980
|
+
});
|
|
1981
|
+
}
|
|
1982
|
+
}
|
|
1983
|
+
for (const [optionId, owner] of owners) {
|
|
1984
|
+
out.set(optionId, {
|
|
1985
|
+
kind: "option",
|
|
1986
|
+
id: optionId,
|
|
1987
|
+
ownerFieldId: owner.fieldId
|
|
1988
|
+
});
|
|
1989
|
+
}
|
|
1990
|
+
return out;
|
|
1991
|
+
}
|
|
1992
|
+
function buildFieldTriggerIndex(fields) {
|
|
1993
|
+
const out = /* @__PURE__ */ new Map();
|
|
1994
|
+
for (const field of fields) {
|
|
1995
|
+
const triggers = [];
|
|
1996
|
+
if (field.button === true) triggers.push(field.id);
|
|
1997
|
+
for (const visit of walkFieldOptions(field)) {
|
|
1998
|
+
triggers.push(visit.optionId);
|
|
1999
|
+
}
|
|
2000
|
+
out.set(field.id, triggers);
|
|
2001
|
+
}
|
|
2002
|
+
return out;
|
|
2003
|
+
}
|
|
2004
|
+
function buildRevealIndex(v, triggerById) {
|
|
2005
|
+
var _a, _b;
|
|
2006
|
+
const out = /* @__PURE__ */ new Map();
|
|
2007
|
+
const addReveal = (triggerId, targetFieldId) => {
|
|
2008
|
+
var _a2;
|
|
2009
|
+
if (!triggerById.has(triggerId)) return;
|
|
2010
|
+
if (!v.fieldById.has(targetFieldId)) return;
|
|
2011
|
+
const set = (_a2 = out.get(triggerId)) != null ? _a2 : /* @__PURE__ */ new Set();
|
|
2012
|
+
set.add(targetFieldId);
|
|
2013
|
+
out.set(triggerId, set);
|
|
2014
|
+
};
|
|
2015
|
+
for (const [triggerId, targetIds] of Object.entries(
|
|
2016
|
+
(_a = v.props.includes_for_buttons) != null ? _a : {}
|
|
2017
|
+
)) {
|
|
2018
|
+
for (const targetId of targetIds != null ? targetIds : []) addReveal(triggerId, targetId);
|
|
2019
|
+
}
|
|
2020
|
+
for (const [triggerId, targets] of Object.entries(
|
|
2021
|
+
(_b = v.props.option_effects_for_buttons) != null ? _b : {}
|
|
2022
|
+
)) {
|
|
2023
|
+
for (const [targetFieldId, effect] of Object.entries(targets != null ? targets : {})) {
|
|
2024
|
+
if ((effect == null ? void 0 : effect.forceVisible) === true)
|
|
2025
|
+
addReveal(triggerId, targetFieldId);
|
|
2026
|
+
}
|
|
2027
|
+
}
|
|
2028
|
+
return new Map(
|
|
2029
|
+
Array.from(out.entries()).map(([triggerId, fieldIds]) => [
|
|
2030
|
+
triggerId,
|
|
2031
|
+
Array.from(fieldIds).sort()
|
|
2032
|
+
])
|
|
2033
|
+
);
|
|
2034
|
+
}
|
|
2035
|
+
function walkFromTrigger(args) {
|
|
2036
|
+
var _a, _b, _c;
|
|
2037
|
+
if (args.depth >= MAX_VISIBILITY_CYCLE_DEPTH) return;
|
|
2038
|
+
const visitedKey = `${args.rootTriggerId}::${args.currentTriggerId}::${args.path.join(">")}`;
|
|
2039
|
+
if (args.visited.has(visitedKey)) return;
|
|
2040
|
+
args.visited.add(visitedKey);
|
|
2041
|
+
const revealedFieldIds = (_a = args.revealTargetsByTrigger.get(args.currentTriggerId)) != null ? _a : [];
|
|
2042
|
+
for (const revealedFieldId of revealedFieldIds) {
|
|
2043
|
+
const reachableTriggers = (_c = (_b = args.fieldTriggers.get(revealedFieldId)) == null ? void 0 : _b.slice().sort()) != null ? _c : [];
|
|
2044
|
+
for (const reachableTriggerId of reachableTriggers) {
|
|
2045
|
+
const invalidation = invalidatesRequiredPath(
|
|
2046
|
+
args.v,
|
|
2047
|
+
args.triggerById,
|
|
2048
|
+
reachableTriggerId,
|
|
2049
|
+
args.required
|
|
2050
|
+
);
|
|
2051
|
+
if (invalidation) {
|
|
2052
|
+
emitCycleError({
|
|
2053
|
+
v: args.v,
|
|
2054
|
+
rootTriggerId: args.rootTriggerId,
|
|
2055
|
+
revealedFieldId,
|
|
2056
|
+
conflictingTriggerId: reachableTriggerId,
|
|
2057
|
+
invalidatedId: invalidation.invalidatedId,
|
|
2058
|
+
path: [...args.path, reachableTriggerId],
|
|
2059
|
+
reported: args.reported
|
|
2060
|
+
});
|
|
2061
|
+
}
|
|
2062
|
+
if (args.path.includes(reachableTriggerId)) continue;
|
|
2063
|
+
walkFromTrigger({
|
|
2064
|
+
...args,
|
|
2065
|
+
currentTriggerId: reachableTriggerId,
|
|
2066
|
+
required: addRequiredTrigger(
|
|
2067
|
+
args.triggerById,
|
|
2068
|
+
args.required,
|
|
2069
|
+
reachableTriggerId
|
|
2070
|
+
),
|
|
2071
|
+
path: [...args.path, reachableTriggerId],
|
|
2072
|
+
depth: args.depth + 1
|
|
2073
|
+
});
|
|
2074
|
+
}
|
|
2075
|
+
}
|
|
2076
|
+
}
|
|
2077
|
+
function makeRequiredState(triggerById, triggerIds) {
|
|
2078
|
+
let required = {
|
|
2079
|
+
triggers: /* @__PURE__ */ new Set(),
|
|
2080
|
+
ownerFields: /* @__PURE__ */ new Set()
|
|
2081
|
+
};
|
|
2082
|
+
for (const triggerId of triggerIds) {
|
|
2083
|
+
required = addRequiredTrigger(triggerById, required, triggerId);
|
|
2084
|
+
}
|
|
2085
|
+
return required;
|
|
2086
|
+
}
|
|
2087
|
+
function addRequiredTrigger(triggerById, current, triggerId) {
|
|
2088
|
+
const next = {
|
|
2089
|
+
triggers: new Set(current.triggers),
|
|
2090
|
+
ownerFields: new Set(current.ownerFields)
|
|
2091
|
+
};
|
|
2092
|
+
const trigger = triggerById.get(triggerId);
|
|
2093
|
+
if (!trigger) return next;
|
|
2094
|
+
next.triggers.add(triggerId);
|
|
2095
|
+
next.ownerFields.add(trigger.ownerFieldId);
|
|
2096
|
+
return next;
|
|
2097
|
+
}
|
|
2098
|
+
function invalidatesRequiredPath(v, triggerById, conflictingTriggerId, required) {
|
|
2099
|
+
var _a, _b, _c, _d, _e, _f;
|
|
2100
|
+
for (const targetId of (_b = (_a = v.props.excludes_for_buttons) == null ? void 0 : _a[conflictingTriggerId]) != null ? _b : []) {
|
|
2101
|
+
if (required.ownerFields.has(targetId)) {
|
|
2102
|
+
return { invalidatedId: targetId };
|
|
2103
|
+
}
|
|
2104
|
+
const targetTrigger = triggerById.get(targetId);
|
|
2105
|
+
if ((targetTrigger == null ? void 0 : targetTrigger.kind) === "option" && required.triggers.has(targetId)) {
|
|
2106
|
+
return { invalidatedId: targetId };
|
|
2107
|
+
}
|
|
2108
|
+
}
|
|
2109
|
+
const effects = (_d = (_c = v.props.option_effects_for_buttons) == null ? void 0 : _c[conflictingTriggerId]) != null ? _d : {};
|
|
2110
|
+
for (const [targetFieldId, effect] of Object.entries(effects)) {
|
|
2111
|
+
if (!v.fieldById.has(targetFieldId)) continue;
|
|
2112
|
+
if ((_e = effect == null ? void 0 : effect.exclude) == null ? void 0 : _e.length) {
|
|
2113
|
+
const excluded = new Set(effect.exclude);
|
|
2114
|
+
for (const requiredTriggerId of required.triggers) {
|
|
2115
|
+
const requiredTrigger = triggerById.get(requiredTriggerId);
|
|
2116
|
+
if ((requiredTrigger == null ? void 0 : requiredTrigger.kind) !== "option") continue;
|
|
2117
|
+
if (requiredTrigger.ownerFieldId !== targetFieldId) continue;
|
|
2118
|
+
if (excluded.has(requiredTriggerId)) {
|
|
2119
|
+
return { invalidatedId: requiredTriggerId };
|
|
2120
|
+
}
|
|
1759
2121
|
}
|
|
1760
2122
|
}
|
|
1761
|
-
if (
|
|
1762
|
-
const
|
|
1763
|
-
|
|
1764
|
-
|
|
2123
|
+
if ((_f = effect == null ? void 0 : effect.include) == null ? void 0 : _f.length) {
|
|
2124
|
+
const included = new Set(effect.include);
|
|
2125
|
+
for (const requiredTriggerId of required.triggers) {
|
|
2126
|
+
const requiredTrigger = triggerById.get(requiredTriggerId);
|
|
2127
|
+
if ((requiredTrigger == null ? void 0 : requiredTrigger.kind) !== "option") continue;
|
|
2128
|
+
if (requiredTrigger.ownerFieldId !== targetFieldId) continue;
|
|
2129
|
+
if (!included.has(requiredTriggerId)) {
|
|
2130
|
+
return { invalidatedId: requiredTriggerId };
|
|
2131
|
+
}
|
|
1765
2132
|
}
|
|
1766
2133
|
}
|
|
1767
|
-
return void 0;
|
|
1768
2134
|
}
|
|
2135
|
+
return void 0;
|
|
2136
|
+
}
|
|
2137
|
+
function emitCycleError(args) {
|
|
2138
|
+
const key = [
|
|
2139
|
+
args.rootTriggerId,
|
|
2140
|
+
args.conflictingTriggerId,
|
|
2141
|
+
args.invalidatedId,
|
|
2142
|
+
args.path.join(">")
|
|
2143
|
+
].join("::");
|
|
2144
|
+
if (args.reported.has(key)) return;
|
|
2145
|
+
args.reported.add(key);
|
|
2146
|
+
args.v.errors.push({
|
|
2147
|
+
code: "visibility_dependency_cycle",
|
|
2148
|
+
severity: "error",
|
|
2149
|
+
message: `Visibility dependency cycle: trigger "${args.rootTriggerId}" reveals "${args.revealedFieldId}", but reachable trigger "${args.conflictingTriggerId}" can hide or remove "${args.invalidatedId}".`,
|
|
2150
|
+
nodeId: args.conflictingTriggerId,
|
|
2151
|
+
details: withAffected(
|
|
2152
|
+
{
|
|
2153
|
+
rootTriggerId: args.rootTriggerId,
|
|
2154
|
+
conflictingTriggerId: args.conflictingTriggerId,
|
|
2155
|
+
invalidatedId: args.invalidatedId,
|
|
2156
|
+
path: args.path
|
|
2157
|
+
},
|
|
2158
|
+
[
|
|
2159
|
+
args.rootTriggerId,
|
|
2160
|
+
args.revealedFieldId,
|
|
2161
|
+
args.conflictingTriggerId,
|
|
2162
|
+
args.invalidatedId
|
|
2163
|
+
]
|
|
2164
|
+
)
|
|
2165
|
+
});
|
|
2166
|
+
}
|
|
2167
|
+
|
|
2168
|
+
// src/utils/order-kind.ts
|
|
2169
|
+
function normalizeSelectedTriggerKey(key, nodeMap) {
|
|
2170
|
+
if (!key) return void 0;
|
|
1769
2171
|
const ref = nodeMap.get(key);
|
|
1770
2172
|
if (!ref) return void 0;
|
|
1771
2173
|
if (ref.kind !== "field" && ref.kind !== "option") return void 0;
|
|
@@ -1924,8 +2326,7 @@ function validateUtilityMarkers(v) {
|
|
|
1924
2326
|
"percent"
|
|
1925
2327
|
]);
|
|
1926
2328
|
for (const f of v.fields) {
|
|
1927
|
-
const
|
|
1928
|
-
for (const o of optsArr) {
|
|
2329
|
+
for (const { option: o } of walkFieldOptions(f)) {
|
|
1929
2330
|
const role = (_b = (_a = o.pricing_role) != null ? _a : f.pricing_role) != null ? _b : "base";
|
|
1930
2331
|
const hasService = isServiceIdRef(o.service_id);
|
|
1931
2332
|
const util = (_c = o.meta) == null ? void 0 : _c.utility;
|
|
@@ -2161,13 +2562,13 @@ function normalizeServiceRef(value) {
|
|
|
2161
2562
|
|
|
2162
2563
|
// src/core/validate/steps/rates.ts
|
|
2163
2564
|
function validateRates(v) {
|
|
2164
|
-
var _a, _b
|
|
2565
|
+
var _a, _b;
|
|
2165
2566
|
const ratePolicy = normalizeRatePolicy(v.options.ratePolicy);
|
|
2166
2567
|
for (const f of v.fields) {
|
|
2167
2568
|
if (!isMultiField(f)) continue;
|
|
2168
2569
|
const baseRates = [];
|
|
2169
|
-
for (const o of (
|
|
2170
|
-
const role = (
|
|
2570
|
+
for (const { option: o } of walkFieldOptions(f)) {
|
|
2571
|
+
const role = (_b = (_a = o.pricing_role) != null ? _a : f.pricing_role) != null ? _b : "base";
|
|
2171
2572
|
if (role !== "base") continue;
|
|
2172
2573
|
const sid = o.service_id;
|
|
2173
2574
|
if (!isServiceIdRef(sid)) continue;
|
|
@@ -2578,7 +2979,7 @@ function effectiveConstraints(v, tagId) {
|
|
|
2578
2979
|
return out;
|
|
2579
2980
|
}
|
|
2580
2981
|
function validateConstraints(v) {
|
|
2581
|
-
var _a
|
|
2982
|
+
var _a;
|
|
2582
2983
|
for (const t of v.tags) {
|
|
2583
2984
|
const eff = effectiveConstraints(v, t.id);
|
|
2584
2985
|
const hasAnyRequired = Object.values(eff).some(
|
|
@@ -2587,7 +2988,7 @@ function validateConstraints(v) {
|
|
|
2587
2988
|
if (!hasAnyRequired) continue;
|
|
2588
2989
|
const visible = v.fieldsVisibleUnder(t.id);
|
|
2589
2990
|
for (const f of visible) {
|
|
2590
|
-
for (const o of (
|
|
2991
|
+
for (const { option: o } of walkFieldOptions(f)) {
|
|
2591
2992
|
if (!isServiceIdRef(o.service_id)) continue;
|
|
2592
2993
|
const svc = getServiceCapability(v.serviceMap, o.service_id);
|
|
2593
2994
|
if (!svc || typeof svc !== "object") continue;
|
|
@@ -2641,7 +3042,7 @@ function validateConstraints(v) {
|
|
|
2641
3042
|
if (!row) continue;
|
|
2642
3043
|
const from = row.from === true;
|
|
2643
3044
|
const to = row.to === true;
|
|
2644
|
-
const origin = String((
|
|
3045
|
+
const origin = String((_a = row.origin) != null ? _a : "");
|
|
2645
3046
|
v.errors.push({
|
|
2646
3047
|
code: "constraint_overridden",
|
|
2647
3048
|
severity: "warning",
|
|
@@ -2675,14 +3076,14 @@ function validateCustomFields(v) {
|
|
|
2675
3076
|
|
|
2676
3077
|
// src/core/validate/steps/global-utility-guard.ts
|
|
2677
3078
|
function validateGlobalUtilityGuard(v) {
|
|
2678
|
-
var _a, _b
|
|
3079
|
+
var _a, _b;
|
|
2679
3080
|
if (!v.options.globalUtilityGuard) return;
|
|
2680
3081
|
let hasUtility = false;
|
|
2681
3082
|
let hasBase = false;
|
|
2682
3083
|
for (const f of v.fields) {
|
|
2683
|
-
for (const o of (
|
|
3084
|
+
for (const { option: o } of walkFieldOptions(f)) {
|
|
2684
3085
|
if (!isServiceIdRef(o.service_id)) continue;
|
|
2685
|
-
const role = (
|
|
3086
|
+
const role = (_b = (_a = o.pricing_role) != null ? _a : f.pricing_role) != null ? _b : "base";
|
|
2686
3087
|
if (role === "base") hasBase = true;
|
|
2687
3088
|
else if (role === "utility") hasUtility = true;
|
|
2688
3089
|
if (hasUtility && hasBase) break;
|
|
@@ -2884,7 +3285,7 @@ function applyFilterAllowLists(tagId, fieldId, filter) {
|
|
|
2884
3285
|
return true;
|
|
2885
3286
|
}
|
|
2886
3287
|
function collectServiceItems(args) {
|
|
2887
|
-
var _a, _b, _c, _d
|
|
3288
|
+
var _a, _b, _c, _d;
|
|
2888
3289
|
const filter = args.filter;
|
|
2889
3290
|
const roleFilter = (_a = filter == null ? void 0 : filter.role) != null ? _a : "both";
|
|
2890
3291
|
const where = filter == null ? void 0 : filter.where;
|
|
@@ -2934,7 +3335,7 @@ function collectServiceItems(args) {
|
|
|
2934
3335
|
affectedIds: [`field:${f.id}`, `service:${String(fSid)}`]
|
|
2935
3336
|
});
|
|
2936
3337
|
}
|
|
2937
|
-
for (const o of (
|
|
3338
|
+
for (const { option: o } of walkFieldOptions(f)) {
|
|
2938
3339
|
const oSid = o.service_id;
|
|
2939
3340
|
if (!isServiceIdRef2(oSid)) continue;
|
|
2940
3341
|
const role = fieldRoleOf(f, o);
|
|
@@ -3019,7 +3420,7 @@ function collectServiceItems(args) {
|
|
|
3019
3420
|
}
|
|
3020
3421
|
} else if (includeGroupFallbacks) {
|
|
3021
3422
|
const allowPrimaries = new Set(
|
|
3022
|
-
((
|
|
3423
|
+
((_d = args.visiblePrimaries) != null ? _d : []).map((x) => String(x))
|
|
3023
3424
|
);
|
|
3024
3425
|
for (const primaryKey of allowPrimaries) {
|
|
3025
3426
|
const list = globalFb[primaryKey];
|
|
@@ -3100,17 +3501,15 @@ function affectedFromItems(items) {
|
|
|
3100
3501
|
return uniq(ids);
|
|
3101
3502
|
}
|
|
3102
3503
|
function visibleGroupNodeIds(tag, fields) {
|
|
3103
|
-
var _a;
|
|
3104
3504
|
const ids = [tag.id];
|
|
3105
3505
|
for (const f of fields) {
|
|
3106
|
-
for (const o of (
|
|
3506
|
+
for (const { option: o } of walkFieldOptions(f)) {
|
|
3107
3507
|
ids.push(o.id);
|
|
3108
3508
|
}
|
|
3109
3509
|
}
|
|
3110
3510
|
return uniq(ids);
|
|
3111
3511
|
}
|
|
3112
3512
|
function visibleGroupPrimaries(tag, fields) {
|
|
3113
|
-
var _a;
|
|
3114
3513
|
const prim = [];
|
|
3115
3514
|
const tagSid = tag.service_id;
|
|
3116
3515
|
if (typeof tagSid === "string" || typeof tagSid === "number" && Number.isFinite(tagSid)) {
|
|
@@ -3121,7 +3520,7 @@ function visibleGroupPrimaries(tag, fields) {
|
|
|
3121
3520
|
if (typeof fsid === "string" || typeof fsid === "number" && Number.isFinite(fsid)) {
|
|
3122
3521
|
prim.push(fsid);
|
|
3123
3522
|
}
|
|
3124
|
-
for (const o of (
|
|
3523
|
+
for (const { option: o } of walkFieldOptions(f)) {
|
|
3125
3524
|
const osid = o.service_id;
|
|
3126
3525
|
if (typeof osid === "string" || typeof osid === "number" && Number.isFinite(osid)) {
|
|
3127
3526
|
prim.push(osid);
|
|
@@ -3345,6 +3744,7 @@ function validate(props, ctx = {}) {
|
|
|
3345
3744
|
validateStructure(v);
|
|
3346
3745
|
validateIdentity(v);
|
|
3347
3746
|
validateOptionMaps(v);
|
|
3747
|
+
validateVisibilityCycles(v);
|
|
3348
3748
|
validateOrderKinds(v);
|
|
3349
3749
|
v.fieldsVisibleUnder = createFieldsVisibleUnder(v);
|
|
3350
3750
|
const visSim = readVisibilitySimOpts(options);
|
|
@@ -3478,14 +3878,14 @@ var BuilderImpl = class {
|
|
|
3478
3878
|
const showOptions = showSet.has(f.id);
|
|
3479
3879
|
if (!showOptions) continue;
|
|
3480
3880
|
if (!Array.isArray(f.options)) continue;
|
|
3481
|
-
for (const o of f
|
|
3881
|
+
for (const { option: o, parentId } of walkFieldOptions(f)) {
|
|
3482
3882
|
nodes.push({
|
|
3483
3883
|
id: o.id,
|
|
3484
3884
|
kind: "option",
|
|
3485
3885
|
label: o.label
|
|
3486
3886
|
});
|
|
3487
3887
|
const e = {
|
|
3488
|
-
from: f.id,
|
|
3888
|
+
from: parentId != null ? parentId : f.id,
|
|
3489
3889
|
to: o.id,
|
|
3490
3890
|
kind: "option",
|
|
3491
3891
|
meta: { ownerField: f.id }
|
|
@@ -3532,7 +3932,7 @@ var BuilderImpl = class {
|
|
|
3532
3932
|
return { nodes, edges };
|
|
3533
3933
|
}
|
|
3534
3934
|
cleanedProps() {
|
|
3535
|
-
var _a, _b, _c, _d, _e;
|
|
3935
|
+
var _a, _b, _c, _d, _e, _f;
|
|
3536
3936
|
const fieldIds = new Set(this.props.fields.map((f) => f.id));
|
|
3537
3937
|
const optionIds = /* @__PURE__ */ new Set();
|
|
3538
3938
|
this.optionOwnerById.forEach((_v, oid) => optionIds.add(oid));
|
|
@@ -3544,6 +3944,7 @@ var BuilderImpl = class {
|
|
|
3544
3944
|
}
|
|
3545
3945
|
const incMap = (_c = this.props.includes_for_buttons) != null ? _c : {};
|
|
3546
3946
|
const excMap = (_d = this.props.excludes_for_buttons) != null ? _d : {};
|
|
3947
|
+
const effectMap = (_e = this.props.option_effects_for_buttons) != null ? _e : {};
|
|
3547
3948
|
const includedByButtons = /* @__PURE__ */ new Set();
|
|
3548
3949
|
const referencedKeys = /* @__PURE__ */ new Set();
|
|
3549
3950
|
const referencedOwnerFields = /* @__PURE__ */ new Set();
|
|
@@ -3563,6 +3964,14 @@ var BuilderImpl = class {
|
|
|
3563
3964
|
void fid;
|
|
3564
3965
|
}
|
|
3565
3966
|
}
|
|
3967
|
+
for (const [key, targets] of Object.entries(effectMap)) {
|
|
3968
|
+
referencedKeys.add(key);
|
|
3969
|
+
const owner = this.optionOwnerById.get(key);
|
|
3970
|
+
if (owner) referencedOwnerFields.add(owner.fieldId);
|
|
3971
|
+
for (const [fid, effect] of Object.entries(targets != null ? targets : {})) {
|
|
3972
|
+
if ((effect == null ? void 0 : effect.forceVisible) === true) includedByButtons.add(fid);
|
|
3973
|
+
}
|
|
3974
|
+
}
|
|
3566
3975
|
const boundIds = /* @__PURE__ */ new Set();
|
|
3567
3976
|
for (const f of this.props.fields) {
|
|
3568
3977
|
const b = f.bind_id;
|
|
@@ -3580,6 +3989,7 @@ var BuilderImpl = class {
|
|
|
3580
3989
|
return bound || included || referenced || !excluded;
|
|
3581
3990
|
});
|
|
3582
3991
|
const allowedTargets = new Set(fields.map((f) => f.id));
|
|
3992
|
+
const allowedFieldById = new Map(fields.map((f) => [f.id, f]));
|
|
3583
3993
|
const pruneButtons = (src) => {
|
|
3584
3994
|
if (!src) return void 0;
|
|
3585
3995
|
const out2 = {};
|
|
@@ -3599,13 +4009,52 @@ var BuilderImpl = class {
|
|
|
3599
4009
|
const excludes_for_buttons = pruneButtons(
|
|
3600
4010
|
this.props.excludes_for_buttons
|
|
3601
4011
|
);
|
|
4012
|
+
const pruneOptionEffects = (src) => {
|
|
4013
|
+
var _a2, _b2, _c2, _d2;
|
|
4014
|
+
if (!src) return void 0;
|
|
4015
|
+
const out2 = {};
|
|
4016
|
+
for (const [key, targets] of Object.entries(src)) {
|
|
4017
|
+
const keyIsValid = optionIds.has(key) || fieldIds.has(key);
|
|
4018
|
+
if (!keyIsValid) continue;
|
|
4019
|
+
const cleanedTargets = {};
|
|
4020
|
+
for (const [targetFieldId, effect] of Object.entries(
|
|
4021
|
+
targets != null ? targets : {}
|
|
4022
|
+
)) {
|
|
4023
|
+
const field = allowedFieldById.get(targetFieldId);
|
|
4024
|
+
if (!field || !effect) continue;
|
|
4025
|
+
const validOptionIds = fieldOptionIdSet(field);
|
|
4026
|
+
const include2 = Array.from(
|
|
4027
|
+
new Set((_a2 = effect.include) != null ? _a2 : [])
|
|
4028
|
+
).filter((optionId) => validOptionIds.has(optionId));
|
|
4029
|
+
const exclude2 = Array.from(
|
|
4030
|
+
new Set((_b2 = effect.exclude) != null ? _b2 : [])
|
|
4031
|
+
).filter((optionId) => validOptionIds.has(optionId));
|
|
4032
|
+
const next = {
|
|
4033
|
+
...effect.forceVisible === true ? { forceVisible: true } : {},
|
|
4034
|
+
...include2.length ? { include: include2 } : {},
|
|
4035
|
+
...exclude2.length ? { exclude: exclude2 } : {}
|
|
4036
|
+
};
|
|
4037
|
+
if (next.forceVisible === true || ((_c2 = next.include) == null ? void 0 : _c2.length) || ((_d2 = next.exclude) == null ? void 0 : _d2.length)) {
|
|
4038
|
+
cleanedTargets[targetFieldId] = next;
|
|
4039
|
+
}
|
|
4040
|
+
}
|
|
4041
|
+
if (Object.keys(cleanedTargets).length) {
|
|
4042
|
+
out2[key] = cleanedTargets;
|
|
4043
|
+
}
|
|
4044
|
+
}
|
|
4045
|
+
return Object.keys(out2).length ? out2 : void 0;
|
|
4046
|
+
};
|
|
4047
|
+
const option_effects_for_buttons = pruneOptionEffects(
|
|
4048
|
+
this.props.option_effects_for_buttons
|
|
4049
|
+
);
|
|
3602
4050
|
const out = {
|
|
3603
4051
|
filters: this.props.filters.slice(),
|
|
3604
4052
|
fields,
|
|
3605
4053
|
...this.props.orderKinds ? { orderKinds: this.props.orderKinds } : {},
|
|
3606
4054
|
...includes_for_buttons && { includes_for_buttons },
|
|
3607
4055
|
...excludes_for_buttons && { excludes_for_buttons },
|
|
3608
|
-
|
|
4056
|
+
...option_effects_for_buttons && { option_effects_for_buttons },
|
|
4057
|
+
schema_version: (_f = this.props.schema_version) != null ? _f : "1.0",
|
|
3609
4058
|
// keep fallbacks & other maps as-is
|
|
3610
4059
|
...this.props.fallbacks ? { fallbacks: this.props.fallbacks } : {}
|
|
3611
4060
|
};
|
|
@@ -3618,12 +4067,15 @@ var BuilderImpl = class {
|
|
|
3618
4067
|
return cloneDeep2(this.options);
|
|
3619
4068
|
}
|
|
3620
4069
|
visibleFields(tagId, selectedKeys) {
|
|
4070
|
+
return this.resolveVisibility(tagId, selectedKeys).fieldIds;
|
|
4071
|
+
}
|
|
4072
|
+
resolveVisibility(tagId, selectedKeys) {
|
|
3621
4073
|
var _a;
|
|
3622
|
-
return
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
)
|
|
3626
|
-
|
|
4074
|
+
return resolveVisibility(
|
|
4075
|
+
this.props,
|
|
4076
|
+
tagId,
|
|
4077
|
+
(_a = selectedKeys != null ? selectedKeys : this.options.selectedOptionKeys) != null ? _a : []
|
|
4078
|
+
);
|
|
3627
4079
|
}
|
|
3628
4080
|
getNodeMap() {
|
|
3629
4081
|
if (!this._nodemap) this._nodemap = buildNodeMap(this.getProps());
|
|
@@ -3638,9 +4090,8 @@ var BuilderImpl = class {
|
|
|
3638
4090
|
for (const t of this.props.filters) this.tagById.set(t.id, t);
|
|
3639
4091
|
for (const f of this.props.fields) {
|
|
3640
4092
|
this.fieldById.set(f.id, f);
|
|
3641
|
-
|
|
3642
|
-
|
|
3643
|
-
this.optionOwnerById.set(o.id, { fieldId: f.id });
|
|
4093
|
+
for (const [optionId, owner] of optionOwnerMap([f])) {
|
|
4094
|
+
this.optionOwnerById.set(optionId, { fieldId: owner.fieldId });
|
|
3644
4095
|
}
|
|
3645
4096
|
}
|
|
3646
4097
|
}
|
|
@@ -5077,20 +5528,20 @@ function isFiniteNumber2(v) {
|
|
|
5077
5528
|
|
|
5078
5529
|
// src/utils/build-order-snapshot/selection.ts
|
|
5079
5530
|
function isOptionBased(f) {
|
|
5080
|
-
const hasOptions =
|
|
5531
|
+
const hasOptions = fieldOptionIdSet(f).size > 0;
|
|
5081
5532
|
return hasOptions || isMultiField(f);
|
|
5082
5533
|
}
|
|
5083
5534
|
function toSelectedOptionKeys(byField) {
|
|
5084
5535
|
const keys = [];
|
|
5085
|
-
for (const
|
|
5536
|
+
for (const optionIds of Object.values(byField != null ? byField : {})) {
|
|
5086
5537
|
for (const optionId of optionIds != null ? optionIds : []) {
|
|
5087
|
-
keys.push(
|
|
5538
|
+
keys.push(optionId);
|
|
5088
5539
|
}
|
|
5089
5540
|
}
|
|
5090
5541
|
return keys;
|
|
5091
5542
|
}
|
|
5092
|
-
function getSelectedOptionsByFieldId(selection, fieldById, mode) {
|
|
5093
|
-
var _a
|
|
5543
|
+
function getSelectedOptionsByFieldId(selection, fieldById, mode, visibleOptionsByFieldId) {
|
|
5544
|
+
var _a;
|
|
5094
5545
|
const collected = {};
|
|
5095
5546
|
for (const visit of buildSelectedNodeVisitOrder(selection, fieldById)) {
|
|
5096
5547
|
if (visit.kind !== "option") continue;
|
|
@@ -5101,18 +5552,18 @@ function getSelectedOptionsByFieldId(selection, fieldById, mode) {
|
|
|
5101
5552
|
for (const [fieldId, optionIds] of Object.entries(collected)) {
|
|
5102
5553
|
const field = fieldById.get(fieldId);
|
|
5103
5554
|
if (!field) continue;
|
|
5104
|
-
const validOptionIds =
|
|
5105
|
-
|
|
5106
|
-
);
|
|
5555
|
+
const validOptionIds = fieldOptionIdSet(field);
|
|
5556
|
+
const visibleOptionIds = (visibleOptionsByFieldId == null ? void 0 : visibleOptionsByFieldId[fieldId]) ? new Set(visibleOptionsByFieldId[fieldId]) : void 0;
|
|
5107
5557
|
const dedupedValid = [];
|
|
5108
5558
|
const seen = /* @__PURE__ */ new Set();
|
|
5109
5559
|
for (const optionId of optionIds) {
|
|
5110
5560
|
if (!validOptionIds.has(optionId)) continue;
|
|
5561
|
+
if (visibleOptionIds && !visibleOptionIds.has(optionId)) continue;
|
|
5111
5562
|
if (seen.has(optionId)) continue;
|
|
5112
5563
|
seen.add(optionId);
|
|
5113
5564
|
dedupedValid.push(optionId);
|
|
5114
5565
|
}
|
|
5115
|
-
const isMulti = ((
|
|
5566
|
+
const isMulti = ((_a = field.meta) == null ? void 0 : _a.multi) === true;
|
|
5116
5567
|
const normalized = mode === "prod" && !isMulti ? dedupedValid.length ? [dedupedValid[dedupedValid.length - 1]] : [] : dedupedValid;
|
|
5117
5568
|
if (normalized.length) out[fieldId] = normalized;
|
|
5118
5569
|
}
|
|
@@ -5129,57 +5580,49 @@ function buildSelectedNodeVisitOrder(selection, fieldById) {
|
|
|
5129
5580
|
out.push({ kind: "field", fieldId });
|
|
5130
5581
|
}
|
|
5131
5582
|
function pushOption(fieldId, optionId) {
|
|
5132
|
-
const key = `option:${
|
|
5583
|
+
const key = `option:${optionId}`;
|
|
5133
5584
|
if (seen.has(key)) return;
|
|
5134
5585
|
seen.add(key);
|
|
5135
5586
|
out.push({ kind: "option", fieldId, optionId });
|
|
5136
5587
|
}
|
|
5137
|
-
for (const
|
|
5138
|
-
|
|
5588
|
+
for (const optionId of (_a = selection.optionTraversalOrder) != null ? _a : []) {
|
|
5589
|
+
const ownerField = findOptionOwnerField(fieldById.values(), optionId);
|
|
5590
|
+
if (ownerField) pushOption(ownerField.id, optionId);
|
|
5139
5591
|
}
|
|
5140
5592
|
for (const rawKey of (_b = selection.selectedKeys) != null ? _b : []) {
|
|
5141
5593
|
const key = String(rawKey);
|
|
5142
|
-
if (key.includes("::")) {
|
|
5143
|
-
const [fieldId, optionId] = key.split("::", 2);
|
|
5144
|
-
if (fieldId && optionId) pushOption(fieldId, optionId);
|
|
5145
|
-
continue;
|
|
5146
|
-
}
|
|
5147
5594
|
const field = fieldById.get(key);
|
|
5148
5595
|
if (field) {
|
|
5149
5596
|
pushField(field.id);
|
|
5150
5597
|
continue;
|
|
5151
5598
|
}
|
|
5152
|
-
const ownerField = findOptionOwnerField(
|
|
5599
|
+
const ownerField = findOptionOwnerField(fieldById.values(), key);
|
|
5153
5600
|
if (ownerField) pushOption(ownerField.id, key);
|
|
5154
5601
|
}
|
|
5155
5602
|
for (const [fieldId, optionIds] of Object.entries(
|
|
5156
5603
|
(_c = selection.optionSelectionsByFieldId) != null ? _c : {}
|
|
5157
5604
|
)) {
|
|
5158
|
-
|
|
5605
|
+
const hintedField = fieldById.get(fieldId);
|
|
5606
|
+
if (!hintedField) continue;
|
|
5159
5607
|
for (const optionId of optionIds != null ? optionIds : []) {
|
|
5160
|
-
|
|
5608
|
+
const ownerField = findOptionOwnerField(fieldById.values(), optionId);
|
|
5609
|
+
if ((ownerField == null ? void 0 : ownerField.id) === hintedField.id) {
|
|
5610
|
+
pushOption(ownerField.id, optionId);
|
|
5611
|
+
}
|
|
5161
5612
|
}
|
|
5162
5613
|
}
|
|
5163
5614
|
return out;
|
|
5164
5615
|
}
|
|
5165
|
-
function findOptionOwnerField(optionId, fieldById) {
|
|
5166
|
-
var _a;
|
|
5167
|
-
for (const field of fieldById.values()) {
|
|
5168
|
-
if ((_a = field.options) == null ? void 0 : _a.some((option) => option.id === optionId)) return field;
|
|
5169
|
-
}
|
|
5170
|
-
return void 0;
|
|
5171
|
-
}
|
|
5172
5616
|
|
|
5173
5617
|
// src/utils/build-order-snapshot/services.ts
|
|
5174
5618
|
function isServiceBased(field) {
|
|
5175
|
-
var _a;
|
|
5176
5619
|
if (field.service_id !== void 0 && field.service_id !== null) return true;
|
|
5177
|
-
return
|
|
5178
|
-
(
|
|
5179
|
-
)
|
|
5620
|
+
return walkFieldOptions(field).some(
|
|
5621
|
+
({ option }) => option.service_id !== void 0 && option.service_id !== null
|
|
5622
|
+
);
|
|
5180
5623
|
}
|
|
5181
5624
|
function resolveServices(tagId, visibleFieldIds, selection, tagById, fieldById, services) {
|
|
5182
|
-
var _a, _b, _c
|
|
5625
|
+
var _a, _b, _c;
|
|
5183
5626
|
const serviceMap = {};
|
|
5184
5627
|
const visible = new Set(visibleFieldIds);
|
|
5185
5628
|
const selectedBaseServices = [];
|
|
@@ -5206,9 +5649,9 @@ function resolveServices(tagId, visibleFieldIds, selection, tagById, fieldById,
|
|
|
5206
5649
|
}
|
|
5207
5650
|
continue;
|
|
5208
5651
|
}
|
|
5209
|
-
const option = (
|
|
5652
|
+
const option = findFieldOption(field, visit.optionId);
|
|
5210
5653
|
if (!option) continue;
|
|
5211
|
-
const role = (
|
|
5654
|
+
const role = (_c = (_b = option.pricing_role) != null ? _b : field.pricing_role) != null ? _c : "base";
|
|
5212
5655
|
if (role === "utility") continue;
|
|
5213
5656
|
if (option.service_id !== void 0 && option.service_id !== null) {
|
|
5214
5657
|
addSelectedBaseService(option.id, option.service_id);
|
|
@@ -5339,16 +5782,15 @@ function resolveQuantity(visibleFieldIds, fieldById, tagById, selection, tagId,
|
|
|
5339
5782
|
return { quantity: hostDefault, source: { kind: "default", defaultedFromHost: true } };
|
|
5340
5783
|
}
|
|
5341
5784
|
function resolveNodeDefaultQuantity(visibleFieldIds, fieldById, tagById, selection, tagId) {
|
|
5342
|
-
var _a, _b
|
|
5785
|
+
var _a, _b;
|
|
5343
5786
|
const visible = new Set(visibleFieldIds);
|
|
5344
5787
|
const visits = buildSelectedNodeVisitOrder(selection, fieldById);
|
|
5345
5788
|
for (const visit of visits) {
|
|
5346
5789
|
if (visit.kind !== "option") continue;
|
|
5347
5790
|
if (!visible.has(visit.fieldId)) continue;
|
|
5348
5791
|
const field = fieldById.get(visit.fieldId);
|
|
5349
|
-
|
|
5350
|
-
const
|
|
5351
|
-
const quantity = readPositiveFiniteNumber((_b = option == null ? void 0 : option.meta) == null ? void 0 : _b.quantityDefault);
|
|
5792
|
+
const option = findFieldOption(field, visit.optionId);
|
|
5793
|
+
const quantity = readPositiveFiniteNumber((_a = option == null ? void 0 : option.meta) == null ? void 0 : _a.quantityDefault);
|
|
5352
5794
|
if (quantity !== void 0) {
|
|
5353
5795
|
return { quantity, source: { kind: "option", id: option.id } };
|
|
5354
5796
|
}
|
|
@@ -5363,7 +5805,7 @@ function resolveNodeDefaultQuantity(visibleFieldIds, fieldById, tagById, selecti
|
|
|
5363
5805
|
}
|
|
5364
5806
|
}
|
|
5365
5807
|
const tag = tagById.get(tagId);
|
|
5366
|
-
const tagQuantity = readPositiveFiniteNumber((
|
|
5808
|
+
const tagQuantity = readPositiveFiniteNumber((_b = tag == null ? void 0 : tag.meta) == null ? void 0 : _b.quantityDefault);
|
|
5367
5809
|
if (tagQuantity !== void 0) {
|
|
5368
5810
|
return { quantity: tagQuantity, source: { kind: "tag", id: tagId } };
|
|
5369
5811
|
}
|
|
@@ -5466,12 +5908,10 @@ function collectUtilityLineItems(visibleFieldIds, fieldById, selection, selected
|
|
|
5466
5908
|
const item = buildUtilityItemFromMarker(field.id, marker, quantity, value);
|
|
5467
5909
|
if (item) items.push(item);
|
|
5468
5910
|
}
|
|
5469
|
-
|
|
5470
|
-
|
|
5471
|
-
if (!selectedOptionIds.length) continue;
|
|
5472
|
-
const optById = new Map(field.options.map((o) => [o.id, o]));
|
|
5911
|
+
const selectedOptionIds = (_c = selectedOptionsByFieldId[field.id]) != null ? _c : [];
|
|
5912
|
+
if (selectedOptionIds.length) {
|
|
5473
5913
|
for (const oid of selectedOptionIds) {
|
|
5474
|
-
const option =
|
|
5914
|
+
const option = findFieldOption(field, oid);
|
|
5475
5915
|
if (!option) continue;
|
|
5476
5916
|
if (((_d = option.pricing_role) != null ? _d : "base") !== "utility") continue;
|
|
5477
5917
|
const optionMarker = readUtilityMarker((_e = option.meta) == null ? void 0 : _e.utility);
|
|
@@ -5587,7 +6027,7 @@ function buildDevWarnings(props, svcMap, originalFallbacks, fieldById, visibleFi
|
|
|
5587
6027
|
|
|
5588
6028
|
// src/utils/build-order-snapshot/index.ts
|
|
5589
6029
|
function buildOrderSnapshot(props, builder, selection, services, settings = {}) {
|
|
5590
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
6030
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
5591
6031
|
const mode = (_a = settings.mode) != null ? _a : "prod";
|
|
5592
6032
|
const hostDefaultQty = Number.isFinite((_b = settings.hostDefaultQuantity) != null ? _b : 1) ? settings.hostDefaultQuantity : 1;
|
|
5593
6033
|
const fbSettings = {
|
|
@@ -5600,14 +6040,31 @@ function buildOrderSnapshot(props, builder, selection, services, settings = {})
|
|
|
5600
6040
|
const builtAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
5601
6041
|
const tagId = selection.activeTagId;
|
|
5602
6042
|
const selectedButtonKeys = (_d = selection.selectedKeys) != null ? _d : toSelectedOptionKeys(selection.optionSelectionsByFieldId);
|
|
5603
|
-
const visibleFieldIds = builder.visibleFields(tagId, selectedButtonKeys);
|
|
5604
6043
|
const tagById = new Map(((_e = props.filters) != null ? _e : []).map((t) => [t.id, t]));
|
|
5605
6044
|
const fieldById = new Map(((_f = props.fields) != null ? _f : []).map((f) => [f.id, f]));
|
|
5606
|
-
const
|
|
6045
|
+
const resolve = typeof builder.resolveVisibility === "function" ? builder.resolveVisibility.bind(builder) : void 0;
|
|
6046
|
+
let resolvedVisibility = resolve == null ? void 0 : resolve(tagId, selectedButtonKeys);
|
|
6047
|
+
let visibleFieldIds = (_g = resolvedVisibility == null ? void 0 : resolvedVisibility.fieldIds) != null ? _g : builder.visibleFields(tagId, selectedButtonKeys);
|
|
6048
|
+
const filteredSelectedButtonKeys = filterSelectedKeysByVisibility(
|
|
6049
|
+
selectedButtonKeys,
|
|
6050
|
+
visibleFieldIds,
|
|
6051
|
+
resolvedVisibility == null ? void 0 : resolvedVisibility.optionsByFieldId,
|
|
6052
|
+
fieldById
|
|
6053
|
+
);
|
|
6054
|
+
if (resolve && filteredSelectedButtonKeys.join("\0") !== selectedButtonKeys.join("\0")) {
|
|
6055
|
+
resolvedVisibility = resolve(tagId, filteredSelectedButtonKeys);
|
|
6056
|
+
visibleFieldIds = resolvedVisibility.fieldIds;
|
|
6057
|
+
}
|
|
6058
|
+
const effectiveSelection = {
|
|
6059
|
+
...selection,
|
|
6060
|
+
selectedKeys: filteredSelectedButtonKeys
|
|
6061
|
+
};
|
|
6062
|
+
const tagConstraints = (_i = (_h = tagById.get(tagId)) == null ? void 0 : _h.constraints) != null ? _i : void 0;
|
|
5607
6063
|
const selectedOptionsByFieldId = getSelectedOptionsByFieldId(
|
|
5608
|
-
|
|
6064
|
+
effectiveSelection,
|
|
5609
6065
|
fieldById,
|
|
5610
|
-
mode
|
|
6066
|
+
mode,
|
|
6067
|
+
resolvedVisibility == null ? void 0 : resolvedVisibility.optionsByFieldId
|
|
5611
6068
|
);
|
|
5612
6069
|
const selectionFields = visibleFieldIds.map((fid) => fieldById.get(fid)).filter((f) => !!f).map((f) => {
|
|
5613
6070
|
var _a2;
|
|
@@ -5621,21 +6078,21 @@ function buildOrderSnapshot(props, builder, selection, services, settings = {})
|
|
|
5621
6078
|
const { formValues, selections } = buildInputs(
|
|
5622
6079
|
visibleFieldIds,
|
|
5623
6080
|
fieldById,
|
|
5624
|
-
|
|
6081
|
+
effectiveSelection,
|
|
5625
6082
|
selectedOptionsByFieldId
|
|
5626
6083
|
);
|
|
5627
6084
|
const qtyRes = resolveQuantity(
|
|
5628
6085
|
visibleFieldIds,
|
|
5629
6086
|
fieldById,
|
|
5630
6087
|
tagById,
|
|
5631
|
-
|
|
6088
|
+
effectiveSelection,
|
|
5632
6089
|
tagId,
|
|
5633
6090
|
hostDefaultQty
|
|
5634
6091
|
);
|
|
5635
6092
|
const { serviceMap, servicesList } = resolveServices(
|
|
5636
6093
|
tagId,
|
|
5637
6094
|
visibleFieldIds,
|
|
5638
|
-
|
|
6095
|
+
effectiveSelection,
|
|
5639
6096
|
tagById,
|
|
5640
6097
|
fieldById,
|
|
5641
6098
|
services
|
|
@@ -5657,7 +6114,7 @@ function buildOrderSnapshot(props, builder, selection, services, settings = {})
|
|
|
5657
6114
|
const utilities = collectUtilityLineItems(
|
|
5658
6115
|
visibleFieldIds,
|
|
5659
6116
|
fieldById,
|
|
5660
|
-
|
|
6117
|
+
effectiveSelection,
|
|
5661
6118
|
selectedOptionsByFieldId,
|
|
5662
6119
|
qtyRes.quantity
|
|
5663
6120
|
);
|
|
@@ -5667,7 +6124,7 @@ function buildOrderSnapshot(props, builder, selection, services, settings = {})
|
|
|
5667
6124
|
prunedFallbacks.original,
|
|
5668
6125
|
fieldById,
|
|
5669
6126
|
visibleFieldIds,
|
|
5670
|
-
|
|
6127
|
+
effectiveSelection
|
|
5671
6128
|
) : void 0;
|
|
5672
6129
|
const meta = {
|
|
5673
6130
|
schema_version: props.schema_version,
|
|
@@ -5680,7 +6137,7 @@ function buildOrderSnapshot(props, builder, selection, services, settings = {})
|
|
|
5680
6137
|
tagId,
|
|
5681
6138
|
visibleFieldIds,
|
|
5682
6139
|
fieldById,
|
|
5683
|
-
|
|
6140
|
+
effectiveSelection,
|
|
5684
6141
|
selectedOptionsByFieldId
|
|
5685
6142
|
),
|
|
5686
6143
|
policy: toSnapshotPolicy(fbSettings)
|
|
@@ -5692,7 +6149,7 @@ function buildOrderSnapshot(props, builder, selection, services, settings = {})
|
|
|
5692
6149
|
builtAt,
|
|
5693
6150
|
selection: {
|
|
5694
6151
|
tag: tagId,
|
|
5695
|
-
buttons:
|
|
6152
|
+
buttons: filteredSelectedButtonKeys,
|
|
5696
6153
|
fields: selectionFields
|
|
5697
6154
|
},
|
|
5698
6155
|
inputs: { form: formValues, selections },
|
|
@@ -5710,6 +6167,24 @@ function buildOrderSnapshot(props, builder, selection, services, settings = {})
|
|
|
5710
6167
|
meta
|
|
5711
6168
|
};
|
|
5712
6169
|
}
|
|
6170
|
+
function filterSelectedKeysByVisibility(selectedKeys, visibleFieldIds, optionsByFieldId, fieldById) {
|
|
6171
|
+
if (!optionsByFieldId) return selectedKeys;
|
|
6172
|
+
const visibleFields = new Set(visibleFieldIds);
|
|
6173
|
+
const out = [];
|
|
6174
|
+
for (const rawKey of selectedKeys) {
|
|
6175
|
+
const key = String(rawKey);
|
|
6176
|
+
if (fieldById.has(key)) {
|
|
6177
|
+
if (visibleFields.has(key)) out.push(key);
|
|
6178
|
+
continue;
|
|
6179
|
+
}
|
|
6180
|
+
const owner = findOptionOwnerField(fieldById.values(), key);
|
|
6181
|
+
if (!owner || !visibleFields.has(owner.id)) continue;
|
|
6182
|
+
const allowed = optionsByFieldId[owner.id];
|
|
6183
|
+
if (allowed && !allowed.includes(key)) continue;
|
|
6184
|
+
out.push(key);
|
|
6185
|
+
}
|
|
6186
|
+
return out;
|
|
6187
|
+
}
|
|
5713
6188
|
|
|
5714
6189
|
// src/core/fallback-editor.ts
|
|
5715
6190
|
function createFallbackEditor(options = {}) {
|
|
@@ -6189,6 +6664,97 @@ function bumpSuffix(old) {
|
|
|
6189
6664
|
return `${stem}${parseInt(m[2], 10) + 1}`;
|
|
6190
6665
|
}
|
|
6191
6666
|
|
|
6667
|
+
// src/react/canvas/editor/editor-utils.ts
|
|
6668
|
+
function ownerOfOption(props, optionId) {
|
|
6669
|
+
var _a;
|
|
6670
|
+
for (const f of (_a = props.fields) != null ? _a : []) {
|
|
6671
|
+
const found = findOptionLocationInField(f, optionId);
|
|
6672
|
+
if (found) return { fieldId: f.id, index: found.index };
|
|
6673
|
+
}
|
|
6674
|
+
return null;
|
|
6675
|
+
}
|
|
6676
|
+
function findMutableOption(props, optionId) {
|
|
6677
|
+
var _a;
|
|
6678
|
+
for (const field of (_a = props.fields) != null ? _a : []) {
|
|
6679
|
+
const found = findOptionLocationInField(field, optionId);
|
|
6680
|
+
if (found) return { field, ...found };
|
|
6681
|
+
}
|
|
6682
|
+
return void 0;
|
|
6683
|
+
}
|
|
6684
|
+
function collectFieldOptionIds(field) {
|
|
6685
|
+
const out = [];
|
|
6686
|
+
const visit = (options) => {
|
|
6687
|
+
for (const option of options != null ? options : []) {
|
|
6688
|
+
out.push(String(option.id));
|
|
6689
|
+
visit(option.children);
|
|
6690
|
+
}
|
|
6691
|
+
};
|
|
6692
|
+
visit(field == null ? void 0 : field.options);
|
|
6693
|
+
return out;
|
|
6694
|
+
}
|
|
6695
|
+
function findOptionLocationInField(field, optionId) {
|
|
6696
|
+
const visit = (siblings, parent) => {
|
|
6697
|
+
if (!siblings) return void 0;
|
|
6698
|
+
const index = siblings.findIndex((option) => option.id === optionId);
|
|
6699
|
+
if (index >= 0) {
|
|
6700
|
+
return {
|
|
6701
|
+
option: siblings[index],
|
|
6702
|
+
siblings,
|
|
6703
|
+
index,
|
|
6704
|
+
parent
|
|
6705
|
+
};
|
|
6706
|
+
}
|
|
6707
|
+
for (const option of siblings) {
|
|
6708
|
+
const found = visit(option.children, option);
|
|
6709
|
+
if (found) return found;
|
|
6710
|
+
}
|
|
6711
|
+
return void 0;
|
|
6712
|
+
};
|
|
6713
|
+
return visit(field.options);
|
|
6714
|
+
}
|
|
6715
|
+
function hasFieldOptions(field) {
|
|
6716
|
+
return Array.isArray(field == null ? void 0 : field.options) && field.options.length > 0;
|
|
6717
|
+
}
|
|
6718
|
+
function isActualButtonField(field) {
|
|
6719
|
+
return (field == null ? void 0 : field.button) === true && !hasFieldOptions(field);
|
|
6720
|
+
}
|
|
6721
|
+
function clearFieldButtonReceiverMaps(props, fieldId) {
|
|
6722
|
+
var _a, _b, _c;
|
|
6723
|
+
if ((_a = props.includes_for_buttons) == null ? void 0 : _a[fieldId]) {
|
|
6724
|
+
delete props.includes_for_buttons[fieldId];
|
|
6725
|
+
}
|
|
6726
|
+
if ((_b = props.excludes_for_buttons) == null ? void 0 : _b[fieldId]) {
|
|
6727
|
+
delete props.excludes_for_buttons[fieldId];
|
|
6728
|
+
}
|
|
6729
|
+
if (props.includes_for_buttons && Object.keys(props.includes_for_buttons).length === 0) {
|
|
6730
|
+
delete props.includes_for_buttons;
|
|
6731
|
+
}
|
|
6732
|
+
if (props.excludes_for_buttons && Object.keys(props.excludes_for_buttons).length === 0) {
|
|
6733
|
+
delete props.excludes_for_buttons;
|
|
6734
|
+
}
|
|
6735
|
+
if ((_c = props.option_effects_for_buttons) == null ? void 0 : _c[fieldId]) {
|
|
6736
|
+
delete props.option_effects_for_buttons[fieldId];
|
|
6737
|
+
}
|
|
6738
|
+
if (props.option_effects_for_buttons && Object.keys(props.option_effects_for_buttons).length === 0) {
|
|
6739
|
+
delete props.option_effects_for_buttons;
|
|
6740
|
+
}
|
|
6741
|
+
}
|
|
6742
|
+
function ensureServiceExists(opts, id) {
|
|
6743
|
+
if (typeof opts.serviceExists === "function") {
|
|
6744
|
+
if (!opts.serviceExists(id)) {
|
|
6745
|
+
throw new Error(`service_not_found:${String(id)}`);
|
|
6746
|
+
}
|
|
6747
|
+
return;
|
|
6748
|
+
}
|
|
6749
|
+
if (opts.serviceMap) {
|
|
6750
|
+
if (!Object.prototype.hasOwnProperty.call(opts.serviceMap, id)) {
|
|
6751
|
+
throw new Error(`service_not_found:${String(id)}`);
|
|
6752
|
+
}
|
|
6753
|
+
return;
|
|
6754
|
+
}
|
|
6755
|
+
throw new Error("service_checker_missing");
|
|
6756
|
+
}
|
|
6757
|
+
|
|
6192
6758
|
// src/react/canvas/editor/editor-duplicate.ts
|
|
6193
6759
|
function duplicate(ctx, ref, opts = {}) {
|
|
6194
6760
|
const snapBefore = ctx.makeSnapshot("duplicate:before");
|
|
@@ -6263,14 +6829,66 @@ function duplicateInPlace(ctx, ref, opts = {}) {
|
|
|
6263
6829
|
return duplicateOption(ctx, ref.fieldId, ref.id, opts);
|
|
6264
6830
|
}
|
|
6265
6831
|
function ownerFieldOfOption(props, optionId) {
|
|
6266
|
-
var _a
|
|
6832
|
+
var _a;
|
|
6267
6833
|
for (const field of (_a = props.fields) != null ? _a : []) {
|
|
6268
|
-
if ((
|
|
6834
|
+
if (findMutableOption({ ...props, fields: [field] }, optionId)) {
|
|
6269
6835
|
return { fieldId: field.id };
|
|
6270
6836
|
}
|
|
6271
6837
|
}
|
|
6272
6838
|
return null;
|
|
6273
6839
|
}
|
|
6840
|
+
function cloneOptionTree(ctx, fieldId, option, opts, optionIdMap) {
|
|
6841
|
+
var _a, _b, _c, _d;
|
|
6842
|
+
const newId = ctx.uniqueOptionId(
|
|
6843
|
+
fieldId,
|
|
6844
|
+
((_a = opts.optionIdStrategy) != null ? _a : defaultOptionIdStrategy)(option.id)
|
|
6845
|
+
);
|
|
6846
|
+
optionIdMap.set(option.id, newId);
|
|
6847
|
+
const children = (_b = option.children) == null ? void 0 : _b.map(
|
|
6848
|
+
(child) => cloneOptionTree(ctx, fieldId, child, opts, optionIdMap)
|
|
6849
|
+
);
|
|
6850
|
+
return {
|
|
6851
|
+
...option,
|
|
6852
|
+
id: newId,
|
|
6853
|
+
label: ((_c = opts.labelStrategy) != null ? _c : nextCopyLabel)((_d = option.label) != null ? _d : option.id),
|
|
6854
|
+
...(children == null ? void 0 : children.length) ? { children } : {}
|
|
6855
|
+
};
|
|
6856
|
+
}
|
|
6857
|
+
function remapEffect(effect, optionIdMap) {
|
|
6858
|
+
const remapList = (values) => values == null ? void 0 : values.map((value) => {
|
|
6859
|
+
var _a;
|
|
6860
|
+
return (_a = optionIdMap.get(value)) != null ? _a : value;
|
|
6861
|
+
});
|
|
6862
|
+
return {
|
|
6863
|
+
...effect,
|
|
6864
|
+
...effect.include ? { include: remapList(effect.include) } : {},
|
|
6865
|
+
...effect.exclude ? { exclude: remapList(effect.exclude) } : {}
|
|
6866
|
+
};
|
|
6867
|
+
}
|
|
6868
|
+
function copyOptionEffects(props, args) {
|
|
6869
|
+
var _a, _b, _c, _d, _e;
|
|
6870
|
+
const source = props.option_effects_for_buttons;
|
|
6871
|
+
if (!source) return;
|
|
6872
|
+
const next = {
|
|
6873
|
+
...source
|
|
6874
|
+
};
|
|
6875
|
+
const triggerIdMap = (_a = args.triggerIdMap) != null ? _a : /* @__PURE__ */ new Map();
|
|
6876
|
+
const targetFieldIdMap = (_b = args.targetFieldIdMap) != null ? _b : /* @__PURE__ */ new Map();
|
|
6877
|
+
const optionIdMap = (_c = args.optionIdMap) != null ? _c : /* @__PURE__ */ new Map();
|
|
6878
|
+
for (const [oldTriggerId, targetMap] of Object.entries(source)) {
|
|
6879
|
+
const newTriggerId = triggerIdMap.get(oldTriggerId);
|
|
6880
|
+
if (!newTriggerId) continue;
|
|
6881
|
+
const copiedTargets = {
|
|
6882
|
+
...(_d = next[newTriggerId]) != null ? _d : {}
|
|
6883
|
+
};
|
|
6884
|
+
for (const [oldTargetFieldId, effect] of Object.entries(targetMap != null ? targetMap : {})) {
|
|
6885
|
+
const newTargetFieldId = (_e = targetFieldIdMap.get(oldTargetFieldId)) != null ? _e : oldTargetFieldId;
|
|
6886
|
+
copiedTargets[newTargetFieldId] = remapEffect(effect, optionIdMap);
|
|
6887
|
+
}
|
|
6888
|
+
next[newTriggerId] = copiedTargets;
|
|
6889
|
+
}
|
|
6890
|
+
props.option_effects_for_buttons = next;
|
|
6891
|
+
}
|
|
6274
6892
|
function duplicateTag(ctx, tagId, opts) {
|
|
6275
6893
|
var _a, _b, _c, _d;
|
|
6276
6894
|
const props = ctx.getProps();
|
|
@@ -6326,7 +6944,7 @@ function duplicateTag(ctx, tagId, opts) {
|
|
|
6326
6944
|
return id;
|
|
6327
6945
|
}
|
|
6328
6946
|
function duplicateField(ctx, fieldId, opts) {
|
|
6329
|
-
var _a, _b, _c, _d, _e, _f
|
|
6947
|
+
var _a, _b, _c, _d, _e, _f;
|
|
6330
6948
|
const props = ctx.getProps();
|
|
6331
6949
|
const fields = (_a = props.fields) != null ? _a : [];
|
|
6332
6950
|
const src = fields.find((f) => f.id === fieldId);
|
|
@@ -6334,21 +6952,10 @@ function duplicateField(ctx, fieldId, opts) {
|
|
|
6334
6952
|
const id = (_b = opts.id) != null ? _b : ctx.uniqueId(src.id);
|
|
6335
6953
|
const label = ((_c = opts.labelStrategy) != null ? _c : nextCopyLabel)((_d = src.label) != null ? _d : id);
|
|
6336
6954
|
const name = opts.nameStrategy ? opts.nameStrategy(src.name) : nextCopyName(src.name);
|
|
6337
|
-
const
|
|
6338
|
-
|
|
6339
|
-
|
|
6340
|
-
|
|
6341
|
-
((_a2 = opts.optionIdStrategy) != null ? _a2 : defaultOptionIdStrategy)(old)
|
|
6342
|
-
);
|
|
6343
|
-
};
|
|
6344
|
-
const clonedOptions = ((_e = src.options) != null ? _e : []).map((o) => {
|
|
6345
|
-
var _a2, _b2;
|
|
6346
|
-
return {
|
|
6347
|
-
...o,
|
|
6348
|
-
id: optId(o.id),
|
|
6349
|
-
label: ((_a2 = opts.labelStrategy) != null ? _a2 : nextCopyLabel)((_b2 = o.label) != null ? _b2 : o.id)
|
|
6350
|
-
};
|
|
6351
|
-
});
|
|
6955
|
+
const optionIdMap = /* @__PURE__ */ new Map();
|
|
6956
|
+
const clonedOptions = ((_e = src.options) != null ? _e : []).map(
|
|
6957
|
+
(o) => cloneOptionTree(ctx, id, o, opts, optionIdMap)
|
|
6958
|
+
);
|
|
6352
6959
|
const cloned = {
|
|
6353
6960
|
...src,
|
|
6354
6961
|
id,
|
|
@@ -6357,14 +6964,8 @@ function duplicateField(ctx, fieldId, opts) {
|
|
|
6357
6964
|
bind_id: ((_f = opts.copyBindings) != null ? _f : true) ? src.bind_id : void 0,
|
|
6358
6965
|
options: clonedOptions
|
|
6359
6966
|
};
|
|
6360
|
-
const optionIdMap = /* @__PURE__ */ new Map();
|
|
6361
|
-
((_g = src.options) != null ? _g : []).forEach((o, i) => {
|
|
6362
|
-
var _a2, _b2;
|
|
6363
|
-
const newOptId = (_b2 = (_a2 = clonedOptions[i]) == null ? void 0 : _a2.id) != null ? _b2 : o.id;
|
|
6364
|
-
optionIdMap.set(o.id, newOptId);
|
|
6365
|
-
});
|
|
6366
6967
|
ctx.patchProps((p) => {
|
|
6367
|
-
var _a2, _b2, _c2, _d2, _e2, _f2,
|
|
6968
|
+
var _a2, _b2, _c2, _d2, _e2, _f2, _g;
|
|
6368
6969
|
const arr = (_a2 = p.fields) != null ? _a2 : [];
|
|
6369
6970
|
const idx = arr.findIndex((f) => f.id === fieldId);
|
|
6370
6971
|
arr.splice(idx + 1, 0, cloned);
|
|
@@ -6402,52 +7003,56 @@ function duplicateField(ctx, fieldId, opts) {
|
|
|
6402
7003
|
}
|
|
6403
7004
|
if (optionIdMap.has(key)) {
|
|
6404
7005
|
const newKey = optionIdMap.get(key);
|
|
6405
|
-
const merged = /* @__PURE__ */ new Set([...(
|
|
7006
|
+
const merged = /* @__PURE__ */ new Set([...(_g = nextMap[newKey]) != null ? _g : [], ...targets]);
|
|
6406
7007
|
nextMap[newKey] = Array.from(merged);
|
|
6407
7008
|
}
|
|
6408
7009
|
}
|
|
6409
7010
|
p[mapKey] = nextMap;
|
|
6410
7011
|
}
|
|
7012
|
+
copyOptionEffects(p, {
|
|
7013
|
+
triggerIdMap: new Map([
|
|
7014
|
+
[fieldId, id],
|
|
7015
|
+
...Array.from(optionIdMap.entries())
|
|
7016
|
+
]),
|
|
7017
|
+
targetFieldIdMap: /* @__PURE__ */ new Map([[fieldId, id]]),
|
|
7018
|
+
optionIdMap
|
|
7019
|
+
});
|
|
6411
7020
|
}
|
|
6412
7021
|
});
|
|
6413
7022
|
return id;
|
|
6414
7023
|
}
|
|
6415
7024
|
function duplicateOption(ctx, fieldId, optionId, opts) {
|
|
6416
|
-
var _a, _b, _c, _d, _e, _f;
|
|
6417
7025
|
const props = ctx.getProps();
|
|
6418
|
-
const
|
|
6419
|
-
|
|
6420
|
-
|
|
6421
|
-
const optIdx = ((_b = f.options) != null ? _b : []).findIndex((o) => o.id === optionId);
|
|
6422
|
-
if (optIdx < 0) {
|
|
6423
|
-
throw new Error(`Option not found: ${fieldId}::${optionId}`);
|
|
7026
|
+
const location = findMutableOption(props, optionId);
|
|
7027
|
+
if (!location || location.field.id !== fieldId) {
|
|
7028
|
+
throw new Error(`Option not found: ${fieldId}/${optionId}`);
|
|
6424
7029
|
}
|
|
6425
|
-
const src =
|
|
6426
|
-
const
|
|
6427
|
-
|
|
6428
|
-
|
|
6429
|
-
);
|
|
6430
|
-
const newLabel = ((_e = opts.labelStrategy) != null ? _e : nextCopyLabel)((_f = src.label) != null ? _f : src.id);
|
|
7030
|
+
const src = location.option;
|
|
7031
|
+
const optionIdMap = /* @__PURE__ */ new Map();
|
|
7032
|
+
const clone2 = cloneOptionTree(ctx, fieldId, src, opts, optionIdMap);
|
|
7033
|
+
const newId = clone2.id;
|
|
6431
7034
|
ctx.patchProps((p) => {
|
|
6432
|
-
var
|
|
6433
|
-
const
|
|
6434
|
-
|
|
6435
|
-
|
|
6436
|
-
arr.splice(optIdx + 1, 0, clone2);
|
|
6437
|
-
fld.options = arr;
|
|
7035
|
+
var _a;
|
|
7036
|
+
const current = findMutableOption(p, optionId);
|
|
7037
|
+
if (!current) return;
|
|
7038
|
+
current.siblings.splice(current.index + 1, 0, clone2);
|
|
6438
7039
|
if (opts.copyOptionMaps) {
|
|
6439
|
-
const oldKey = `${fieldId}::${optionId}`;
|
|
6440
|
-
const newKey = `${fieldId}::${newId}`;
|
|
6441
7040
|
for (const mapKey of [
|
|
6442
7041
|
"includes_for_buttons",
|
|
6443
7042
|
"excludes_for_buttons"
|
|
6444
7043
|
]) {
|
|
6445
|
-
const m = (
|
|
6446
|
-
|
|
6447
|
-
|
|
6448
|
-
|
|
7044
|
+
const m = (_a = p[mapKey]) != null ? _a : {};
|
|
7045
|
+
for (const [oldKey, newKey] of optionIdMap.entries()) {
|
|
7046
|
+
if (m[oldKey]) {
|
|
7047
|
+
m[newKey] = Array.from(new Set(m[oldKey]));
|
|
7048
|
+
p[mapKey] = m;
|
|
7049
|
+
}
|
|
6449
7050
|
}
|
|
6450
7051
|
}
|
|
7052
|
+
copyOptionEffects(p, {
|
|
7053
|
+
triggerIdMap: optionIdMap,
|
|
7054
|
+
optionIdMap
|
|
7055
|
+
});
|
|
6451
7056
|
}
|
|
6452
7057
|
});
|
|
6453
7058
|
return newId;
|
|
@@ -6509,54 +7114,6 @@ function removeNotice(ctx, id) {
|
|
|
6509
7114
|
|
|
6510
7115
|
// src/react/canvas/editor/editor-nodes.ts
|
|
6511
7116
|
import { cloneDeep as cloneDeep3 } from "lodash-es";
|
|
6512
|
-
|
|
6513
|
-
// src/react/canvas/editor/editor-utils.ts
|
|
6514
|
-
function ownerOfOption(props, optionId) {
|
|
6515
|
-
var _a, _b;
|
|
6516
|
-
for (const f of (_a = props.fields) != null ? _a : []) {
|
|
6517
|
-
const idx = ((_b = f.options) != null ? _b : []).findIndex((o) => o.id === optionId);
|
|
6518
|
-
if (idx >= 0) return { fieldId: f.id, index: idx };
|
|
6519
|
-
}
|
|
6520
|
-
return null;
|
|
6521
|
-
}
|
|
6522
|
-
function hasFieldOptions(field) {
|
|
6523
|
-
return Array.isArray(field == null ? void 0 : field.options) && field.options.length > 0;
|
|
6524
|
-
}
|
|
6525
|
-
function isActualButtonField(field) {
|
|
6526
|
-
return (field == null ? void 0 : field.button) === true && !hasFieldOptions(field);
|
|
6527
|
-
}
|
|
6528
|
-
function clearFieldButtonReceiverMaps(props, fieldId) {
|
|
6529
|
-
var _a, _b;
|
|
6530
|
-
if ((_a = props.includes_for_buttons) == null ? void 0 : _a[fieldId]) {
|
|
6531
|
-
delete props.includes_for_buttons[fieldId];
|
|
6532
|
-
}
|
|
6533
|
-
if ((_b = props.excludes_for_buttons) == null ? void 0 : _b[fieldId]) {
|
|
6534
|
-
delete props.excludes_for_buttons[fieldId];
|
|
6535
|
-
}
|
|
6536
|
-
if (props.includes_for_buttons && Object.keys(props.includes_for_buttons).length === 0) {
|
|
6537
|
-
delete props.includes_for_buttons;
|
|
6538
|
-
}
|
|
6539
|
-
if (props.excludes_for_buttons && Object.keys(props.excludes_for_buttons).length === 0) {
|
|
6540
|
-
delete props.excludes_for_buttons;
|
|
6541
|
-
}
|
|
6542
|
-
}
|
|
6543
|
-
function ensureServiceExists(opts, id) {
|
|
6544
|
-
if (typeof opts.serviceExists === "function") {
|
|
6545
|
-
if (!opts.serviceExists(id)) {
|
|
6546
|
-
throw new Error(`service_not_found:${String(id)}`);
|
|
6547
|
-
}
|
|
6548
|
-
return;
|
|
6549
|
-
}
|
|
6550
|
-
if (opts.serviceMap) {
|
|
6551
|
-
if (!Object.prototype.hasOwnProperty.call(opts.serviceMap, id)) {
|
|
6552
|
-
throw new Error(`service_not_found:${String(id)}`);
|
|
6553
|
-
}
|
|
6554
|
-
return;
|
|
6555
|
-
}
|
|
6556
|
-
throw new Error("service_checker_missing");
|
|
6557
|
-
}
|
|
6558
|
-
|
|
6559
|
-
// src/react/canvas/editor/editor-nodes.ts
|
|
6560
7117
|
var RELATION_MAP_KEYS = [
|
|
6561
7118
|
"includes_for_buttons",
|
|
6562
7119
|
"excludes_for_buttons",
|
|
@@ -6607,14 +7164,51 @@ function cleanRelationMapsForDeleted(p, deleted) {
|
|
|
6607
7164
|
delete map[mapKey];
|
|
6608
7165
|
continue;
|
|
6609
7166
|
}
|
|
6610
|
-
const next = ((_a = map[mapKey]) != null ? _a : []).filter(
|
|
6611
|
-
(item) => !deleted.has(String(item))
|
|
6612
|
-
);
|
|
6613
|
-
if (next.length) map[mapKey] = next;
|
|
6614
|
-
else delete map[mapKey];
|
|
7167
|
+
const next = ((_a = map[mapKey]) != null ? _a : []).filter(
|
|
7168
|
+
(item) => !deleted.has(String(item))
|
|
7169
|
+
);
|
|
7170
|
+
if (next.length) map[mapKey] = next;
|
|
7171
|
+
else delete map[mapKey];
|
|
7172
|
+
}
|
|
7173
|
+
if (!Object.keys(map).length) delete p[key];
|
|
7174
|
+
}
|
|
7175
|
+
}
|
|
7176
|
+
function cleanOptionEffectsForDeleted(p, deleted) {
|
|
7177
|
+
var _a, _b;
|
|
7178
|
+
const map = p.option_effects_for_buttons;
|
|
7179
|
+
if (!map) return;
|
|
7180
|
+
for (const triggerId of Object.keys(map)) {
|
|
7181
|
+
if (deleted.has(String(triggerId))) {
|
|
7182
|
+
delete map[triggerId];
|
|
7183
|
+
continue;
|
|
7184
|
+
}
|
|
7185
|
+
const targets = map[triggerId];
|
|
7186
|
+
for (const targetFieldId of Object.keys(targets != null ? targets : {})) {
|
|
7187
|
+
if (deleted.has(String(targetFieldId))) {
|
|
7188
|
+
delete targets[targetFieldId];
|
|
7189
|
+
continue;
|
|
7190
|
+
}
|
|
7191
|
+
const effect = targets[targetFieldId];
|
|
7192
|
+
if (!effect) continue;
|
|
7193
|
+
if (effect.include) {
|
|
7194
|
+
effect.include = effect.include.filter(
|
|
7195
|
+
(optionId) => !deleted.has(String(optionId))
|
|
7196
|
+
);
|
|
7197
|
+
if (!effect.include.length) delete effect.include;
|
|
7198
|
+
}
|
|
7199
|
+
if (effect.exclude) {
|
|
7200
|
+
effect.exclude = effect.exclude.filter(
|
|
7201
|
+
(optionId) => !deleted.has(String(optionId))
|
|
7202
|
+
);
|
|
7203
|
+
if (!effect.exclude.length) delete effect.exclude;
|
|
7204
|
+
}
|
|
7205
|
+
if (effect.forceVisible !== true && !((_a = effect.include) == null ? void 0 : _a.length) && !((_b = effect.exclude) == null ? void 0 : _b.length)) {
|
|
7206
|
+
delete targets[targetFieldId];
|
|
7207
|
+
}
|
|
6615
7208
|
}
|
|
6616
|
-
if (!Object.keys(
|
|
7209
|
+
if (!Object.keys(targets != null ? targets : {}).length) delete map[triggerId];
|
|
6617
7210
|
}
|
|
7211
|
+
if (!Object.keys(map).length) delete p.option_effects_for_buttons;
|
|
6618
7212
|
}
|
|
6619
7213
|
function cleanOrderForTagsForDeleted(p, deleted) {
|
|
6620
7214
|
var _a, _b;
|
|
@@ -6651,28 +7245,37 @@ function applyDeleteCleanup(p, deleted) {
|
|
|
6651
7245
|
cleanTagRelationsForDeleted(p, deleted);
|
|
6652
7246
|
cleanFieldBindsForDeleted(p, deleted);
|
|
6653
7247
|
cleanRelationMapsForDeleted(p, deleted);
|
|
7248
|
+
cleanOptionEffectsForDeleted(p, deleted);
|
|
6654
7249
|
cleanOrderForTagsForDeleted(p, deleted);
|
|
6655
7250
|
cleanNoticesForDeleted(p, deleted);
|
|
6656
7251
|
}
|
|
7252
|
+
function collectOptionSubtreeIds(option) {
|
|
7253
|
+
var _a;
|
|
7254
|
+
return [
|
|
7255
|
+
String(option.id),
|
|
7256
|
+
...((_a = option.children) != null ? _a : []).flatMap((child) => collectOptionSubtreeIds(child))
|
|
7257
|
+
];
|
|
7258
|
+
}
|
|
6657
7259
|
function removeOptionInPlace(p, optionId) {
|
|
6658
7260
|
var _a;
|
|
6659
|
-
const
|
|
6660
|
-
if (!
|
|
6661
|
-
const
|
|
6662
|
-
|
|
6663
|
-
|
|
6664
|
-
|
|
6665
|
-
|
|
7261
|
+
const found = findMutableOption(p, optionId);
|
|
7262
|
+
if (!found) return [];
|
|
7263
|
+
const deleted = collectOptionSubtreeIds(found.option);
|
|
7264
|
+
found.siblings.splice(found.index, 1);
|
|
7265
|
+
if (found.parent && ((_a = found.parent.children) == null ? void 0 : _a.length) === 0) {
|
|
7266
|
+
delete found.parent.children;
|
|
7267
|
+
}
|
|
7268
|
+
return deleted;
|
|
6666
7269
|
}
|
|
6667
7270
|
function removeFieldInPlace(p, fieldId) {
|
|
6668
|
-
var _a, _b, _c, _d
|
|
7271
|
+
var _a, _b, _c, _d;
|
|
6669
7272
|
const field = ((_a = p.fields) != null ? _a : []).find((f) => f.id === fieldId);
|
|
6670
7273
|
if (!field) return [];
|
|
6671
|
-
const deleted = [fieldId, ...(
|
|
6672
|
-
const before = ((
|
|
6673
|
-
p.fields = ((
|
|
7274
|
+
const deleted = [fieldId, ...collectFieldOptionIds(field)];
|
|
7275
|
+
const before = ((_b = p.fields) != null ? _b : []).length;
|
|
7276
|
+
p.fields = ((_c = p.fields) != null ? _c : []).filter((f) => f.id !== fieldId);
|
|
6674
7277
|
clearFieldButtonReceiverMaps(p, fieldId);
|
|
6675
|
-
return ((
|
|
7278
|
+
return ((_d = p.fields) != null ? _d : []).length !== before ? deleted : [];
|
|
6676
7279
|
}
|
|
6677
7280
|
function removeTagInPlace(p, tagId) {
|
|
6678
7281
|
var _a, _b, _c;
|
|
@@ -6685,7 +7288,7 @@ function reLabel(ctx, id, nextLabel) {
|
|
|
6685
7288
|
ctx.exec({
|
|
6686
7289
|
name: "reLabel",
|
|
6687
7290
|
do: () => ctx.patchProps((p) => {
|
|
6688
|
-
var _a, _b, _c, _d, _e, _f
|
|
7291
|
+
var _a, _b, _c, _d, _e, _f;
|
|
6689
7292
|
if (ctx.isTagId(id)) {
|
|
6690
7293
|
const t = ((_a = p.filters) != null ? _a : []).find((x) => x.id === id);
|
|
6691
7294
|
if (!t) return;
|
|
@@ -6695,19 +7298,16 @@ function reLabel(ctx, id, nextLabel) {
|
|
|
6695
7298
|
return;
|
|
6696
7299
|
}
|
|
6697
7300
|
if (ctx.isOptionId(id)) {
|
|
6698
|
-
const
|
|
6699
|
-
if (!own) return;
|
|
6700
|
-
const f = ((_c = p.fields) != null ? _c : []).find((x) => x.id === own.fieldId);
|
|
6701
|
-
const o = (_d = f == null ? void 0 : f.options) == null ? void 0 : _d.find((x) => x.id === id);
|
|
7301
|
+
const o = (_c = findMutableOption(p, id)) == null ? void 0 : _c.option;
|
|
6702
7302
|
if (!o) return;
|
|
6703
|
-
if (((
|
|
7303
|
+
if (((_d = o.label) != null ? _d : "") === label) return;
|
|
6704
7304
|
o.label = label;
|
|
6705
7305
|
ctx.api.refreshGraph();
|
|
6706
7306
|
return;
|
|
6707
7307
|
}
|
|
6708
|
-
const fld = ((
|
|
7308
|
+
const fld = ((_e = p.fields) != null ? _e : []).find((x) => x.id === id);
|
|
6709
7309
|
if (!fld) return;
|
|
6710
|
-
if (((
|
|
7310
|
+
if (((_f = fld.label) != null ? _f : "") === label) return;
|
|
6711
7311
|
fld.label = label;
|
|
6712
7312
|
ctx.api.refreshGraph();
|
|
6713
7313
|
}),
|
|
@@ -6797,11 +7397,7 @@ function updateOption(ctx, optionId, patch) {
|
|
|
6797
7397
|
name: "updateOption",
|
|
6798
7398
|
do: () => ctx.patchProps((p) => {
|
|
6799
7399
|
var _a;
|
|
6800
|
-
const
|
|
6801
|
-
if (!owner) return;
|
|
6802
|
-
const f = ((_a = p.fields) != null ? _a : []).find((x) => x.id === owner.fieldId);
|
|
6803
|
-
if (!(f == null ? void 0 : f.options)) return;
|
|
6804
|
-
const o = f.options.find((x) => x.id === optionId);
|
|
7400
|
+
const o = (_a = findMutableOption(p, optionId)) == null ? void 0 : _a.option;
|
|
6805
7401
|
if (o) Object.assign(o, patch);
|
|
6806
7402
|
}),
|
|
6807
7403
|
undo: () => ctx.undo()
|
|
@@ -6814,9 +7410,9 @@ function removeOption(ctx, optionId) {
|
|
|
6814
7410
|
ctx.exec({
|
|
6815
7411
|
name: "removeOption",
|
|
6816
7412
|
do: () => ctx.patchProps((p) => {
|
|
6817
|
-
const
|
|
6818
|
-
if (!
|
|
6819
|
-
applyDeleteCleanup(p,
|
|
7413
|
+
const removedIds = removeOptionInPlace(p, optionId);
|
|
7414
|
+
if (!removedIds.length) return;
|
|
7415
|
+
applyDeleteCleanup(p, new Set(removedIds));
|
|
6820
7416
|
}),
|
|
6821
7417
|
undo: () => ctx.undo()
|
|
6822
7418
|
});
|
|
@@ -6827,7 +7423,7 @@ function editLabel(ctx, id, label) {
|
|
|
6827
7423
|
ctx.exec({
|
|
6828
7424
|
name: "editLabel",
|
|
6829
7425
|
do: () => ctx.patchProps((p) => {
|
|
6830
|
-
var _a, _b, _c
|
|
7426
|
+
var _a, _b, _c;
|
|
6831
7427
|
if (ctx.isTagId(id)) {
|
|
6832
7428
|
const t = ((_a = p.filters) != null ? _a : []).find((x) => x.id === id);
|
|
6833
7429
|
if (t) t.label = next;
|
|
@@ -6839,10 +7435,7 @@ function editLabel(ctx, id, label) {
|
|
|
6839
7435
|
return;
|
|
6840
7436
|
}
|
|
6841
7437
|
if (ctx.isOptionId(id)) {
|
|
6842
|
-
const
|
|
6843
|
-
if (!own) return;
|
|
6844
|
-
const f = ((_c = p.fields) != null ? _c : []).find((x) => x.id === own.fieldId);
|
|
6845
|
-
const o = (_d = f == null ? void 0 : f.options) == null ? void 0 : _d.find((x) => x.id === id);
|
|
7438
|
+
const o = (_c = findMutableOption(p, id)) == null ? void 0 : _c.option;
|
|
6846
7439
|
if (o) o.label = next;
|
|
6847
7440
|
return;
|
|
6848
7441
|
}
|
|
@@ -6867,7 +7460,7 @@ function setService(ctx, id, input) {
|
|
|
6867
7460
|
ctx.exec({
|
|
6868
7461
|
name: "setService",
|
|
6869
7462
|
do: () => ctx.patchProps((p) => {
|
|
6870
|
-
var _a, _b, _c, _d, _e
|
|
7463
|
+
var _a, _b, _c, _d, _e;
|
|
6871
7464
|
const hasSidKey = Object.prototype.hasOwnProperty.call(
|
|
6872
7465
|
input,
|
|
6873
7466
|
"service_id"
|
|
@@ -6885,12 +7478,9 @@ function setService(ctx, id, input) {
|
|
|
6885
7478
|
return;
|
|
6886
7479
|
}
|
|
6887
7480
|
if (ctx.isOptionId(id)) {
|
|
6888
|
-
const
|
|
6889
|
-
if (!own) return;
|
|
6890
|
-
const f2 = ((_b = p.fields) != null ? _b : []).find((x) => x.id === own.fieldId);
|
|
6891
|
-
const o = (_c = f2 == null ? void 0 : f2.options) == null ? void 0 : _c.find((x) => x.id === id);
|
|
7481
|
+
const o = (_b = findMutableOption(p, id)) == null ? void 0 : _b.option;
|
|
6892
7482
|
if (!o) return;
|
|
6893
|
-
const currentRole = (
|
|
7483
|
+
const currentRole = (_c = o.pricing_role) != null ? _c : "base";
|
|
6894
7484
|
const role = nextRole != null ? nextRole : currentRole;
|
|
6895
7485
|
if (role === "utility") {
|
|
6896
7486
|
if (hasSidKey && sid !== void 0) {
|
|
@@ -6911,7 +7501,7 @@ function setService(ctx, id, input) {
|
|
|
6911
7501
|
}
|
|
6912
7502
|
return;
|
|
6913
7503
|
}
|
|
6914
|
-
const f = ((
|
|
7504
|
+
const f = ((_d = p.fields) != null ? _d : []).find((x) => x.id === id);
|
|
6915
7505
|
if (!f) {
|
|
6916
7506
|
throw new Error(
|
|
6917
7507
|
'setService only supports tag ("t:*"), option ("o:*"), or field ("f:*") ids'
|
|
@@ -6922,7 +7512,7 @@ function setService(ctx, id, input) {
|
|
|
6922
7512
|
if (nextRole) {
|
|
6923
7513
|
f.pricing_role = nextRole;
|
|
6924
7514
|
}
|
|
6925
|
-
const effectiveRole = (
|
|
7515
|
+
const effectiveRole = (_e = f.pricing_role) != null ? _e : "base";
|
|
6926
7516
|
if (isOptionBased2) {
|
|
6927
7517
|
if (hasSidKey) {
|
|
6928
7518
|
ctx.api.emit("error", {
|
|
@@ -7034,13 +7624,15 @@ function updateField(ctx, id, patch) {
|
|
|
7034
7624
|
let prev;
|
|
7035
7625
|
let prevIncludesForButton;
|
|
7036
7626
|
let prevExcludesForButton;
|
|
7627
|
+
let prevOptionEffectsForButton;
|
|
7037
7628
|
ctx.exec({
|
|
7038
7629
|
name: "updateField",
|
|
7039
7630
|
do: () => ctx.patchProps((p) => {
|
|
7040
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
7631
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
7041
7632
|
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;
|
|
7042
7633
|
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;
|
|
7043
|
-
|
|
7634
|
+
prevOptionEffectsForButton = ((_g = p.option_effects_for_buttons) == null ? void 0 : _g[id]) ? cloneDeep3(p.option_effects_for_buttons[id]) : void 0;
|
|
7635
|
+
p.fields = ((_h = p.fields) != null ? _h : []).map((f) => {
|
|
7044
7636
|
if (f.id !== id) return f;
|
|
7045
7637
|
prev = cloneDeep3(f);
|
|
7046
7638
|
const nextField = { ...f, ...patch };
|
|
@@ -7051,7 +7643,7 @@ function updateField(ctx, id, patch) {
|
|
|
7051
7643
|
});
|
|
7052
7644
|
}),
|
|
7053
7645
|
undo: () => ctx.patchProps((p) => {
|
|
7054
|
-
var _a, _b, _c;
|
|
7646
|
+
var _a, _b, _c, _d;
|
|
7055
7647
|
p.fields = ((_a = p.fields) != null ? _a : []).map(
|
|
7056
7648
|
(f) => f.id === id && prev ? prev : f
|
|
7057
7649
|
);
|
|
@@ -7069,6 +7661,12 @@ function updateField(ctx, id, patch) {
|
|
|
7069
7661
|
[id]: [...prevExcludesForButton]
|
|
7070
7662
|
};
|
|
7071
7663
|
}
|
|
7664
|
+
if (prevOptionEffectsForButton) {
|
|
7665
|
+
p.option_effects_for_buttons = {
|
|
7666
|
+
...(_d = p.option_effects_for_buttons) != null ? _d : {},
|
|
7667
|
+
[id]: cloneDeep3(prevOptionEffectsForButton)
|
|
7668
|
+
};
|
|
7669
|
+
}
|
|
7072
7670
|
})
|
|
7073
7671
|
});
|
|
7074
7672
|
}
|
|
@@ -7115,9 +7713,9 @@ function remove(ctx, id) {
|
|
|
7115
7713
|
ctx.exec({
|
|
7116
7714
|
name: "removeOption",
|
|
7117
7715
|
do: () => ctx.patchProps((p) => {
|
|
7118
|
-
const
|
|
7119
|
-
if (!
|
|
7120
|
-
applyDeleteCleanup(p,
|
|
7716
|
+
const removedIds = removeOptionInPlace(p, key);
|
|
7717
|
+
if (!removedIds.length) return;
|
|
7718
|
+
applyDeleteCleanup(p, new Set(removedIds));
|
|
7121
7719
|
}),
|
|
7122
7720
|
undo: () => ctx.undo()
|
|
7123
7721
|
});
|
|
@@ -7134,10 +7732,7 @@ function removeMany(ctx, ids) {
|
|
|
7134
7732
|
const existingFieldIds = new Set(((_a = p.fields) != null ? _a : []).map((f) => String(f.id)));
|
|
7135
7733
|
const existingTagIds = new Set(((_b = p.filters) != null ? _b : []).map((t) => String(t.id)));
|
|
7136
7734
|
const existingOptionIds = new Set(
|
|
7137
|
-
((_c = p.fields) != null ? _c : []).flatMap((f) =>
|
|
7138
|
-
var _a2;
|
|
7139
|
-
return ((_a2 = f.options) != null ? _a2 : []).map((o) => String(o.id));
|
|
7140
|
-
})
|
|
7735
|
+
((_c = p.fields) != null ? _c : []).flatMap((f) => collectFieldOptionIds(f))
|
|
7141
7736
|
);
|
|
7142
7737
|
const fieldIds = ordered.filter((id) => ctx.isFieldId(id) && existingFieldIds.has(id));
|
|
7143
7738
|
const fieldIdSet = new Set(fieldIds);
|
|
@@ -7150,7 +7745,9 @@ function removeMany(ctx, ids) {
|
|
|
7150
7745
|
});
|
|
7151
7746
|
const deleted = /* @__PURE__ */ new Set();
|
|
7152
7747
|
for (const optionId of optionIds) {
|
|
7153
|
-
|
|
7748
|
+
for (const removedId of removeOptionInPlace(p, optionId)) {
|
|
7749
|
+
deleted.add(removedId);
|
|
7750
|
+
}
|
|
7154
7751
|
}
|
|
7155
7752
|
for (const fieldId of fieldIds) {
|
|
7156
7753
|
const removedIds = removeFieldInPlace(p, fieldId);
|
|
@@ -7165,7 +7762,7 @@ function removeMany(ctx, ids) {
|
|
|
7165
7762
|
});
|
|
7166
7763
|
}
|
|
7167
7764
|
function getNode(ctx, id) {
|
|
7168
|
-
var _a, _b, _c
|
|
7765
|
+
var _a, _b, _c;
|
|
7169
7766
|
const props = ctx.getProps();
|
|
7170
7767
|
if (ctx.isTagId(id)) {
|
|
7171
7768
|
const t = ((_a = props.filters) != null ? _a : []).find((x) => x.id === id);
|
|
@@ -7182,8 +7779,7 @@ function getNode(ctx, id) {
|
|
|
7182
7779
|
}
|
|
7183
7780
|
if (ctx.isOptionId(id)) {
|
|
7184
7781
|
const own = ownerOfOption(props, id);
|
|
7185
|
-
const
|
|
7186
|
-
const o = (_d = f == null ? void 0 : f.options) == null ? void 0 : _d.find((x) => x.id === id);
|
|
7782
|
+
const o = (_c = findMutableOption(props, id)) == null ? void 0 : _c.option;
|
|
7187
7783
|
return {
|
|
7188
7784
|
kind: "option",
|
|
7189
7785
|
data: o,
|
|
@@ -7720,7 +8316,7 @@ function connect(ctx, kind, fromId, toId2) {
|
|
|
7720
8316
|
ctx.exec({
|
|
7721
8317
|
name: `connect:${kind}`,
|
|
7722
8318
|
do: () => ctx.patchProps((p) => {
|
|
7723
|
-
var _a, _b, _c, _d, _e, _f, _g
|
|
8319
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
7724
8320
|
if (kind === "bind") {
|
|
7725
8321
|
if (ctx.isTagId(fromId) && ctx.isTagId(toId2)) {
|
|
7726
8322
|
if (wouldCreateTagCycle(ctx, p, fromId, toId2)) {
|
|
@@ -7800,12 +8396,10 @@ function connect(ctx, kind, fromId, toId2) {
|
|
|
7800
8396
|
return;
|
|
7801
8397
|
}
|
|
7802
8398
|
if (toId2.startsWith("o:")) {
|
|
7803
|
-
|
|
7804
|
-
|
|
7805
|
-
|
|
7806
|
-
|
|
7807
|
-
return;
|
|
7808
|
-
}
|
|
8399
|
+
const o = (_g = findMutableOption(p, toId2)) == null ? void 0 : _g.option;
|
|
8400
|
+
if (o) {
|
|
8401
|
+
o.service_id = fromId;
|
|
8402
|
+
return;
|
|
7809
8403
|
}
|
|
7810
8404
|
return;
|
|
7811
8405
|
}
|
|
@@ -7822,7 +8416,7 @@ function disconnect(ctx, kind, fromId, toId2) {
|
|
|
7822
8416
|
ctx.exec({
|
|
7823
8417
|
name: `disconnect:${kind}`,
|
|
7824
8418
|
do: () => ctx.patchProps((p) => {
|
|
7825
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i
|
|
8419
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
7826
8420
|
if (kind === "bind") {
|
|
7827
8421
|
if (ctx.isTagId(fromId) && ctx.isTagId(toId2)) {
|
|
7828
8422
|
const child = ((_a = p.filters) != null ? _a : []).find(
|
|
@@ -7898,12 +8492,10 @@ function disconnect(ctx, kind, fromId, toId2) {
|
|
|
7898
8492
|
return;
|
|
7899
8493
|
}
|
|
7900
8494
|
if (toId2.startsWith("o:")) {
|
|
7901
|
-
|
|
7902
|
-
|
|
7903
|
-
|
|
7904
|
-
|
|
7905
|
-
return;
|
|
7906
|
-
}
|
|
8495
|
+
const o = (_i = findMutableOption(p, toId2)) == null ? void 0 : _i.option;
|
|
8496
|
+
if (o) {
|
|
8497
|
+
delete o.service_id;
|
|
8498
|
+
return;
|
|
7907
8499
|
}
|
|
7908
8500
|
return;
|
|
7909
8501
|
}
|
|
@@ -7926,6 +8518,250 @@ function addMappedField(p, mapKey, fromId, toId2) {
|
|
|
7926
8518
|
p[mapKey] = maps;
|
|
7927
8519
|
}
|
|
7928
8520
|
|
|
8521
|
+
// src/react/canvas/editor/editor-option-effects.ts
|
|
8522
|
+
function assertCanonicalId(id, label) {
|
|
8523
|
+
if (!id || id.includes("::") || id.includes("/")) {
|
|
8524
|
+
throw new Error(
|
|
8525
|
+
`${label}: expected a raw field or option id, not a composite/path id`
|
|
8526
|
+
);
|
|
8527
|
+
}
|
|
8528
|
+
}
|
|
8529
|
+
function assertTrigger(ctx, triggerId) {
|
|
8530
|
+
assertCanonicalId(triggerId, "option effect trigger");
|
|
8531
|
+
const trigger = ctx.getNode(triggerId);
|
|
8532
|
+
if (trigger.kind === "option" && trigger.data) return;
|
|
8533
|
+
if (trigger.kind === "field" && trigger.data && isActualButtonField(trigger.data)) {
|
|
8534
|
+
return;
|
|
8535
|
+
}
|
|
8536
|
+
throw new Error(
|
|
8537
|
+
"option effect trigger must be an option id or button field id"
|
|
8538
|
+
);
|
|
8539
|
+
}
|
|
8540
|
+
function assertTargetField(props, targetFieldId) {
|
|
8541
|
+
var _a;
|
|
8542
|
+
assertCanonicalId(targetFieldId, "option effect target");
|
|
8543
|
+
const field = ((_a = props.fields) != null ? _a : []).find((item) => item.id === targetFieldId);
|
|
8544
|
+
if (!field) {
|
|
8545
|
+
throw new Error(`option effect target field not found: ${targetFieldId}`);
|
|
8546
|
+
}
|
|
8547
|
+
return field;
|
|
8548
|
+
}
|
|
8549
|
+
function dedupe2(values) {
|
|
8550
|
+
if (!values) return void 0;
|
|
8551
|
+
const out = [];
|
|
8552
|
+
for (const value of values) {
|
|
8553
|
+
const id = String(value);
|
|
8554
|
+
if (!id || out.includes(id)) continue;
|
|
8555
|
+
out.push(id);
|
|
8556
|
+
}
|
|
8557
|
+
return out.length ? out : void 0;
|
|
8558
|
+
}
|
|
8559
|
+
function assertTargetOptions(props, targetFieldId, ids, kind) {
|
|
8560
|
+
if (!(ids == null ? void 0 : ids.length)) return;
|
|
8561
|
+
const field = assertTargetField(props, targetFieldId);
|
|
8562
|
+
const valid = fieldOptionIdSet(field);
|
|
8563
|
+
for (const id of ids) {
|
|
8564
|
+
assertCanonicalId(String(id), `option effect ${kind} option`);
|
|
8565
|
+
if (!valid.has(String(id))) {
|
|
8566
|
+
throw new Error(
|
|
8567
|
+
`option effect ${kind} option not found under ${targetFieldId}: ${String(id)}`
|
|
8568
|
+
);
|
|
8569
|
+
}
|
|
8570
|
+
}
|
|
8571
|
+
}
|
|
8572
|
+
function normalizeEffect(effect) {
|
|
8573
|
+
var _a;
|
|
8574
|
+
if (!effect) return void 0;
|
|
8575
|
+
const exclude2 = dedupe2(effect.exclude);
|
|
8576
|
+
const excluded = new Set(exclude2 != null ? exclude2 : []);
|
|
8577
|
+
const include2 = (_a = dedupe2(effect.include)) == null ? void 0 : _a.filter((id) => !excluded.has(id));
|
|
8578
|
+
const out = {};
|
|
8579
|
+
if (effect.forceVisible === true) out.forceVisible = true;
|
|
8580
|
+
if (include2 == null ? void 0 : include2.length) out.include = include2;
|
|
8581
|
+
if (exclude2 == null ? void 0 : exclude2.length) out.exclude = exclude2;
|
|
8582
|
+
return Object.keys(out).length ? out : void 0;
|
|
8583
|
+
}
|
|
8584
|
+
function ensureTargetMap(props, triggerId) {
|
|
8585
|
+
var _a, _b, _c;
|
|
8586
|
+
(_a = props.option_effects_for_buttons) != null ? _a : props.option_effects_for_buttons = {};
|
|
8587
|
+
(_c = (_b = props.option_effects_for_buttons)[triggerId]) != null ? _c : _b[triggerId] = {};
|
|
8588
|
+
return props.option_effects_for_buttons[triggerId];
|
|
8589
|
+
}
|
|
8590
|
+
function pruneEffectMap(props, triggerId) {
|
|
8591
|
+
const map = props.option_effects_for_buttons;
|
|
8592
|
+
if (!map) return;
|
|
8593
|
+
const keys = triggerId ? [triggerId] : Object.keys(map);
|
|
8594
|
+
for (const key of keys) {
|
|
8595
|
+
const targets = map[key];
|
|
8596
|
+
if (!targets || Object.keys(targets).length === 0) delete map[key];
|
|
8597
|
+
}
|
|
8598
|
+
if (Object.keys(map).length === 0) delete props.option_effects_for_buttons;
|
|
8599
|
+
}
|
|
8600
|
+
function validateEffect(ctx, props, triggerId, targetFieldId, effect) {
|
|
8601
|
+
assertTrigger(ctx, triggerId);
|
|
8602
|
+
assertTargetField(props, targetFieldId);
|
|
8603
|
+
assertTargetOptions(props, targetFieldId, effect == null ? void 0 : effect.include, "include");
|
|
8604
|
+
assertTargetOptions(props, targetFieldId, effect == null ? void 0 : effect.exclude, "exclude");
|
|
8605
|
+
return normalizeEffect(effect);
|
|
8606
|
+
}
|
|
8607
|
+
function setOptionEffect(ctx, triggerId, targetFieldId, effect) {
|
|
8608
|
+
ctx.exec({
|
|
8609
|
+
name: "setOptionEffect",
|
|
8610
|
+
do: () => ctx.patchProps((props) => {
|
|
8611
|
+
var _a;
|
|
8612
|
+
const normalized = validateEffect(
|
|
8613
|
+
ctx,
|
|
8614
|
+
props,
|
|
8615
|
+
triggerId,
|
|
8616
|
+
targetFieldId,
|
|
8617
|
+
effect
|
|
8618
|
+
);
|
|
8619
|
+
if (!normalized) {
|
|
8620
|
+
const map = (_a = props.option_effects_for_buttons) == null ? void 0 : _a[triggerId];
|
|
8621
|
+
if (map) delete map[targetFieldId];
|
|
8622
|
+
pruneEffectMap(props, triggerId);
|
|
8623
|
+
return;
|
|
8624
|
+
}
|
|
8625
|
+
ensureTargetMap(props, triggerId)[targetFieldId] = normalized;
|
|
8626
|
+
}),
|
|
8627
|
+
undo: () => ctx.undo()
|
|
8628
|
+
});
|
|
8629
|
+
}
|
|
8630
|
+
function patchOptionEffect(ctx, triggerId, targetFieldId, patch) {
|
|
8631
|
+
ctx.exec({
|
|
8632
|
+
name: "patchOptionEffect",
|
|
8633
|
+
do: () => ctx.patchProps((props) => {
|
|
8634
|
+
var _a, _b, _c, _d;
|
|
8635
|
+
const current = (_c = (_b = (_a = props.option_effects_for_buttons) == null ? void 0 : _a[triggerId]) == null ? void 0 : _b[targetFieldId]) != null ? _c : {};
|
|
8636
|
+
const merged = {
|
|
8637
|
+
...current,
|
|
8638
|
+
...patch
|
|
8639
|
+
};
|
|
8640
|
+
const normalized = validateEffect(
|
|
8641
|
+
ctx,
|
|
8642
|
+
props,
|
|
8643
|
+
triggerId,
|
|
8644
|
+
targetFieldId,
|
|
8645
|
+
merged
|
|
8646
|
+
);
|
|
8647
|
+
if (!normalized) {
|
|
8648
|
+
const map = (_d = props.option_effects_for_buttons) == null ? void 0 : _d[triggerId];
|
|
8649
|
+
if (map) delete map[targetFieldId];
|
|
8650
|
+
pruneEffectMap(props, triggerId);
|
|
8651
|
+
return;
|
|
8652
|
+
}
|
|
8653
|
+
ensureTargetMap(props, triggerId)[targetFieldId] = normalized;
|
|
8654
|
+
}),
|
|
8655
|
+
undo: () => ctx.undo()
|
|
8656
|
+
});
|
|
8657
|
+
}
|
|
8658
|
+
function clearOptionEffect(ctx, triggerId, targetFieldId) {
|
|
8659
|
+
ctx.exec({
|
|
8660
|
+
name: "clearOptionEffect",
|
|
8661
|
+
do: () => ctx.patchProps((props) => {
|
|
8662
|
+
var _a;
|
|
8663
|
+
const map = (_a = props.option_effects_for_buttons) == null ? void 0 : _a[triggerId];
|
|
8664
|
+
if (!map) return;
|
|
8665
|
+
delete map[targetFieldId];
|
|
8666
|
+
pruneEffectMap(props, triggerId);
|
|
8667
|
+
}),
|
|
8668
|
+
undo: () => ctx.undo()
|
|
8669
|
+
});
|
|
8670
|
+
}
|
|
8671
|
+
function clearOptionEffectsForTrigger(ctx, triggerId) {
|
|
8672
|
+
ctx.exec({
|
|
8673
|
+
name: "clearOptionEffectsForTrigger",
|
|
8674
|
+
do: () => ctx.patchProps((props) => {
|
|
8675
|
+
if (!props.option_effects_for_buttons) return;
|
|
8676
|
+
delete props.option_effects_for_buttons[triggerId];
|
|
8677
|
+
pruneEffectMap(props);
|
|
8678
|
+
}),
|
|
8679
|
+
undo: () => ctx.undo()
|
|
8680
|
+
});
|
|
8681
|
+
}
|
|
8682
|
+
function clearOptionEffectsForTarget(ctx, targetFieldId) {
|
|
8683
|
+
ctx.exec({
|
|
8684
|
+
name: "clearOptionEffectsForTarget",
|
|
8685
|
+
do: () => ctx.patchProps((props) => {
|
|
8686
|
+
var _a;
|
|
8687
|
+
const map = props.option_effects_for_buttons;
|
|
8688
|
+
if (!map) return;
|
|
8689
|
+
for (const triggerId of Object.keys(map)) {
|
|
8690
|
+
(_a = map[triggerId]) == null ? true : delete _a[targetFieldId];
|
|
8691
|
+
}
|
|
8692
|
+
pruneEffectMap(props);
|
|
8693
|
+
}),
|
|
8694
|
+
undo: () => ctx.undo()
|
|
8695
|
+
});
|
|
8696
|
+
}
|
|
8697
|
+
function addOptionEffectOptions(ctx, triggerId, targetFieldId, kind, optionIds) {
|
|
8698
|
+
var _a;
|
|
8699
|
+
const additions = (_a = dedupe2(optionIds)) != null ? _a : [];
|
|
8700
|
+
if (!additions.length) return;
|
|
8701
|
+
ctx.exec({
|
|
8702
|
+
name: "addOptionEffectOptions",
|
|
8703
|
+
do: () => ctx.patchProps((props) => {
|
|
8704
|
+
var _a2, _b, _c, _d;
|
|
8705
|
+
const current = (_c = (_b = (_a2 = props.option_effects_for_buttons) == null ? void 0 : _a2[triggerId]) == null ? void 0 : _b[targetFieldId]) != null ? _c : {};
|
|
8706
|
+
const nextValues = dedupe2([
|
|
8707
|
+
...(_d = current[kind]) != null ? _d : [],
|
|
8708
|
+
...additions
|
|
8709
|
+
]);
|
|
8710
|
+
const normalized = validateEffect(
|
|
8711
|
+
ctx,
|
|
8712
|
+
props,
|
|
8713
|
+
triggerId,
|
|
8714
|
+
targetFieldId,
|
|
8715
|
+
{
|
|
8716
|
+
...current,
|
|
8717
|
+
[kind]: nextValues
|
|
8718
|
+
}
|
|
8719
|
+
);
|
|
8720
|
+
if (!normalized) return;
|
|
8721
|
+
ensureTargetMap(props, triggerId)[targetFieldId] = normalized;
|
|
8722
|
+
}),
|
|
8723
|
+
undo: () => ctx.undo()
|
|
8724
|
+
});
|
|
8725
|
+
}
|
|
8726
|
+
function removeOptionEffectOptions(ctx, triggerId, targetFieldId, kind, optionIds) {
|
|
8727
|
+
var _a;
|
|
8728
|
+
const removals = new Set((_a = dedupe2(optionIds)) != null ? _a : []);
|
|
8729
|
+
if (!removals.size) return;
|
|
8730
|
+
ctx.exec({
|
|
8731
|
+
name: "removeOptionEffectOptions",
|
|
8732
|
+
do: () => ctx.patchProps((props) => {
|
|
8733
|
+
var _a2, _b, _c, _d, _e;
|
|
8734
|
+
const current = (_b = (_a2 = props.option_effects_for_buttons) == null ? void 0 : _a2[triggerId]) == null ? void 0 : _b[targetFieldId];
|
|
8735
|
+
if (!current) return;
|
|
8736
|
+
const next = {
|
|
8737
|
+
...current,
|
|
8738
|
+
[kind]: ((_c = current[kind]) != null ? _c : []).filter(
|
|
8739
|
+
(optionId) => !removals.has(optionId)
|
|
8740
|
+
)
|
|
8741
|
+
};
|
|
8742
|
+
const normalized = validateEffect(
|
|
8743
|
+
ctx,
|
|
8744
|
+
props,
|
|
8745
|
+
triggerId,
|
|
8746
|
+
targetFieldId,
|
|
8747
|
+
next
|
|
8748
|
+
);
|
|
8749
|
+
if (!normalized) {
|
|
8750
|
+
(_e = (_d = props.option_effects_for_buttons) == null ? void 0 : _d[triggerId]) == null ? true : delete _e[targetFieldId];
|
|
8751
|
+
pruneEffectMap(props, triggerId);
|
|
8752
|
+
return;
|
|
8753
|
+
}
|
|
8754
|
+
ensureTargetMap(props, triggerId)[targetFieldId] = normalized;
|
|
8755
|
+
}),
|
|
8756
|
+
undo: () => ctx.undo()
|
|
8757
|
+
});
|
|
8758
|
+
}
|
|
8759
|
+
function setOptionEffectForceVisible(ctx, triggerId, targetFieldId, forceVisible) {
|
|
8760
|
+
patchOptionEffect(ctx, triggerId, targetFieldId, {
|
|
8761
|
+
forceVisible: forceVisible === true ? true : void 0
|
|
8762
|
+
});
|
|
8763
|
+
}
|
|
8764
|
+
|
|
7929
8765
|
// src/react/canvas/editor/editor-service-filter.ts
|
|
7930
8766
|
function filterServicesForVisibleGroup2(ctx, candidates, input) {
|
|
7931
8767
|
const coreInput = {
|
|
@@ -8512,7 +9348,7 @@ var Editor = class {
|
|
|
8512
9348
|
if (!ordered.length) return;
|
|
8513
9349
|
this.transact("clearServiceMany", () => {
|
|
8514
9350
|
this.patchProps((p) => {
|
|
8515
|
-
var _a, _b
|
|
9351
|
+
var _a, _b;
|
|
8516
9352
|
for (const id of ordered) {
|
|
8517
9353
|
if (this.isTagId(id)) {
|
|
8518
9354
|
const t = ((_a = p.filters) != null ? _a : []).find((x) => x.id === id);
|
|
@@ -8525,10 +9361,8 @@ var Editor = class {
|
|
|
8525
9361
|
continue;
|
|
8526
9362
|
}
|
|
8527
9363
|
if (this.isOptionId(id)) {
|
|
8528
|
-
const
|
|
8529
|
-
|
|
8530
|
-
const f = ((_c = p.fields) != null ? _c : []).find((x) => x.id === own.fieldId);
|
|
8531
|
-
const o = (_d = f == null ? void 0 : f.options) == null ? void 0 : _d.find((x) => x.id === id);
|
|
9364
|
+
const found = findMutableOption(p, id);
|
|
9365
|
+
const o = found == null ? void 0 : found.option;
|
|
8532
9366
|
if (o && "service_id" in o) delete o.service_id;
|
|
8533
9367
|
}
|
|
8534
9368
|
}
|
|
@@ -8577,7 +9411,7 @@ var Editor = class {
|
|
|
8577
9411
|
if (!selected.size) return;
|
|
8578
9412
|
this.transact("clearRelationsMany", () => {
|
|
8579
9413
|
this.patchProps((p) => {
|
|
8580
|
-
var _a, _b, _c;
|
|
9414
|
+
var _a, _b, _c, _d, _e;
|
|
8581
9415
|
const clearOwned = mode === "owned" || mode === "both";
|
|
8582
9416
|
const clearIncoming = mode === "incoming" || mode === "both";
|
|
8583
9417
|
for (const t of (_a = p.filters) != null ? _a : []) {
|
|
@@ -8617,6 +9451,44 @@ var Editor = class {
|
|
|
8617
9451
|
}
|
|
8618
9452
|
if (!Object.keys(map).length) delete p[k];
|
|
8619
9453
|
}
|
|
9454
|
+
const effectMap = p.option_effects_for_buttons;
|
|
9455
|
+
if (effectMap) {
|
|
9456
|
+
for (const triggerId of Object.keys(effectMap)) {
|
|
9457
|
+
if (clearOwned && selected.has(String(triggerId))) {
|
|
9458
|
+
delete effectMap[triggerId];
|
|
9459
|
+
continue;
|
|
9460
|
+
}
|
|
9461
|
+
const targets = effectMap[triggerId];
|
|
9462
|
+
if (!targets || !clearIncoming) continue;
|
|
9463
|
+
for (const targetFieldId of Object.keys(targets)) {
|
|
9464
|
+
if (selected.has(String(targetFieldId))) {
|
|
9465
|
+
delete targets[targetFieldId];
|
|
9466
|
+
continue;
|
|
9467
|
+
}
|
|
9468
|
+
const effect = targets[targetFieldId];
|
|
9469
|
+
if (!effect) continue;
|
|
9470
|
+
if (effect.include) {
|
|
9471
|
+
effect.include = effect.include.filter(
|
|
9472
|
+
(optionId) => !selected.has(String(optionId))
|
|
9473
|
+
);
|
|
9474
|
+
if (!effect.include.length) delete effect.include;
|
|
9475
|
+
}
|
|
9476
|
+
if (effect.exclude) {
|
|
9477
|
+
effect.exclude = effect.exclude.filter(
|
|
9478
|
+
(optionId) => !selected.has(String(optionId))
|
|
9479
|
+
);
|
|
9480
|
+
if (!effect.exclude.length) delete effect.exclude;
|
|
9481
|
+
}
|
|
9482
|
+
if (effect.forceVisible !== true && !((_d = effect.include) == null ? void 0 : _d.length) && !((_e = effect.exclude) == null ? void 0 : _e.length)) {
|
|
9483
|
+
delete targets[targetFieldId];
|
|
9484
|
+
}
|
|
9485
|
+
}
|
|
9486
|
+
if (!Object.keys(targets).length) delete effectMap[triggerId];
|
|
9487
|
+
}
|
|
9488
|
+
if (!Object.keys(effectMap).length) {
|
|
9489
|
+
delete p.option_effects_for_buttons;
|
|
9490
|
+
}
|
|
9491
|
+
}
|
|
8620
9492
|
});
|
|
8621
9493
|
});
|
|
8622
9494
|
}
|
|
@@ -8628,7 +9500,7 @@ var Editor = class {
|
|
|
8628
9500
|
const suffix = (_b = input.suffix) != null ? _b : "";
|
|
8629
9501
|
this.transact("renameLabelsMany", () => {
|
|
8630
9502
|
this.patchProps((p) => {
|
|
8631
|
-
var _a2, _b2, _c, _d, _e, _f
|
|
9503
|
+
var _a2, _b2, _c, _d, _e, _f;
|
|
8632
9504
|
for (const id of ordered) {
|
|
8633
9505
|
if (this.isTagId(id)) {
|
|
8634
9506
|
const t = ((_a2 = p.filters) != null ? _a2 : []).find((x) => x.id === id);
|
|
@@ -8641,11 +9513,8 @@ var Editor = class {
|
|
|
8641
9513
|
continue;
|
|
8642
9514
|
}
|
|
8643
9515
|
if (this.isOptionId(id)) {
|
|
8644
|
-
const
|
|
8645
|
-
if (
|
|
8646
|
-
const f = ((_e = p.fields) != null ? _e : []).find((x) => x.id === own.fieldId);
|
|
8647
|
-
const o = (_f = f == null ? void 0 : f.options) == null ? void 0 : _f.find((x) => x.id === id);
|
|
8648
|
-
if (o) o.label = `${prefix}${(_g = o.label) != null ? _g : ""}${suffix}`.trim();
|
|
9516
|
+
const o = (_e = findMutableOption(p, id)) == null ? void 0 : _e.option;
|
|
9517
|
+
if (o) o.label = `${prefix}${(_f = o.label) != null ? _f : ""}${suffix}`.trim();
|
|
8649
9518
|
}
|
|
8650
9519
|
}
|
|
8651
9520
|
});
|
|
@@ -8798,6 +9667,57 @@ var Editor = class {
|
|
|
8798
9667
|
exclude(receiverId, idOrIds) {
|
|
8799
9668
|
return exclude(this.moduleCtx(), receiverId, idOrIds);
|
|
8800
9669
|
}
|
|
9670
|
+
setOptionEffect(triggerId, targetFieldId, effect) {
|
|
9671
|
+
return setOptionEffect(
|
|
9672
|
+
this.moduleCtx(),
|
|
9673
|
+
triggerId,
|
|
9674
|
+
targetFieldId,
|
|
9675
|
+
effect
|
|
9676
|
+
);
|
|
9677
|
+
}
|
|
9678
|
+
patchOptionEffect(triggerId, targetFieldId, patch) {
|
|
9679
|
+
return patchOptionEffect(
|
|
9680
|
+
this.moduleCtx(),
|
|
9681
|
+
triggerId,
|
|
9682
|
+
targetFieldId,
|
|
9683
|
+
patch
|
|
9684
|
+
);
|
|
9685
|
+
}
|
|
9686
|
+
clearOptionEffect(triggerId, targetFieldId) {
|
|
9687
|
+
return clearOptionEffect(this.moduleCtx(), triggerId, targetFieldId);
|
|
9688
|
+
}
|
|
9689
|
+
clearOptionEffectsForTrigger(triggerId) {
|
|
9690
|
+
return clearOptionEffectsForTrigger(this.moduleCtx(), triggerId);
|
|
9691
|
+
}
|
|
9692
|
+
clearOptionEffectsForTarget(targetFieldId) {
|
|
9693
|
+
return clearOptionEffectsForTarget(this.moduleCtx(), targetFieldId);
|
|
9694
|
+
}
|
|
9695
|
+
addOptionEffectOptions(triggerId, targetFieldId, kind, optionIds) {
|
|
9696
|
+
return addOptionEffectOptions(
|
|
9697
|
+
this.moduleCtx(),
|
|
9698
|
+
triggerId,
|
|
9699
|
+
targetFieldId,
|
|
9700
|
+
kind,
|
|
9701
|
+
optionIds
|
|
9702
|
+
);
|
|
9703
|
+
}
|
|
9704
|
+
removeOptionEffectOptions(triggerId, targetFieldId, kind, optionIds) {
|
|
9705
|
+
return removeOptionEffectOptions(
|
|
9706
|
+
this.moduleCtx(),
|
|
9707
|
+
triggerId,
|
|
9708
|
+
targetFieldId,
|
|
9709
|
+
kind,
|
|
9710
|
+
optionIds
|
|
9711
|
+
);
|
|
9712
|
+
}
|
|
9713
|
+
setOptionEffectForceVisible(triggerId, targetFieldId, forceVisible) {
|
|
9714
|
+
return setOptionEffectForceVisible(
|
|
9715
|
+
this.moduleCtx(),
|
|
9716
|
+
triggerId,
|
|
9717
|
+
targetFieldId,
|
|
9718
|
+
forceVisible
|
|
9719
|
+
);
|
|
9720
|
+
}
|
|
8801
9721
|
connect(kind, fromId, toId2) {
|
|
8802
9722
|
return connect(this.moduleCtx(), kind, fromId, toId2);
|
|
8803
9723
|
}
|
|
@@ -9166,11 +10086,10 @@ var Selection = class {
|
|
|
9166
10086
|
* What counts as a "button selection" (trigger key):
|
|
9167
10087
|
* - field key where the field has button === true (e.g. "f:dripfeed")
|
|
9168
10088
|
* - option key (e.g. "o:fast")
|
|
9169
|
-
* - composite key "fieldId::optionId" (e.g. "f:speed::o:fast")
|
|
9170
10089
|
*
|
|
9171
10090
|
* Grouping:
|
|
9172
10091
|
* - button-field trigger groups under its own fieldId
|
|
9173
|
-
* - option
|
|
10092
|
+
* - option trigger groups under the option's owning fieldId (from nodeMap)
|
|
9174
10093
|
*
|
|
9175
10094
|
* Deterministic:
|
|
9176
10095
|
* - preserves selection insertion order
|
|
@@ -9187,15 +10106,6 @@ var Selection = class {
|
|
|
9187
10106
|
};
|
|
9188
10107
|
for (const key of this.set) {
|
|
9189
10108
|
if (!key) continue;
|
|
9190
|
-
const idx = key.indexOf("::");
|
|
9191
|
-
if (idx !== -1) {
|
|
9192
|
-
const optionId = key.slice(idx + 2);
|
|
9193
|
-
const optRef = nodeMap.get(optionId);
|
|
9194
|
-
if ((optRef == null ? void 0 : optRef.kind) === "option" && typeof optRef.fieldId === "string") {
|
|
9195
|
-
push(optRef.fieldId, key);
|
|
9196
|
-
}
|
|
9197
|
-
continue;
|
|
9198
|
-
}
|
|
9199
10109
|
const ref = nodeMap.get(key);
|
|
9200
10110
|
if (!ref) continue;
|
|
9201
10111
|
if (ref.kind === "option" && typeof ref.fieldId === "string") {
|
|
@@ -9216,7 +10126,6 @@ var Selection = class {
|
|
|
9216
10126
|
* Returns only selection keys that are valid "trigger buttons":
|
|
9217
10127
|
* - field keys where field.button === true
|
|
9218
10128
|
* - option keys
|
|
9219
|
-
* - composite keys "fieldId::optionId" (validated by optionId)
|
|
9220
10129
|
* Excludes tags and non-button fields.
|
|
9221
10130
|
*/
|
|
9222
10131
|
selectedButtons() {
|
|
@@ -9232,13 +10141,6 @@ var Selection = class {
|
|
|
9232
10141
|
};
|
|
9233
10142
|
for (const key of this.set) {
|
|
9234
10143
|
if (!key) continue;
|
|
9235
|
-
const idx = key.indexOf("::");
|
|
9236
|
-
if (idx !== -1) {
|
|
9237
|
-
const optionId = key.slice(idx + 2);
|
|
9238
|
-
const optRef = nodeMap.get(optionId);
|
|
9239
|
-
if ((optRef == null ? void 0 : optRef.kind) === "option") push(key);
|
|
9240
|
-
continue;
|
|
9241
|
-
}
|
|
9242
10144
|
const ref = nodeMap.get(key);
|
|
9243
10145
|
if (!ref) continue;
|
|
9244
10146
|
if (ref.kind === "option") {
|
|
@@ -9277,17 +10179,7 @@ var Selection = class {
|
|
|
9277
10179
|
const direct = fields.find((x) => x.id === id);
|
|
9278
10180
|
if (direct) return direct;
|
|
9279
10181
|
if (this.builder.isOptionId(id)) {
|
|
9280
|
-
return fields
|
|
9281
|
-
(x) => {
|
|
9282
|
-
var _a2;
|
|
9283
|
-
return ((_a2 = x.options) != null ? _a2 : []).some((o) => o.id === id);
|
|
9284
|
-
}
|
|
9285
|
-
);
|
|
9286
|
-
}
|
|
9287
|
-
if (id.includes("::")) {
|
|
9288
|
-
const [fieldId] = id.split("::");
|
|
9289
|
-
if (!fieldId) return void 0;
|
|
9290
|
-
return fields.find((x) => x.id === fieldId);
|
|
10182
|
+
return findOptionOwnerField(fields, id);
|
|
9291
10183
|
}
|
|
9292
10184
|
return void 0;
|
|
9293
10185
|
};
|
|
@@ -9318,18 +10210,7 @@ var Selection = class {
|
|
|
9318
10210
|
}
|
|
9319
10211
|
for (const id of this.set) {
|
|
9320
10212
|
if (this.builder.isOptionId(id)) {
|
|
9321
|
-
const host = fields
|
|
9322
|
-
(x) => {
|
|
9323
|
-
var _a2;
|
|
9324
|
-
return ((_a2 = x.options) != null ? _a2 : []).some((o) => o.id === id);
|
|
9325
|
-
}
|
|
9326
|
-
);
|
|
9327
|
-
if (host == null ? void 0 : host.bind_id)
|
|
9328
|
-
return Array.isArray(host.bind_id) ? host.bind_id[0] : host.bind_id;
|
|
9329
|
-
}
|
|
9330
|
-
if (id.includes("::")) {
|
|
9331
|
-
const [fid] = id.split("::");
|
|
9332
|
-
const host = fields.find((x) => x.id === fid);
|
|
10213
|
+
const host = findOptionOwnerField(fields, id);
|
|
9333
10214
|
if (host == null ? void 0 : host.bind_id)
|
|
9334
10215
|
return Array.isArray(host.bind_id) ? host.bind_id[0] : host.bind_id;
|
|
9335
10216
|
}
|
|
@@ -9343,7 +10224,11 @@ var Selection = class {
|
|
|
9343
10224
|
const tagById = new Map(tags.map((t) => [t.id, t]));
|
|
9344
10225
|
const tag = tagById.get(tagId);
|
|
9345
10226
|
const selectedTriggerIds = this.selectedButtons();
|
|
9346
|
-
const
|
|
10227
|
+
const visibility = this.builder.resolveVisibility(
|
|
10228
|
+
tagId,
|
|
10229
|
+
selectedTriggerIds
|
|
10230
|
+
);
|
|
10231
|
+
const fieldIds = visibility.fieldIds;
|
|
9347
10232
|
const fieldById = new Map(fields.map((f) => [f.id, f]));
|
|
9348
10233
|
const visible = fieldIds.map((id) => fieldById.get(id)).filter(Boolean);
|
|
9349
10234
|
const parentTags = [];
|
|
@@ -9369,6 +10254,14 @@ var Selection = class {
|
|
|
9369
10254
|
let baseOverridden = false;
|
|
9370
10255
|
for (const selId of this.set) {
|
|
9371
10256
|
const opt = this.findOptionById(fields, selId);
|
|
10257
|
+
if (opt && !this.isSelectedOptionVisible(
|
|
10258
|
+
fields,
|
|
10259
|
+
selId,
|
|
10260
|
+
fieldIds,
|
|
10261
|
+
visibility.optionsByFieldId
|
|
10262
|
+
)) {
|
|
10263
|
+
continue;
|
|
10264
|
+
}
|
|
9372
10265
|
if ((opt == null ? void 0 : opt.service_id) != null) {
|
|
9373
10266
|
const role = (_d = opt.pricing_role) != null ? _d : "base";
|
|
9374
10267
|
const cap = (_e = resolve == null ? void 0 : resolve(opt.service_id)) != null ? _e : { id: opt.service_id };
|
|
@@ -9399,6 +10292,8 @@ var Selection = class {
|
|
|
9399
10292
|
tag,
|
|
9400
10293
|
fields: visible,
|
|
9401
10294
|
fieldIds,
|
|
10295
|
+
optionsByFieldId: visibility.optionsByFieldId,
|
|
10296
|
+
forcedFieldIds: visibility.forcedFieldIds,
|
|
9402
10297
|
parentTags,
|
|
9403
10298
|
childrenTags,
|
|
9404
10299
|
services
|
|
@@ -9422,21 +10317,19 @@ var Selection = class {
|
|
|
9422
10317
|
return baseOverridden;
|
|
9423
10318
|
}
|
|
9424
10319
|
findOptionById(fields, selId) {
|
|
9425
|
-
var _a, _b;
|
|
9426
10320
|
if (this.builder.isOptionId(selId)) {
|
|
9427
|
-
|
|
9428
|
-
|
|
9429
|
-
if (o) return o;
|
|
9430
|
-
}
|
|
9431
|
-
}
|
|
9432
|
-
if (selId.includes("::")) {
|
|
9433
|
-
const [fid, oid] = selId.split("::");
|
|
9434
|
-
const f = fields.find((x) => x.id === fid);
|
|
9435
|
-
const o = (_b = f == null ? void 0 : f.options) == null ? void 0 : _b.find((x) => x.id === oid || x.id === selId);
|
|
9436
|
-
if (o) return o;
|
|
10321
|
+
const field = findOptionOwnerField(fields, selId);
|
|
10322
|
+
return findFieldOption(field, selId);
|
|
9437
10323
|
}
|
|
9438
10324
|
return void 0;
|
|
9439
10325
|
}
|
|
10326
|
+
isSelectedOptionVisible(fields, selId, visibleFieldIds, optionsByFieldId) {
|
|
10327
|
+
const visibleFields = new Set(visibleFieldIds);
|
|
10328
|
+
const field = findOptionOwnerField(fields, selId);
|
|
10329
|
+
if (!field || !visibleFields.has(field.id)) return false;
|
|
10330
|
+
const allowed = optionsByFieldId[field.id];
|
|
10331
|
+
return !allowed || allowed.includes(selId);
|
|
10332
|
+
}
|
|
9440
10333
|
};
|
|
9441
10334
|
|
|
9442
10335
|
// src/react/canvas/api.ts
|
|
@@ -10349,11 +11242,83 @@ function useOrderFlow() {
|
|
|
10349
11242
|
if (!ready) return void 0;
|
|
10350
11243
|
return (_c2 = (_b2 = (_a2 = ctx.selection) == null ? void 0 : _a2.currentTag) == null ? void 0 : _b2.call(_a2)) != null ? _c2 : ctx.activeTagId;
|
|
10351
11244
|
}, [ready, ctx.selection, ctx.activeTagId, selTick]);
|
|
11245
|
+
const visibleOptionsByFieldId = useMemo4(
|
|
11246
|
+
() => {
|
|
11247
|
+
var _a2;
|
|
11248
|
+
return (_a2 = visibleGroup == null ? void 0 : visibleGroup.optionsByFieldId) != null ? _a2 : {};
|
|
11249
|
+
},
|
|
11250
|
+
[visibleGroup]
|
|
11251
|
+
);
|
|
11252
|
+
const forcedFieldIds = useMemo4(
|
|
11253
|
+
() => {
|
|
11254
|
+
var _a2;
|
|
11255
|
+
return (_a2 = visibleGroup == null ? void 0 : visibleGroup.forcedFieldIds) != null ? _a2 : [];
|
|
11256
|
+
},
|
|
11257
|
+
[visibleGroup]
|
|
11258
|
+
);
|
|
10352
11259
|
const formValuesByFieldId = useMemo4(() => {
|
|
10353
11260
|
var _a2, _b2, _c2;
|
|
10354
11261
|
const values = (_c2 = (_b2 = (_a2 = ctx.formApi).snapshot) == null ? void 0 : _b2.call(_a2)) != null ? _c2 : {};
|
|
10355
11262
|
return values;
|
|
10356
11263
|
}, [ctx.formApi, formTick]);
|
|
11264
|
+
useEffect3(() => {
|
|
11265
|
+
var _a2, _b2, _c2, _d;
|
|
11266
|
+
if (!ready || !ctx.selection) return;
|
|
11267
|
+
const { builder, selection } = ctx.ensureReady("pruneHiddenOptions");
|
|
11268
|
+
const fields = (_a2 = builder.getProps().fields) != null ? _a2 : [];
|
|
11269
|
+
const visibleOptionEntries = Object.entries(visibleOptionsByFieldId);
|
|
11270
|
+
if (!visibleOptionEntries.length) return;
|
|
11271
|
+
const visibleOptionSets = new Map(
|
|
11272
|
+
visibleOptionEntries.map(([fieldId, optionIds]) => [
|
|
11273
|
+
fieldId,
|
|
11274
|
+
new Set(optionIds)
|
|
11275
|
+
])
|
|
11276
|
+
);
|
|
11277
|
+
const changedFieldIds = /* @__PURE__ */ new Set();
|
|
11278
|
+
const ownerForToken = (token) => {
|
|
11279
|
+
if (!token) return void 0;
|
|
11280
|
+
const owner = findOptionOwnerField(fields, token);
|
|
11281
|
+
return owner == null ? void 0 : owner.id;
|
|
11282
|
+
};
|
|
11283
|
+
const retained = [];
|
|
11284
|
+
let changed = false;
|
|
11285
|
+
for (const token of selection.all()) {
|
|
11286
|
+
const ownerFieldId = ownerForToken(token);
|
|
11287
|
+
if (!ownerFieldId) {
|
|
11288
|
+
retained.push(token);
|
|
11289
|
+
continue;
|
|
11290
|
+
}
|
|
11291
|
+
const allowed = visibleOptionSets.get(ownerFieldId);
|
|
11292
|
+
if (!allowed) {
|
|
11293
|
+
retained.push(token);
|
|
11294
|
+
continue;
|
|
11295
|
+
}
|
|
11296
|
+
if (allowed.has(token)) {
|
|
11297
|
+
retained.push(token);
|
|
11298
|
+
continue;
|
|
11299
|
+
}
|
|
11300
|
+
changed = true;
|
|
11301
|
+
changedFieldIds.add(ownerFieldId);
|
|
11302
|
+
}
|
|
11303
|
+
if (!changed) return;
|
|
11304
|
+
for (const fieldId of changedFieldIds) {
|
|
11305
|
+
const allowed = visibleOptionSets.get(fieldId);
|
|
11306
|
+
const currentValue = ((_d = (_c2 = (_b2 = ctx.formApi).snapshot) == null ? void 0 : _c2.call(_b2)) != null ? _d : {})[fieldId];
|
|
11307
|
+
if (Array.isArray(currentValue)) {
|
|
11308
|
+
const next = currentValue.filter(
|
|
11309
|
+
(value) => allowed == null ? void 0 : allowed.has(String(value))
|
|
11310
|
+
);
|
|
11311
|
+
if (next.length !== currentValue.length) {
|
|
11312
|
+
ctx.formApi.set(fieldId, next.length ? next : void 0);
|
|
11313
|
+
}
|
|
11314
|
+
continue;
|
|
11315
|
+
}
|
|
11316
|
+
if (currentValue !== void 0 && allowed && !allowed.has(String(currentValue))) {
|
|
11317
|
+
ctx.formApi.set(fieldId, void 0);
|
|
11318
|
+
}
|
|
11319
|
+
}
|
|
11320
|
+
selection.many(retained, retained[retained.length - 1]);
|
|
11321
|
+
}, [ctx, ready, selTick, visibleOptionsByFieldId]);
|
|
10357
11322
|
const optionSelectionsByFieldId = useMemo4(
|
|
10358
11323
|
() => ({}),
|
|
10359
11324
|
[]
|
|
@@ -10501,7 +11466,7 @@ function useOrderFlow() {
|
|
|
10501
11466
|
);
|
|
10502
11467
|
const setFieldOptions = useCallback3(
|
|
10503
11468
|
(fieldId, optionIds) => {
|
|
10504
|
-
var _a2, _b2, _c2
|
|
11469
|
+
var _a2, _b2, _c2;
|
|
10505
11470
|
const { builder, selection, init } = ctx.ensureReady(
|
|
10506
11471
|
"setFieldOptions"
|
|
10507
11472
|
);
|
|
@@ -10509,7 +11474,9 @@ function useOrderFlow() {
|
|
|
10509
11474
|
const field = fields.find((f) => f.id === fieldId);
|
|
10510
11475
|
if (!field) return;
|
|
10511
11476
|
const validOptionIds = new Set(
|
|
10512
|
-
((
|
|
11477
|
+
Array.from(fieldOptionIdSet(field)).map(
|
|
11478
|
+
(optionId) => String(optionId)
|
|
11479
|
+
)
|
|
10513
11480
|
);
|
|
10514
11481
|
const dedupedValid = [];
|
|
10515
11482
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -10520,36 +11487,18 @@ function useOrderFlow() {
|
|
|
10520
11487
|
seen.add(optionId);
|
|
10521
11488
|
dedupedValid.push(optionId);
|
|
10522
11489
|
}
|
|
10523
|
-
const mode = (
|
|
10524
|
-
const isMulti = ((
|
|
11490
|
+
const mode = (_b2 = init.mode) != null ? _b2 : "prod";
|
|
11491
|
+
const isMulti = ((_c2 = field.meta) == null ? void 0 : _c2.multi) === true;
|
|
10525
11492
|
const normalized = mode === "prod" && !isMulti ? dedupedValid.length ? [dedupedValid[dedupedValid.length - 1]] : [] : dedupedValid;
|
|
10526
|
-
const fieldById = new Map(fields.map((f) => [f.id, f]));
|
|
10527
11493
|
const nodeMap = builder.getNodeMap();
|
|
10528
11494
|
const resolveOptionOwnerFieldId = (token) => {
|
|
10529
11495
|
var _a3;
|
|
10530
11496
|
if (!token) return void 0;
|
|
10531
|
-
if (token.includes("::")) {
|
|
10532
|
-
const [legacyFieldId, optionId] = token.split("::", 2);
|
|
10533
|
-
if (!optionId) return void 0;
|
|
10534
|
-
const optionRef2 = nodeMap.get(optionId);
|
|
10535
|
-
if ((optionRef2 == null ? void 0 : optionRef2.kind) === "option" && typeof optionRef2.fieldId === "string") {
|
|
10536
|
-
return optionRef2.fieldId;
|
|
10537
|
-
}
|
|
10538
|
-
if (legacyFieldId && fieldById.has(legacyFieldId)) {
|
|
10539
|
-
return legacyFieldId;
|
|
10540
|
-
}
|
|
10541
|
-
return void 0;
|
|
10542
|
-
}
|
|
10543
11497
|
const optionRef = nodeMap.get(token);
|
|
10544
11498
|
if ((optionRef == null ? void 0 : optionRef.kind) === "option" && typeof optionRef.fieldId === "string") {
|
|
10545
11499
|
return optionRef.fieldId;
|
|
10546
11500
|
}
|
|
10547
|
-
|
|
10548
|
-
if ((_a3 = f.options) == null ? void 0 : _a3.some((option) => option.id === token)) {
|
|
10549
|
-
return f.id;
|
|
10550
|
-
}
|
|
10551
|
-
}
|
|
10552
|
-
return void 0;
|
|
11501
|
+
return (_a3 = findOptionOwnerField(fields, token)) == null ? void 0 : _a3.id;
|
|
10553
11502
|
};
|
|
10554
11503
|
const retained = Array.from(selection.all()).filter(
|
|
10555
11504
|
(token) => resolveOptionOwnerFieldId(token) !== fieldId
|
|
@@ -10653,6 +11602,8 @@ function useOrderFlow() {
|
|
|
10653
11602
|
raw,
|
|
10654
11603
|
notices,
|
|
10655
11604
|
visibleGroup,
|
|
11605
|
+
visibleOptionsByFieldId,
|
|
11606
|
+
forcedFieldIds,
|
|
10656
11607
|
formValuesByFieldId,
|
|
10657
11608
|
optionSelectionsByFieldId,
|
|
10658
11609
|
quantityPreview: previewSnapshot.quantity,
|
|
@@ -10759,6 +11710,18 @@ function Wrapper({
|
|
|
10759
11710
|
const flow = useOrderFlow();
|
|
10760
11711
|
const kind = toKind(field);
|
|
10761
11712
|
const variant = toVariant(field);
|
|
11713
|
+
const renderedField = React4.useMemo(() => {
|
|
11714
|
+
var _a2;
|
|
11715
|
+
const visibleOptionIds = flow.visibleOptionsByFieldId[field.id];
|
|
11716
|
+
if (!visibleOptionIds) return field;
|
|
11717
|
+
return {
|
|
11718
|
+
...field,
|
|
11719
|
+
options: (_a2 = filterFieldOptionsById(
|
|
11720
|
+
field.options,
|
|
11721
|
+
new Set(visibleOptionIds)
|
|
11722
|
+
)) != null ? _a2 : []
|
|
11723
|
+
};
|
|
11724
|
+
}, [field, flow.visibleOptionsByFieldId]);
|
|
10762
11725
|
const descriptor = React4.useMemo(
|
|
10763
11726
|
() => resolveInputDescriptor(registry, kind, variant),
|
|
10764
11727
|
[kind, registry, variant]
|
|
@@ -10772,8 +11735,8 @@ function Wrapper({
|
|
|
10772
11735
|
const baseProps = (_b = descriptor.defaultProps) != null ? _b : {};
|
|
10773
11736
|
const defaultProps = useMemo6(() => {
|
|
10774
11737
|
var _a2;
|
|
10775
|
-
return { ...baseProps, ...(_a2 =
|
|
10776
|
-
}, [baseProps,
|
|
11738
|
+
return { ...baseProps, ...(_a2 = renderedField.defaults) != null ? _a2 : {} };
|
|
11739
|
+
}, [baseProps, renderedField.defaults]);
|
|
10777
11740
|
const valueProp = (_c = adapter.valueProp) != null ? _c : "value";
|
|
10778
11741
|
const changeProp = (_d = adapter.changeProp) != null ? _d : "onChange";
|
|
10779
11742
|
const errorProp = (_e = adapter.errorProp) != null ? _e : "errorText";
|
|
@@ -10787,13 +11750,14 @@ function Wrapper({
|
|
|
10787
11750
|
disabled: !!disabled
|
|
10788
11751
|
});
|
|
10789
11752
|
const optionIds = React4.useMemo(() => {
|
|
10790
|
-
var _a2;
|
|
10791
11753
|
if (!isOptionBased2) return /* @__PURE__ */ new Set();
|
|
10792
|
-
return new Set(
|
|
10793
|
-
|
|
11754
|
+
return new Set(
|
|
11755
|
+
Array.from(fieldOptionIdSet(renderedField)).map(String)
|
|
11756
|
+
);
|
|
11757
|
+
}, [isOptionBased2, renderedField]);
|
|
10794
11758
|
const adapterCtx = React4.useMemo(
|
|
10795
|
-
() => ({ field, props: flow.raw }),
|
|
10796
|
-
[
|
|
11759
|
+
() => ({ field: renderedField, props: flow.raw }),
|
|
11760
|
+
[renderedField, flow.raw]
|
|
10797
11761
|
);
|
|
10798
11762
|
const onHostChange = React4.useCallback(
|
|
10799
11763
|
(next) => {
|
|
@@ -10804,7 +11768,7 @@ function Wrapper({
|
|
|
10804
11768
|
if (isOptionBased2) {
|
|
10805
11769
|
if (!adapter.getSelectedOptions) {
|
|
10806
11770
|
throw new Error(
|
|
10807
|
-
`[Wrapper] Adapter for "${
|
|
11771
|
+
`[Wrapper] Adapter for "${renderedField.id}" (${renderedField.type}) must implement getSelectedOptions() because this field has options.`
|
|
10808
11772
|
);
|
|
10809
11773
|
}
|
|
10810
11774
|
const rawIds = adapter.getSelectedOptions(
|
|
@@ -10817,20 +11781,20 @@ function Wrapper({
|
|
|
10817
11781
|
(rawIds != null ? rawIds : []).map(String).filter((id) => optionIds.has(id))
|
|
10818
11782
|
)
|
|
10819
11783
|
);
|
|
10820
|
-
flow.setFieldOptions(
|
|
11784
|
+
flow.setFieldOptions(renderedField.id, nextIds);
|
|
10821
11785
|
return;
|
|
10822
11786
|
}
|
|
10823
11787
|
if (isActionButton) {
|
|
10824
11788
|
const isActive = (_e2 = (_d2 = adapter.isActive) == null ? void 0 : _d2.call(adapter, stored, adapterCtx)) != null ? _e2 : Boolean(stored);
|
|
10825
|
-
if (isActive) flow.toggleOption(
|
|
10826
|
-
else flow.clearField(
|
|
11789
|
+
if (isActive) flow.toggleOption(renderedField.id);
|
|
11790
|
+
else flow.clearField(renderedField.id);
|
|
10827
11791
|
}
|
|
10828
11792
|
},
|
|
10829
11793
|
[
|
|
10830
11794
|
adapter,
|
|
10831
11795
|
adapterCtx,
|
|
10832
|
-
|
|
10833
|
-
|
|
11796
|
+
renderedField.id,
|
|
11797
|
+
renderedField.type,
|
|
10834
11798
|
flow,
|
|
10835
11799
|
fp,
|
|
10836
11800
|
isActionButton,
|
|
@@ -10844,12 +11808,12 @@ function Wrapper({
|
|
|
10844
11808
|
const ctx = ctxOverrides && typeof ctxOverrides === "object" ? { ...ctxFromInit, ...ctxOverrides } : ctxFromInit;
|
|
10845
11809
|
return {
|
|
10846
11810
|
...ctx,
|
|
10847
|
-
field,
|
|
11811
|
+
field: renderedField,
|
|
10848
11812
|
flow,
|
|
10849
11813
|
value: fp.value,
|
|
10850
11814
|
error: fp.error
|
|
10851
11815
|
};
|
|
10852
|
-
}, [ctxOverrides,
|
|
11816
|
+
}, [ctxOverrides, renderedField, flow, fp.error, fp.value]);
|
|
10853
11817
|
const templatedDefaultProps = React4.useMemo(() => {
|
|
10854
11818
|
if (!templateStrings) return defaultProps;
|
|
10855
11819
|
return templateDeep(defaultProps, templateCtx);
|
|
@@ -10859,14 +11823,14 @@ function Wrapper({
|
|
|
10859
11823
|
return extraProps != null ? extraProps : {};
|
|
10860
11824
|
return templateDeep(extraProps != null ? extraProps : {}, templateCtx);
|
|
10861
11825
|
}, [extraProps, templateCtx, templateStrings]);
|
|
10862
|
-
const fieldProps = (_h = (_g = adapter == null ? void 0 : adapter.getInputPropsFromField) == null ? void 0 : _g.call(adapter, { field, props: flow.raw })) != null ? _h : {};
|
|
11826
|
+
const fieldProps = (_h = (_g = adapter == null ? void 0 : adapter.getInputPropsFromField) == null ? void 0 : _g.call(adapter, { field: renderedField, props: flow.raw })) != null ? _h : {};
|
|
10863
11827
|
const hostProps = {
|
|
10864
|
-
id:
|
|
10865
|
-
field,
|
|
11828
|
+
id: renderedField.id,
|
|
11829
|
+
field: renderedField,
|
|
10866
11830
|
disabled: !!disabled || !!fp.disabled,
|
|
10867
11831
|
required: field.required,
|
|
10868
11832
|
// DO NOT pass `name` to InputField/entries
|
|
10869
|
-
fieldKey:
|
|
11833
|
+
fieldKey: renderedField.id,
|
|
10870
11834
|
...fieldProps != null ? fieldProps : {},
|
|
10871
11835
|
// error channel
|
|
10872
11836
|
error: fp.error,
|
|
@@ -11872,7 +12836,10 @@ var treeSelectDescriptor = {
|
|
|
11872
12836
|
supported: true,
|
|
11873
12837
|
autoCreate: true,
|
|
11874
12838
|
defaultLabel: "Option label",
|
|
11875
|
-
defaultValue: "option"
|
|
12839
|
+
defaultValue: "option",
|
|
12840
|
+
children: {
|
|
12841
|
+
supported: true
|
|
12842
|
+
}
|
|
11876
12843
|
},
|
|
11877
12844
|
multi: {
|
|
11878
12845
|
supported: true,
|
|
@@ -13063,20 +14030,29 @@ function withInputFieldUi(desc) {
|
|
|
13063
14030
|
const fieldNotices = notices.filter(
|
|
13064
14031
|
(notice) => matchesNotice(field, notice)
|
|
13065
14032
|
);
|
|
14033
|
+
const mapOptionForInputField = (item) => {
|
|
14034
|
+
var _a3;
|
|
14035
|
+
const optionNotices = notices.filter(
|
|
14036
|
+
(notice) => matchesNotice(item, notice)
|
|
14037
|
+
);
|
|
14038
|
+
return {
|
|
14039
|
+
...item,
|
|
14040
|
+
tags: optionNotices.map(toTagPill),
|
|
14041
|
+
...((_a3 = item.children) == null ? void 0 : _a3.length) ? {
|
|
14042
|
+
children: item.children.map(
|
|
14043
|
+
mapOptionForInputField
|
|
14044
|
+
)
|
|
14045
|
+
} : {}
|
|
14046
|
+
};
|
|
14047
|
+
};
|
|
13066
14048
|
return {
|
|
13067
14049
|
label: field.label,
|
|
13068
14050
|
tags: fieldNotices.map(toTagPill),
|
|
13069
14051
|
required: field.required,
|
|
13070
14052
|
...((_b = field.options) == null ? void 0 : _b.length) ? {
|
|
13071
|
-
options: field.options.map(
|
|
13072
|
-
|
|
13073
|
-
|
|
13074
|
-
);
|
|
13075
|
-
return {
|
|
13076
|
-
...item,
|
|
13077
|
-
tags: optionNotices.map(toTagPill)
|
|
13078
|
-
};
|
|
13079
|
-
})
|
|
14053
|
+
options: field.options.map(
|
|
14054
|
+
mapOptionForInputField
|
|
14055
|
+
)
|
|
13080
14056
|
} : {}
|
|
13081
14057
|
};
|
|
13082
14058
|
},
|