@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/workspace/index.cjs
CHANGED
|
@@ -384,6 +384,7 @@ function templateTime(template) {
|
|
|
384
384
|
return (_a = parseTimestamp(template.updatedAt)) != null ? _a : parseTimestamp(template.createdAt);
|
|
385
385
|
}
|
|
386
386
|
function shouldReplaceTemplates(params) {
|
|
387
|
+
var _a;
|
|
387
388
|
if (!params.requestedSince) return true;
|
|
388
389
|
if (!params.lastUpdatedAt) return false;
|
|
389
390
|
const requested = parseTimestamp(params.requestedSince);
|
|
@@ -391,7 +392,9 @@ function shouldReplaceTemplates(params) {
|
|
|
391
392
|
if (requested === void 0 || last === void 0) {
|
|
392
393
|
return false;
|
|
393
394
|
}
|
|
394
|
-
|
|
395
|
+
const currentTimes = ((_a = params.current) != null ? _a : []).map((template) => templateTime(template)).filter((time) => time !== void 0);
|
|
396
|
+
if (!currentTimes.length) return requested < last;
|
|
397
|
+
return requested < Math.min(...currentTimes);
|
|
395
398
|
}
|
|
396
399
|
function pickNewestTemplate(current, incoming) {
|
|
397
400
|
const currentTime = templateTime(current);
|
|
@@ -399,7 +402,8 @@ function pickNewestTemplate(current, incoming) {
|
|
|
399
402
|
if (currentTime !== void 0 && incomingTime !== void 0) {
|
|
400
403
|
return incomingTime >= currentTime ? incoming : current;
|
|
401
404
|
}
|
|
402
|
-
if (currentTime === void 0 && incomingTime !== void 0)
|
|
405
|
+
if (currentTime === void 0 && incomingTime !== void 0)
|
|
406
|
+
return incoming;
|
|
403
407
|
if (currentTime !== void 0 && incomingTime === void 0) return current;
|
|
404
408
|
return incoming;
|
|
405
409
|
}
|
|
@@ -472,7 +476,8 @@ function useTemplatesSlice(params) {
|
|
|
472
476
|
setTemplates((current) => {
|
|
473
477
|
const replace = shouldReplaceTemplates({
|
|
474
478
|
requestedSince,
|
|
475
|
-
lastUpdatedAt: current.updatedAt
|
|
479
|
+
lastUpdatedAt: current.updatedAt,
|
|
480
|
+
current: current.data
|
|
476
481
|
});
|
|
477
482
|
return {
|
|
478
483
|
data: replace ? res.value : mergeTemplates(current.data, res.value, {
|
|
@@ -571,7 +576,9 @@ function useTemplatesSlice(params) {
|
|
|
571
576
|
var _a, _b;
|
|
572
577
|
return {
|
|
573
578
|
...current,
|
|
574
|
-
data: (_b = (_a = current.data) == null ? void 0 : _a.filter(
|
|
579
|
+
data: (_b = (_a = current.data) == null ? void 0 : _a.filter(
|
|
580
|
+
(template) => template.id !== id
|
|
581
|
+
)) != null ? _b : current.data,
|
|
575
582
|
updatedAt: deleteRefreshSince
|
|
576
583
|
};
|
|
577
584
|
});
|
|
@@ -3634,6 +3641,9 @@ function normalise(input, opts = {}) {
|
|
|
3634
3641
|
const excludes_for_buttons = toStringArrayMap(
|
|
3635
3642
|
obj.excludes_for_buttons
|
|
3636
3643
|
);
|
|
3644
|
+
const option_effects_for_buttons = toOptionEffectMap(
|
|
3645
|
+
obj.option_effects_for_buttons
|
|
3646
|
+
);
|
|
3637
3647
|
const orderKinds = toStringMap(obj.orderKinds);
|
|
3638
3648
|
const notices = toNoticeArray(obj.notices);
|
|
3639
3649
|
let filters = rawFilters.map((t) => coerceTag(t, constraints));
|
|
@@ -3649,6 +3659,9 @@ function normalise(input, opts = {}) {
|
|
|
3649
3659
|
...isNonEmpty(orderKinds) && { orderKinds },
|
|
3650
3660
|
...isNonEmpty(includes_for_buttons) && { includes_for_buttons },
|
|
3651
3661
|
...isNonEmpty(excludes_for_buttons) && { excludes_for_buttons },
|
|
3662
|
+
...isNonEmpty(option_effects_for_buttons) && {
|
|
3663
|
+
option_effects_for_buttons
|
|
3664
|
+
},
|
|
3652
3665
|
...fallbacks && (isNonEmpty(fallbacks.nodes) || isNonEmpty(fallbacks.global)) && {
|
|
3653
3666
|
fallbacks
|
|
3654
3667
|
},
|
|
@@ -3803,6 +3816,7 @@ function coerceOption(src, inheritRole) {
|
|
|
3803
3816
|
const value = typeof src.value === "string" || typeof src.value === "number" ? src.value : void 0;
|
|
3804
3817
|
const pricing_role = src.pricing_role === "utility" || src.pricing_role === "base" ? src.pricing_role : inheritRole;
|
|
3805
3818
|
const meta = src.meta && typeof src.meta === "object" ? src.meta : void 0;
|
|
3819
|
+
const children = Array.isArray(src.children) ? src.children.map((child) => coerceOption(child, pricing_role)) : void 0;
|
|
3806
3820
|
const option = {
|
|
3807
3821
|
id: "",
|
|
3808
3822
|
label: "",
|
|
@@ -3811,7 +3825,8 @@ function coerceOption(src, inheritRole) {
|
|
|
3811
3825
|
...value !== void 0 && { value },
|
|
3812
3826
|
...service_id !== void 0 && { service_id },
|
|
3813
3827
|
pricing_role,
|
|
3814
|
-
...meta && { meta }
|
|
3828
|
+
...meta && { meta },
|
|
3829
|
+
...children && children.length && { children }
|
|
3815
3830
|
};
|
|
3816
3831
|
return option;
|
|
3817
3832
|
}
|
|
@@ -3876,6 +3891,35 @@ function toStringArrayMap(src) {
|
|
|
3876
3891
|
}
|
|
3877
3892
|
return Object.keys(out).length ? out : void 0;
|
|
3878
3893
|
}
|
|
3894
|
+
function toOptionEffectMap(src) {
|
|
3895
|
+
var _a, _b;
|
|
3896
|
+
if (!src || typeof src !== "object") return void 0;
|
|
3897
|
+
const out = {};
|
|
3898
|
+
for (const [triggerId, rawTargets] of Object.entries(src)) {
|
|
3899
|
+
if (!triggerId || !rawTargets || typeof rawTargets !== "object") {
|
|
3900
|
+
continue;
|
|
3901
|
+
}
|
|
3902
|
+
const targets = {};
|
|
3903
|
+
for (const [fieldId, rawEffect] of Object.entries(rawTargets)) {
|
|
3904
|
+
if (!fieldId || !rawEffect || typeof rawEffect !== "object") {
|
|
3905
|
+
continue;
|
|
3906
|
+
}
|
|
3907
|
+
const effect = rawEffect;
|
|
3908
|
+
const include2 = toStringArray(effect.include);
|
|
3909
|
+
const exclude2 = toStringArray(effect.exclude);
|
|
3910
|
+
const next = {
|
|
3911
|
+
...effect.forceVisible === true ? { forceVisible: true } : {},
|
|
3912
|
+
...include2.length ? { include: dedupe(include2) } : {},
|
|
3913
|
+
...exclude2.length ? { exclude: dedupe(exclude2) } : {}
|
|
3914
|
+
};
|
|
3915
|
+
if (next.forceVisible === true || ((_a = next.include) == null ? void 0 : _a.length) || ((_b = next.exclude) == null ? void 0 : _b.length)) {
|
|
3916
|
+
targets[fieldId] = next;
|
|
3917
|
+
}
|
|
3918
|
+
}
|
|
3919
|
+
if (Object.keys(targets).length) out[triggerId] = targets;
|
|
3920
|
+
}
|
|
3921
|
+
return Object.keys(out).length ? out : void 0;
|
|
3922
|
+
}
|
|
3879
3923
|
function toStringArray(v) {
|
|
3880
3924
|
if (!Array.isArray(v)) return [];
|
|
3881
3925
|
return v.map((x) => String(x)).filter((s) => !!s && s.trim().length > 0);
|
|
@@ -3950,6 +3994,57 @@ function normalizeFieldValidation(input) {
|
|
|
3950
3994
|
return one ? [one] : void 0;
|
|
3951
3995
|
}
|
|
3952
3996
|
|
|
3997
|
+
// src/core/options.ts
|
|
3998
|
+
function walkFieldOptions(field) {
|
|
3999
|
+
const out = [];
|
|
4000
|
+
const visit = (options, depth, parentId) => {
|
|
4001
|
+
for (const option of options != null ? options : []) {
|
|
4002
|
+
out.push({
|
|
4003
|
+
field,
|
|
4004
|
+
fieldId: field.id,
|
|
4005
|
+
option,
|
|
4006
|
+
optionId: option.id,
|
|
4007
|
+
depth,
|
|
4008
|
+
parentId
|
|
4009
|
+
});
|
|
4010
|
+
visit(option.children, depth + 1, option.id);
|
|
4011
|
+
}
|
|
4012
|
+
};
|
|
4013
|
+
visit(field.options, 0);
|
|
4014
|
+
return out;
|
|
4015
|
+
}
|
|
4016
|
+
function fieldOptionIds(field) {
|
|
4017
|
+
return walkFieldOptions(field).map((visit) => visit.optionId);
|
|
4018
|
+
}
|
|
4019
|
+
function fieldOptionIdSet(field) {
|
|
4020
|
+
return new Set(fieldOptionIds(field));
|
|
4021
|
+
}
|
|
4022
|
+
function findFieldOption(field, optionId) {
|
|
4023
|
+
var _a;
|
|
4024
|
+
if (!field) return void 0;
|
|
4025
|
+
return (_a = walkFieldOptions(field).find((visit) => visit.optionId === optionId)) == null ? void 0 : _a.option;
|
|
4026
|
+
}
|
|
4027
|
+
function findOptionOwnerField(fields, optionId) {
|
|
4028
|
+
for (const field of fields) {
|
|
4029
|
+
if (findFieldOption(field, optionId)) return field;
|
|
4030
|
+
}
|
|
4031
|
+
return void 0;
|
|
4032
|
+
}
|
|
4033
|
+
function optionOwnerMap(fields) {
|
|
4034
|
+
const out = /* @__PURE__ */ new Map();
|
|
4035
|
+
for (const field of fields) {
|
|
4036
|
+
for (const visit of walkFieldOptions(field)) {
|
|
4037
|
+
if (!out.has(visit.optionId)) {
|
|
4038
|
+
out.set(visit.optionId, {
|
|
4039
|
+
fieldId: field.id,
|
|
4040
|
+
option: visit.option
|
|
4041
|
+
});
|
|
4042
|
+
}
|
|
4043
|
+
}
|
|
4044
|
+
}
|
|
4045
|
+
return out;
|
|
4046
|
+
}
|
|
4047
|
+
|
|
3953
4048
|
// src/core/validate/shared.ts
|
|
3954
4049
|
function isFiniteNumber(v) {
|
|
3955
4050
|
return typeof v === "number" && Number.isFinite(v);
|
|
@@ -3958,8 +4053,9 @@ function isServiceIdRef(v) {
|
|
|
3958
4053
|
return typeof v === "string" && v.trim().length > 0 || typeof v === "number" && Number.isFinite(v);
|
|
3959
4054
|
}
|
|
3960
4055
|
function hasAnyServiceOption(f) {
|
|
3961
|
-
|
|
3962
|
-
|
|
4056
|
+
return walkFieldOptions(f).some(
|
|
4057
|
+
(visit) => isServiceIdRef(visit.option.service_id)
|
|
4058
|
+
);
|
|
3963
4059
|
}
|
|
3964
4060
|
function getByPath(obj, path) {
|
|
3965
4061
|
if (!path) return void 0;
|
|
@@ -4048,14 +4144,14 @@ function withAffected(details, ids) {
|
|
|
4048
4144
|
|
|
4049
4145
|
// src/core/node-map.ts
|
|
4050
4146
|
function buildNodeMap(props) {
|
|
4051
|
-
var _a, _b
|
|
4147
|
+
var _a, _b;
|
|
4052
4148
|
const map = /* @__PURE__ */ new Map();
|
|
4053
4149
|
for (const t of (_a = props.filters) != null ? _a : []) {
|
|
4054
4150
|
if (!map.has(t.id)) map.set(t.id, { kind: "tag", id: t.id, node: t });
|
|
4055
4151
|
}
|
|
4056
4152
|
for (const f of (_b = props.fields) != null ? _b : []) {
|
|
4057
4153
|
if (!map.has(f.id)) map.set(f.id, { kind: "field", id: f.id, node: f });
|
|
4058
|
-
for (const o of (
|
|
4154
|
+
for (const { option: o } of walkFieldOptions(f)) {
|
|
4059
4155
|
if (!map.has(o.id))
|
|
4060
4156
|
map.set(o.id, {
|
|
4061
4157
|
kind: "option",
|
|
@@ -4068,12 +4164,6 @@ function buildNodeMap(props) {
|
|
|
4068
4164
|
return map;
|
|
4069
4165
|
}
|
|
4070
4166
|
function resolveTrigger(trigger, nodeMap) {
|
|
4071
|
-
const idx = trigger.indexOf("::");
|
|
4072
|
-
if (idx !== -1) {
|
|
4073
|
-
const fieldId = trigger.slice(0, idx);
|
|
4074
|
-
const optionId = trigger.slice(idx + 2);
|
|
4075
|
-
return { kind: "composite", triggerKey: trigger, fieldId, optionId };
|
|
4076
|
-
}
|
|
4077
4167
|
const direct = nodeMap.get(trigger);
|
|
4078
4168
|
if (!direct) return void 0;
|
|
4079
4169
|
if (direct.kind === "option") {
|
|
@@ -4125,11 +4215,6 @@ function visibleFieldIdsUnder(props, tagId, opts = {}) {
|
|
|
4125
4215
|
const ownerDepthForTriggerKey = (triggerKey) => {
|
|
4126
4216
|
const t = resolveTrigger(triggerKey, nodeMap);
|
|
4127
4217
|
if (!t) return void 0;
|
|
4128
|
-
if (t.kind === "composite") {
|
|
4129
|
-
const f = fieldById.get(t.fieldId);
|
|
4130
|
-
if (!f) return void 0;
|
|
4131
|
-
return ownerDepthForField(f);
|
|
4132
|
-
}
|
|
4133
4218
|
if (t.kind === "field") {
|
|
4134
4219
|
const f = fieldById.get(t.id);
|
|
4135
4220
|
if (!f || f.button !== true) return void 0;
|
|
@@ -4212,6 +4297,84 @@ function visibleFieldsUnder(props, tagId, opts = {}) {
|
|
|
4212
4297
|
const fieldById = new Map(((_a = props.fields) != null ? _a : []).map((f) => [f.id, f]));
|
|
4213
4298
|
return ids.map((id) => fieldById.get(id)).filter(Boolean);
|
|
4214
4299
|
}
|
|
4300
|
+
function resolveVisibility(props, tagId, selectedKeys) {
|
|
4301
|
+
var _a, _b, _c, _d;
|
|
4302
|
+
const selected = new Set(selectedKeys != null ? selectedKeys : []);
|
|
4303
|
+
const baseFieldIds = visibleFieldIdsUnder(props, tagId, { selectedKeys: selected });
|
|
4304
|
+
const fieldById = new Map(((_a = props.fields) != null ? _a : []).map((field) => [field.id, field]));
|
|
4305
|
+
const visible = new Set(baseFieldIds);
|
|
4306
|
+
const forced = /* @__PURE__ */ new Set();
|
|
4307
|
+
const optionsByFieldId = {};
|
|
4308
|
+
const optionIdsByFieldId = /* @__PURE__ */ new Map();
|
|
4309
|
+
const getOptionIds = (field) => {
|
|
4310
|
+
let ids = optionIdsByFieldId.get(field.id);
|
|
4311
|
+
if (!ids) {
|
|
4312
|
+
ids = fieldOptionIds(field);
|
|
4313
|
+
optionIdsByFieldId.set(field.id, ids);
|
|
4314
|
+
}
|
|
4315
|
+
return ids;
|
|
4316
|
+
};
|
|
4317
|
+
const ensureOptions = (field) => {
|
|
4318
|
+
const ids = getOptionIds(field);
|
|
4319
|
+
if (!ids.length) return void 0;
|
|
4320
|
+
if (!optionsByFieldId[field.id]) optionsByFieldId[field.id] = [...ids];
|
|
4321
|
+
return optionsByFieldId[field.id];
|
|
4322
|
+
};
|
|
4323
|
+
for (const fieldId of baseFieldIds) {
|
|
4324
|
+
const field = fieldById.get(fieldId);
|
|
4325
|
+
if (field) ensureOptions(field);
|
|
4326
|
+
}
|
|
4327
|
+
const effects = (_b = props.option_effects_for_buttons) != null ? _b : {};
|
|
4328
|
+
for (const triggerId of selected) {
|
|
4329
|
+
const targetRules = effects[triggerId];
|
|
4330
|
+
if (!targetRules) continue;
|
|
4331
|
+
for (const [targetFieldId, rule] of Object.entries(targetRules)) {
|
|
4332
|
+
const field = fieldById.get(targetFieldId);
|
|
4333
|
+
if (!field) continue;
|
|
4334
|
+
const isVisible = visible.has(targetFieldId);
|
|
4335
|
+
if (!isVisible && rule.forceVisible !== true) continue;
|
|
4336
|
+
if (!isVisible && rule.forceVisible === true) {
|
|
4337
|
+
visible.add(targetFieldId);
|
|
4338
|
+
forced.add(targetFieldId);
|
|
4339
|
+
}
|
|
4340
|
+
const orderedOptionIds = getOptionIds(field);
|
|
4341
|
+
if (!orderedOptionIds.length) continue;
|
|
4342
|
+
const known = new Set(orderedOptionIds);
|
|
4343
|
+
let allowed = (_c = optionsByFieldId[targetFieldId]) != null ? _c : [...orderedOptionIds];
|
|
4344
|
+
if (Array.isArray(rule.include) && rule.include.length) {
|
|
4345
|
+
const include2 = new Set(
|
|
4346
|
+
rule.include.filter((optionId) => known.has(optionId))
|
|
4347
|
+
);
|
|
4348
|
+
allowed = orderedOptionIds.filter(
|
|
4349
|
+
(optionId) => include2.has(optionId) && allowed.includes(optionId)
|
|
4350
|
+
);
|
|
4351
|
+
}
|
|
4352
|
+
if (Array.isArray(rule.exclude) && rule.exclude.length) {
|
|
4353
|
+
const exclude2 = new Set(
|
|
4354
|
+
rule.exclude.filter((optionId) => known.has(optionId))
|
|
4355
|
+
);
|
|
4356
|
+
allowed = allowed.filter((optionId) => !exclude2.has(optionId));
|
|
4357
|
+
}
|
|
4358
|
+
optionsByFieldId[targetFieldId] = allowed;
|
|
4359
|
+
}
|
|
4360
|
+
}
|
|
4361
|
+
const visibleFieldIds = baseFieldIds.filter((fieldId) => visible.has(fieldId));
|
|
4362
|
+
const seen = new Set(visibleFieldIds);
|
|
4363
|
+
for (const field of (_d = props.fields) != null ? _d : []) {
|
|
4364
|
+
if (!visible.has(field.id) || seen.has(field.id)) continue;
|
|
4365
|
+
seen.add(field.id);
|
|
4366
|
+
visibleFieldIds.push(field.id);
|
|
4367
|
+
ensureOptions(field);
|
|
4368
|
+
}
|
|
4369
|
+
for (const fieldId of Object.keys(optionsByFieldId)) {
|
|
4370
|
+
if (!visible.has(fieldId)) delete optionsByFieldId[fieldId];
|
|
4371
|
+
}
|
|
4372
|
+
return {
|
|
4373
|
+
fieldIds: visibleFieldIds,
|
|
4374
|
+
optionsByFieldId,
|
|
4375
|
+
forcedFieldIds: visibleFieldIds.filter((fieldId) => forced.has(fieldId))
|
|
4376
|
+
};
|
|
4377
|
+
}
|
|
4215
4378
|
|
|
4216
4379
|
// src/core/validate/steps/visibility.ts
|
|
4217
4380
|
function createFieldsVisibleUnder(v) {
|
|
@@ -4229,7 +4392,6 @@ function resolveRootTags(tags) {
|
|
|
4229
4392
|
return roots.length ? roots : tags.slice(0, 1);
|
|
4230
4393
|
}
|
|
4231
4394
|
function collectSelectableTriggersInContext(v, tagId, selectedKeys, effectfulKeys) {
|
|
4232
|
-
var _a;
|
|
4233
4395
|
const visible = visibleFieldsUnder(v.props, tagId, {
|
|
4234
4396
|
selectedKeys
|
|
4235
4397
|
});
|
|
@@ -4239,7 +4401,7 @@ function collectSelectableTriggersInContext(v, tagId, selectedKeys, effectfulKey
|
|
|
4239
4401
|
const t = f.id;
|
|
4240
4402
|
if (effectfulKeys.has(t)) triggers.push(t);
|
|
4241
4403
|
}
|
|
4242
|
-
for (const o of (
|
|
4404
|
+
for (const { option: o } of walkFieldOptions(f)) {
|
|
4243
4405
|
const t = o.id;
|
|
4244
4406
|
if (effectfulKeys.has(t)) triggers.push(t);
|
|
4245
4407
|
}
|
|
@@ -4248,7 +4410,7 @@ function collectSelectableTriggersInContext(v, tagId, selectedKeys, effectfulKey
|
|
|
4248
4410
|
return triggers;
|
|
4249
4411
|
}
|
|
4250
4412
|
function runVisibilityRulesOnce(v) {
|
|
4251
|
-
var _a, _b, _c, _d
|
|
4413
|
+
var _a, _b, _c, _d;
|
|
4252
4414
|
for (const t of v.tags) {
|
|
4253
4415
|
const visible = v.fieldsVisibleUnder(t.id);
|
|
4254
4416
|
const seen = /* @__PURE__ */ new Map();
|
|
@@ -4298,9 +4460,9 @@ function runVisibilityRulesOnce(v) {
|
|
|
4298
4460
|
let hasUtility = false;
|
|
4299
4461
|
const utilityOptionIds = [];
|
|
4300
4462
|
for (const f of visible) {
|
|
4301
|
-
for (const o of (
|
|
4463
|
+
for (const { option: o } of walkFieldOptions(f)) {
|
|
4302
4464
|
if (!isServiceIdRef(o.service_id)) continue;
|
|
4303
|
-
const role = (
|
|
4465
|
+
const role = (_d = (_c = o.pricing_role) != null ? _c : f.pricing_role) != null ? _d : "base";
|
|
4304
4466
|
if (role === "base") hasBase = true;
|
|
4305
4467
|
else if (role === "utility") {
|
|
4306
4468
|
hasUtility = true;
|
|
@@ -4341,7 +4503,7 @@ function dedupeErrorsInPlace(v, startIndex) {
|
|
|
4341
4503
|
v.errors.splice(startIndex, v.errors.length - startIndex, ...kept);
|
|
4342
4504
|
}
|
|
4343
4505
|
function validateVisibility(v, options = {}) {
|
|
4344
|
-
var _a, _b, _c, _d, _e;
|
|
4506
|
+
var _a, _b, _c, _d, _e, _f;
|
|
4345
4507
|
v.simulatedVisibilityContexts = [];
|
|
4346
4508
|
const simulate = options.simulate === true;
|
|
4347
4509
|
if (!simulate) {
|
|
@@ -4366,10 +4528,13 @@ function validateVisibility(v, options = {}) {
|
|
|
4366
4528
|
for (const key of Object.keys((_d = v.props.excludes_for_buttons) != null ? _d : {})) {
|
|
4367
4529
|
effectfulKeys.add(key);
|
|
4368
4530
|
}
|
|
4531
|
+
for (const key of Object.keys((_e = v.props.option_effects_for_buttons) != null ? _e : {})) {
|
|
4532
|
+
effectfulKeys.add(key);
|
|
4533
|
+
}
|
|
4369
4534
|
}
|
|
4370
4535
|
const roots = resolveRootTags(v.tags);
|
|
4371
4536
|
const rootTags = options.simulateAllRoots ? roots : roots.slice(0, 1);
|
|
4372
|
-
const originalSelected = new Set((
|
|
4537
|
+
const originalSelected = new Set((_f = v.selectedKeys) != null ? _f : []);
|
|
4373
4538
|
const errorsStart = v.errors.length;
|
|
4374
4539
|
const visited = /* @__PURE__ */ new Set();
|
|
4375
4540
|
const seenContexts = /* @__PURE__ */ new Set();
|
|
@@ -4510,7 +4675,7 @@ function validateStructure(v) {
|
|
|
4510
4675
|
|
|
4511
4676
|
// src/core/validate/steps/identity.ts
|
|
4512
4677
|
function validateIdentity(v) {
|
|
4513
|
-
var _a
|
|
4678
|
+
var _a;
|
|
4514
4679
|
const tags = v.tags;
|
|
4515
4680
|
const fields = v.fields;
|
|
4516
4681
|
{
|
|
@@ -4610,7 +4775,7 @@ function validateIdentity(v) {
|
|
|
4610
4775
|
}
|
|
4611
4776
|
}
|
|
4612
4777
|
for (const f of fields) {
|
|
4613
|
-
for (const o of (
|
|
4778
|
+
for (const { option: o } of walkFieldOptions(f)) {
|
|
4614
4779
|
if (!o.label || !o.label.trim()) {
|
|
4615
4780
|
v.errors.push({
|
|
4616
4781
|
code: "label_missing",
|
|
@@ -4625,25 +4790,11 @@ function validateIdentity(v) {
|
|
|
4625
4790
|
}
|
|
4626
4791
|
|
|
4627
4792
|
// src/core/validate/steps/option-maps.ts
|
|
4628
|
-
function parseFieldOptionKey(key) {
|
|
4629
|
-
const idx = key.indexOf("::");
|
|
4630
|
-
if (idx === -1) return null;
|
|
4631
|
-
const fieldId = key.slice(0, idx).trim();
|
|
4632
|
-
const optionId = key.slice(idx + 2).trim();
|
|
4633
|
-
if (!fieldId || !optionId) return null;
|
|
4634
|
-
return { fieldId, optionId };
|
|
4635
|
-
}
|
|
4636
|
-
function hasOption(v, fid, oid) {
|
|
4637
|
-
var _a;
|
|
4638
|
-
const f = v.fieldById.get(fid);
|
|
4639
|
-
if (!f) return false;
|
|
4640
|
-
return !!((_a = f.options) != null ? _a : []).find((o) => o.id === oid);
|
|
4641
|
-
}
|
|
4642
4793
|
function validateOptionMaps(v) {
|
|
4643
|
-
var _a, _b;
|
|
4794
|
+
var _a, _b, _c;
|
|
4644
4795
|
const incMap = (_a = v.props.includes_for_buttons) != null ? _a : {};
|
|
4645
4796
|
const excMap = (_b = v.props.excludes_for_buttons) != null ? _b : {};
|
|
4646
|
-
const badKeyMessage = (key) => `Invalid trigger-map key "${key}". Expected a known
|
|
4797
|
+
const badKeyMessage = (key) => `Invalid trigger-map key "${key}". Expected a known option id or button-field id.`;
|
|
4647
4798
|
const validateTriggerKey = (key) => {
|
|
4648
4799
|
const ref = v.nodeMap.get(key);
|
|
4649
4800
|
if (ref) {
|
|
@@ -4662,19 +4813,7 @@ function validateOptionMaps(v) {
|
|
|
4662
4813
|
}
|
|
4663
4814
|
return { ok: false, nodeId: ref.id, affected: [ref.id] };
|
|
4664
4815
|
}
|
|
4665
|
-
|
|
4666
|
-
if (!p) return { ok: false };
|
|
4667
|
-
if (!hasOption(v, p.fieldId, p.optionId))
|
|
4668
|
-
return {
|
|
4669
|
-
ok: false,
|
|
4670
|
-
nodeId: p.fieldId,
|
|
4671
|
-
affected: [p.fieldId, p.optionId]
|
|
4672
|
-
};
|
|
4673
|
-
return {
|
|
4674
|
-
ok: true,
|
|
4675
|
-
nodeId: p.fieldId,
|
|
4676
|
-
affected: [p.fieldId, p.optionId]
|
|
4677
|
-
};
|
|
4816
|
+
return { ok: false };
|
|
4678
4817
|
};
|
|
4679
4818
|
for (const k of Object.keys(incMap)) {
|
|
4680
4819
|
const r = validateTriggerKey(k);
|
|
@@ -4700,6 +4839,57 @@ function validateOptionMaps(v) {
|
|
|
4700
4839
|
});
|
|
4701
4840
|
}
|
|
4702
4841
|
}
|
|
4842
|
+
const effectMap = (_c = v.props.option_effects_for_buttons) != null ? _c : {};
|
|
4843
|
+
for (const [triggerKey, targets] of Object.entries(effectMap)) {
|
|
4844
|
+
const trigger = validateTriggerKey(triggerKey);
|
|
4845
|
+
if (!trigger.ok) {
|
|
4846
|
+
v.errors.push({
|
|
4847
|
+
code: "bad_option_effect_key",
|
|
4848
|
+
severity: "error",
|
|
4849
|
+
message: badKeyMessage(triggerKey),
|
|
4850
|
+
nodeId: trigger.nodeId,
|
|
4851
|
+
details: withAffected({ key: triggerKey }, trigger.affected)
|
|
4852
|
+
});
|
|
4853
|
+
}
|
|
4854
|
+
for (const [targetFieldId, effect] of Object.entries(targets != null ? targets : {})) {
|
|
4855
|
+
const field = v.fieldById.get(targetFieldId);
|
|
4856
|
+
if (!field) {
|
|
4857
|
+
v.errors.push({
|
|
4858
|
+
code: "bad_option_effect_target",
|
|
4859
|
+
severity: "error",
|
|
4860
|
+
message: `Option effect trigger "${triggerKey}" targets unknown field "${targetFieldId}".`,
|
|
4861
|
+
details: withAffected(
|
|
4862
|
+
{ key: triggerKey, targetFieldId },
|
|
4863
|
+
trigger.affected
|
|
4864
|
+
)
|
|
4865
|
+
});
|
|
4866
|
+
continue;
|
|
4867
|
+
}
|
|
4868
|
+
const validOptionIds = fieldOptionIdSet(field);
|
|
4869
|
+
const checkTargetOptions = (kind, optionIds) => {
|
|
4870
|
+
for (const optionId of optionIds != null ? optionIds : []) {
|
|
4871
|
+
if (validOptionIds.has(optionId)) continue;
|
|
4872
|
+
v.errors.push({
|
|
4873
|
+
code: "bad_option_effect_option",
|
|
4874
|
+
severity: "error",
|
|
4875
|
+
message: `Option effect trigger "${triggerKey}" references unknown ${kind} option "${optionId}" for field "${targetFieldId}".`,
|
|
4876
|
+
nodeId: targetFieldId,
|
|
4877
|
+
details: withAffected(
|
|
4878
|
+
{
|
|
4879
|
+
key: triggerKey,
|
|
4880
|
+
targetFieldId,
|
|
4881
|
+
optionId,
|
|
4882
|
+
kind
|
|
4883
|
+
},
|
|
4884
|
+
[targetFieldId, optionId]
|
|
4885
|
+
)
|
|
4886
|
+
});
|
|
4887
|
+
}
|
|
4888
|
+
};
|
|
4889
|
+
checkTargetOptions("include", effect == null ? void 0 : effect.include);
|
|
4890
|
+
checkTargetOptions("exclude", effect == null ? void 0 : effect.exclude);
|
|
4891
|
+
}
|
|
4892
|
+
}
|
|
4703
4893
|
for (const k of Object.keys(incMap)) {
|
|
4704
4894
|
if (!(k in excMap)) continue;
|
|
4705
4895
|
const r = validateTriggerKey(k);
|
|
@@ -4713,27 +4903,231 @@ function validateOptionMaps(v) {
|
|
|
4713
4903
|
}
|
|
4714
4904
|
}
|
|
4715
4905
|
|
|
4716
|
-
// src/
|
|
4717
|
-
|
|
4718
|
-
|
|
4719
|
-
const
|
|
4720
|
-
if (
|
|
4721
|
-
|
|
4722
|
-
|
|
4723
|
-
|
|
4724
|
-
|
|
4725
|
-
|
|
4726
|
-
|
|
4906
|
+
// src/core/validate/steps/visibility-cycles.ts
|
|
4907
|
+
var MAX_VISIBILITY_CYCLE_DEPTH = 20;
|
|
4908
|
+
function validateVisibilityCycles(v) {
|
|
4909
|
+
const triggerById = buildTriggerIndex(v.fields);
|
|
4910
|
+
if (!triggerById.size) return;
|
|
4911
|
+
const fieldTriggers = buildFieldTriggerIndex(v.fields);
|
|
4912
|
+
const revealTargetsByTrigger = buildRevealIndex(v, triggerById);
|
|
4913
|
+
const reported = /* @__PURE__ */ new Set();
|
|
4914
|
+
for (const rootTriggerId of Array.from(triggerById.keys()).sort()) {
|
|
4915
|
+
const required = makeRequiredState(triggerById, [rootTriggerId]);
|
|
4916
|
+
walkFromTrigger({
|
|
4917
|
+
v,
|
|
4918
|
+
triggerById,
|
|
4919
|
+
fieldTriggers,
|
|
4920
|
+
revealTargetsByTrigger,
|
|
4921
|
+
rootTriggerId,
|
|
4922
|
+
currentTriggerId: rootTriggerId,
|
|
4923
|
+
required,
|
|
4924
|
+
path: [rootTriggerId],
|
|
4925
|
+
visited: /* @__PURE__ */ new Set(),
|
|
4926
|
+
reported,
|
|
4927
|
+
depth: 0
|
|
4928
|
+
});
|
|
4929
|
+
}
|
|
4930
|
+
}
|
|
4931
|
+
function buildTriggerIndex(fields) {
|
|
4932
|
+
const out = /* @__PURE__ */ new Map();
|
|
4933
|
+
const owners = optionOwnerMap(fields);
|
|
4934
|
+
for (const field of fields) {
|
|
4935
|
+
if (field.button === true) {
|
|
4936
|
+
out.set(field.id, {
|
|
4937
|
+
kind: "field",
|
|
4938
|
+
id: field.id,
|
|
4939
|
+
ownerFieldId: field.id
|
|
4940
|
+
});
|
|
4941
|
+
}
|
|
4942
|
+
}
|
|
4943
|
+
for (const [optionId, owner] of owners) {
|
|
4944
|
+
out.set(optionId, {
|
|
4945
|
+
kind: "option",
|
|
4946
|
+
id: optionId,
|
|
4947
|
+
ownerFieldId: owner.fieldId
|
|
4948
|
+
});
|
|
4949
|
+
}
|
|
4950
|
+
return out;
|
|
4951
|
+
}
|
|
4952
|
+
function buildFieldTriggerIndex(fields) {
|
|
4953
|
+
const out = /* @__PURE__ */ new Map();
|
|
4954
|
+
for (const field of fields) {
|
|
4955
|
+
const triggers = [];
|
|
4956
|
+
if (field.button === true) triggers.push(field.id);
|
|
4957
|
+
for (const visit of walkFieldOptions(field)) {
|
|
4958
|
+
triggers.push(visit.optionId);
|
|
4959
|
+
}
|
|
4960
|
+
out.set(field.id, triggers);
|
|
4961
|
+
}
|
|
4962
|
+
return out;
|
|
4963
|
+
}
|
|
4964
|
+
function buildRevealIndex(v, triggerById) {
|
|
4965
|
+
var _a, _b;
|
|
4966
|
+
const out = /* @__PURE__ */ new Map();
|
|
4967
|
+
const addReveal = (triggerId, targetFieldId) => {
|
|
4968
|
+
var _a2;
|
|
4969
|
+
if (!triggerById.has(triggerId)) return;
|
|
4970
|
+
if (!v.fieldById.has(targetFieldId)) return;
|
|
4971
|
+
const set = (_a2 = out.get(triggerId)) != null ? _a2 : /* @__PURE__ */ new Set();
|
|
4972
|
+
set.add(targetFieldId);
|
|
4973
|
+
out.set(triggerId, set);
|
|
4974
|
+
};
|
|
4975
|
+
for (const [triggerId, targetIds] of Object.entries(
|
|
4976
|
+
(_a = v.props.includes_for_buttons) != null ? _a : {}
|
|
4977
|
+
)) {
|
|
4978
|
+
for (const targetId of targetIds != null ? targetIds : []) addReveal(triggerId, targetId);
|
|
4979
|
+
}
|
|
4980
|
+
for (const [triggerId, targets] of Object.entries(
|
|
4981
|
+
(_b = v.props.option_effects_for_buttons) != null ? _b : {}
|
|
4982
|
+
)) {
|
|
4983
|
+
for (const [targetFieldId, effect] of Object.entries(targets != null ? targets : {})) {
|
|
4984
|
+
if ((effect == null ? void 0 : effect.forceVisible) === true)
|
|
4985
|
+
addReveal(triggerId, targetFieldId);
|
|
4986
|
+
}
|
|
4987
|
+
}
|
|
4988
|
+
return new Map(
|
|
4989
|
+
Array.from(out.entries()).map(([triggerId, fieldIds]) => [
|
|
4990
|
+
triggerId,
|
|
4991
|
+
Array.from(fieldIds).sort()
|
|
4992
|
+
])
|
|
4993
|
+
);
|
|
4994
|
+
}
|
|
4995
|
+
function walkFromTrigger(args) {
|
|
4996
|
+
var _a, _b, _c;
|
|
4997
|
+
if (args.depth >= MAX_VISIBILITY_CYCLE_DEPTH) return;
|
|
4998
|
+
const visitedKey = `${args.rootTriggerId}::${args.currentTriggerId}::${args.path.join(">")}`;
|
|
4999
|
+
if (args.visited.has(visitedKey)) return;
|
|
5000
|
+
args.visited.add(visitedKey);
|
|
5001
|
+
const revealedFieldIds = (_a = args.revealTargetsByTrigger.get(args.currentTriggerId)) != null ? _a : [];
|
|
5002
|
+
for (const revealedFieldId of revealedFieldIds) {
|
|
5003
|
+
const reachableTriggers = (_c = (_b = args.fieldTriggers.get(revealedFieldId)) == null ? void 0 : _b.slice().sort()) != null ? _c : [];
|
|
5004
|
+
for (const reachableTriggerId of reachableTriggers) {
|
|
5005
|
+
const invalidation = invalidatesRequiredPath(
|
|
5006
|
+
args.v,
|
|
5007
|
+
args.triggerById,
|
|
5008
|
+
reachableTriggerId,
|
|
5009
|
+
args.required
|
|
5010
|
+
);
|
|
5011
|
+
if (invalidation) {
|
|
5012
|
+
emitCycleError({
|
|
5013
|
+
v: args.v,
|
|
5014
|
+
rootTriggerId: args.rootTriggerId,
|
|
5015
|
+
revealedFieldId,
|
|
5016
|
+
conflictingTriggerId: reachableTriggerId,
|
|
5017
|
+
invalidatedId: invalidation.invalidatedId,
|
|
5018
|
+
path: [...args.path, reachableTriggerId],
|
|
5019
|
+
reported: args.reported
|
|
5020
|
+
});
|
|
4727
5021
|
}
|
|
5022
|
+
if (args.path.includes(reachableTriggerId)) continue;
|
|
5023
|
+
walkFromTrigger({
|
|
5024
|
+
...args,
|
|
5025
|
+
currentTriggerId: reachableTriggerId,
|
|
5026
|
+
required: addRequiredTrigger(
|
|
5027
|
+
args.triggerById,
|
|
5028
|
+
args.required,
|
|
5029
|
+
reachableTriggerId
|
|
5030
|
+
),
|
|
5031
|
+
path: [...args.path, reachableTriggerId],
|
|
5032
|
+
depth: args.depth + 1
|
|
5033
|
+
});
|
|
4728
5034
|
}
|
|
4729
|
-
|
|
4730
|
-
|
|
4731
|
-
|
|
4732
|
-
|
|
5035
|
+
}
|
|
5036
|
+
}
|
|
5037
|
+
function makeRequiredState(triggerById, triggerIds) {
|
|
5038
|
+
let required = {
|
|
5039
|
+
triggers: /* @__PURE__ */ new Set(),
|
|
5040
|
+
ownerFields: /* @__PURE__ */ new Set()
|
|
5041
|
+
};
|
|
5042
|
+
for (const triggerId of triggerIds) {
|
|
5043
|
+
required = addRequiredTrigger(triggerById, required, triggerId);
|
|
5044
|
+
}
|
|
5045
|
+
return required;
|
|
5046
|
+
}
|
|
5047
|
+
function addRequiredTrigger(triggerById, current, triggerId) {
|
|
5048
|
+
const next = {
|
|
5049
|
+
triggers: new Set(current.triggers),
|
|
5050
|
+
ownerFields: new Set(current.ownerFields)
|
|
5051
|
+
};
|
|
5052
|
+
const trigger = triggerById.get(triggerId);
|
|
5053
|
+
if (!trigger) return next;
|
|
5054
|
+
next.triggers.add(triggerId);
|
|
5055
|
+
next.ownerFields.add(trigger.ownerFieldId);
|
|
5056
|
+
return next;
|
|
5057
|
+
}
|
|
5058
|
+
function invalidatesRequiredPath(v, triggerById, conflictingTriggerId, required) {
|
|
5059
|
+
var _a, _b, _c, _d, _e, _f;
|
|
5060
|
+
for (const targetId of (_b = (_a = v.props.excludes_for_buttons) == null ? void 0 : _a[conflictingTriggerId]) != null ? _b : []) {
|
|
5061
|
+
if (required.ownerFields.has(targetId)) {
|
|
5062
|
+
return { invalidatedId: targetId };
|
|
5063
|
+
}
|
|
5064
|
+
const targetTrigger = triggerById.get(targetId);
|
|
5065
|
+
if ((targetTrigger == null ? void 0 : targetTrigger.kind) === "option" && required.triggers.has(targetId)) {
|
|
5066
|
+
return { invalidatedId: targetId };
|
|
5067
|
+
}
|
|
5068
|
+
}
|
|
5069
|
+
const effects = (_d = (_c = v.props.option_effects_for_buttons) == null ? void 0 : _c[conflictingTriggerId]) != null ? _d : {};
|
|
5070
|
+
for (const [targetFieldId, effect] of Object.entries(effects)) {
|
|
5071
|
+
if (!v.fieldById.has(targetFieldId)) continue;
|
|
5072
|
+
if ((_e = effect == null ? void 0 : effect.exclude) == null ? void 0 : _e.length) {
|
|
5073
|
+
const excluded = new Set(effect.exclude);
|
|
5074
|
+
for (const requiredTriggerId of required.triggers) {
|
|
5075
|
+
const requiredTrigger = triggerById.get(requiredTriggerId);
|
|
5076
|
+
if ((requiredTrigger == null ? void 0 : requiredTrigger.kind) !== "option") continue;
|
|
5077
|
+
if (requiredTrigger.ownerFieldId !== targetFieldId) continue;
|
|
5078
|
+
if (excluded.has(requiredTriggerId)) {
|
|
5079
|
+
return { invalidatedId: requiredTriggerId };
|
|
5080
|
+
}
|
|
5081
|
+
}
|
|
5082
|
+
}
|
|
5083
|
+
if ((_f = effect == null ? void 0 : effect.include) == null ? void 0 : _f.length) {
|
|
5084
|
+
const included = new Set(effect.include);
|
|
5085
|
+
for (const requiredTriggerId of required.triggers) {
|
|
5086
|
+
const requiredTrigger = triggerById.get(requiredTriggerId);
|
|
5087
|
+
if ((requiredTrigger == null ? void 0 : requiredTrigger.kind) !== "option") continue;
|
|
5088
|
+
if (requiredTrigger.ownerFieldId !== targetFieldId) continue;
|
|
5089
|
+
if (!included.has(requiredTriggerId)) {
|
|
5090
|
+
return { invalidatedId: requiredTriggerId };
|
|
5091
|
+
}
|
|
4733
5092
|
}
|
|
4734
5093
|
}
|
|
4735
|
-
return void 0;
|
|
4736
5094
|
}
|
|
5095
|
+
return void 0;
|
|
5096
|
+
}
|
|
5097
|
+
function emitCycleError(args) {
|
|
5098
|
+
const key = [
|
|
5099
|
+
args.rootTriggerId,
|
|
5100
|
+
args.conflictingTriggerId,
|
|
5101
|
+
args.invalidatedId,
|
|
5102
|
+
args.path.join(">")
|
|
5103
|
+
].join("::");
|
|
5104
|
+
if (args.reported.has(key)) return;
|
|
5105
|
+
args.reported.add(key);
|
|
5106
|
+
args.v.errors.push({
|
|
5107
|
+
code: "visibility_dependency_cycle",
|
|
5108
|
+
severity: "error",
|
|
5109
|
+
message: `Visibility dependency cycle: trigger "${args.rootTriggerId}" reveals "${args.revealedFieldId}", but reachable trigger "${args.conflictingTriggerId}" can hide or remove "${args.invalidatedId}".`,
|
|
5110
|
+
nodeId: args.conflictingTriggerId,
|
|
5111
|
+
details: withAffected(
|
|
5112
|
+
{
|
|
5113
|
+
rootTriggerId: args.rootTriggerId,
|
|
5114
|
+
conflictingTriggerId: args.conflictingTriggerId,
|
|
5115
|
+
invalidatedId: args.invalidatedId,
|
|
5116
|
+
path: args.path
|
|
5117
|
+
},
|
|
5118
|
+
[
|
|
5119
|
+
args.rootTriggerId,
|
|
5120
|
+
args.revealedFieldId,
|
|
5121
|
+
args.conflictingTriggerId,
|
|
5122
|
+
args.invalidatedId
|
|
5123
|
+
]
|
|
5124
|
+
)
|
|
5125
|
+
});
|
|
5126
|
+
}
|
|
5127
|
+
|
|
5128
|
+
// src/utils/order-kind.ts
|
|
5129
|
+
function normalizeSelectedTriggerKey(key, nodeMap) {
|
|
5130
|
+
if (!key) return void 0;
|
|
4737
5131
|
const ref = nodeMap.get(key);
|
|
4738
5132
|
if (!ref) return void 0;
|
|
4739
5133
|
if (ref.kind !== "field" && ref.kind !== "option") return void 0;
|
|
@@ -4892,8 +5286,7 @@ function validateUtilityMarkers(v) {
|
|
|
4892
5286
|
"percent"
|
|
4893
5287
|
]);
|
|
4894
5288
|
for (const f of v.fields) {
|
|
4895
|
-
const
|
|
4896
|
-
for (const o of optsArr) {
|
|
5289
|
+
for (const { option: o } of walkFieldOptions(f)) {
|
|
4897
5290
|
const role = (_b = (_a = o.pricing_role) != null ? _a : f.pricing_role) != null ? _b : "base";
|
|
4898
5291
|
const hasService = isServiceIdRef(o.service_id);
|
|
4899
5292
|
const util = (_c = o.meta) == null ? void 0 : _c.utility;
|
|
@@ -5115,13 +5508,13 @@ function normalizeServiceRef(value) {
|
|
|
5115
5508
|
|
|
5116
5509
|
// src/core/validate/steps/rates.ts
|
|
5117
5510
|
function validateRates(v) {
|
|
5118
|
-
var _a, _b
|
|
5511
|
+
var _a, _b;
|
|
5119
5512
|
const ratePolicy = normalizeRatePolicy(v.options.ratePolicy);
|
|
5120
5513
|
for (const f of v.fields) {
|
|
5121
5514
|
if (!isMultiField(f)) continue;
|
|
5122
5515
|
const baseRates = [];
|
|
5123
|
-
for (const o of (
|
|
5124
|
-
const role = (
|
|
5516
|
+
for (const { option: o } of walkFieldOptions(f)) {
|
|
5517
|
+
const role = (_b = (_a = o.pricing_role) != null ? _a : f.pricing_role) != null ? _b : "base";
|
|
5125
5518
|
if (role !== "base") continue;
|
|
5126
5519
|
const sid = o.service_id;
|
|
5127
5520
|
if (!isServiceIdRef(sid)) continue;
|
|
@@ -5532,7 +5925,7 @@ function effectiveConstraints(v, tagId) {
|
|
|
5532
5925
|
return out;
|
|
5533
5926
|
}
|
|
5534
5927
|
function validateConstraints(v) {
|
|
5535
|
-
var _a
|
|
5928
|
+
var _a;
|
|
5536
5929
|
for (const t of v.tags) {
|
|
5537
5930
|
const eff = effectiveConstraints(v, t.id);
|
|
5538
5931
|
const hasAnyRequired = Object.values(eff).some(
|
|
@@ -5541,7 +5934,7 @@ function validateConstraints(v) {
|
|
|
5541
5934
|
if (!hasAnyRequired) continue;
|
|
5542
5935
|
const visible = v.fieldsVisibleUnder(t.id);
|
|
5543
5936
|
for (const f of visible) {
|
|
5544
|
-
for (const o of (
|
|
5937
|
+
for (const { option: o } of walkFieldOptions(f)) {
|
|
5545
5938
|
if (!isServiceIdRef(o.service_id)) continue;
|
|
5546
5939
|
const svc = getServiceCapability(v.serviceMap, o.service_id);
|
|
5547
5940
|
if (!svc || typeof svc !== "object") continue;
|
|
@@ -5595,7 +5988,7 @@ function validateConstraints(v) {
|
|
|
5595
5988
|
if (!row) continue;
|
|
5596
5989
|
const from = row.from === true;
|
|
5597
5990
|
const to = row.to === true;
|
|
5598
|
-
const origin = String((
|
|
5991
|
+
const origin = String((_a = row.origin) != null ? _a : "");
|
|
5599
5992
|
v.errors.push({
|
|
5600
5993
|
code: "constraint_overridden",
|
|
5601
5994
|
severity: "warning",
|
|
@@ -5629,14 +6022,14 @@ function validateCustomFields(v) {
|
|
|
5629
6022
|
|
|
5630
6023
|
// src/core/validate/steps/global-utility-guard.ts
|
|
5631
6024
|
function validateGlobalUtilityGuard(v) {
|
|
5632
|
-
var _a, _b
|
|
6025
|
+
var _a, _b;
|
|
5633
6026
|
if (!v.options.globalUtilityGuard) return;
|
|
5634
6027
|
let hasUtility = false;
|
|
5635
6028
|
let hasBase = false;
|
|
5636
6029
|
for (const f of v.fields) {
|
|
5637
|
-
for (const o of (
|
|
6030
|
+
for (const { option: o } of walkFieldOptions(f)) {
|
|
5638
6031
|
if (!isServiceIdRef(o.service_id)) continue;
|
|
5639
|
-
const role = (
|
|
6032
|
+
const role = (_b = (_a = o.pricing_role) != null ? _a : f.pricing_role) != null ? _b : "base";
|
|
5640
6033
|
if (role === "base") hasBase = true;
|
|
5641
6034
|
else if (role === "utility") hasUtility = true;
|
|
5642
6035
|
if (hasUtility && hasBase) break;
|
|
@@ -5838,7 +6231,7 @@ function applyFilterAllowLists(tagId, fieldId, filter) {
|
|
|
5838
6231
|
return true;
|
|
5839
6232
|
}
|
|
5840
6233
|
function collectServiceItems(args) {
|
|
5841
|
-
var _a, _b, _c, _d
|
|
6234
|
+
var _a, _b, _c, _d;
|
|
5842
6235
|
const filter = args.filter;
|
|
5843
6236
|
const roleFilter = (_a = filter == null ? void 0 : filter.role) != null ? _a : "both";
|
|
5844
6237
|
const where = filter == null ? void 0 : filter.where;
|
|
@@ -5888,7 +6281,7 @@ function collectServiceItems(args) {
|
|
|
5888
6281
|
affectedIds: [`field:${f.id}`, `service:${String(fSid)}`]
|
|
5889
6282
|
});
|
|
5890
6283
|
}
|
|
5891
|
-
for (const o of (
|
|
6284
|
+
for (const { option: o } of walkFieldOptions(f)) {
|
|
5892
6285
|
const oSid = o.service_id;
|
|
5893
6286
|
if (!isServiceIdRef2(oSid)) continue;
|
|
5894
6287
|
const role = fieldRoleOf(f, o);
|
|
@@ -5973,7 +6366,7 @@ function collectServiceItems(args) {
|
|
|
5973
6366
|
}
|
|
5974
6367
|
} else if (includeGroupFallbacks) {
|
|
5975
6368
|
const allowPrimaries = new Set(
|
|
5976
|
-
((
|
|
6369
|
+
((_d = args.visiblePrimaries) != null ? _d : []).map((x) => String(x))
|
|
5977
6370
|
);
|
|
5978
6371
|
for (const primaryKey of allowPrimaries) {
|
|
5979
6372
|
const list = globalFb[primaryKey];
|
|
@@ -6054,17 +6447,15 @@ function affectedFromItems(items) {
|
|
|
6054
6447
|
return uniq(ids);
|
|
6055
6448
|
}
|
|
6056
6449
|
function visibleGroupNodeIds(tag, fields) {
|
|
6057
|
-
var _a;
|
|
6058
6450
|
const ids = [tag.id];
|
|
6059
6451
|
for (const f of fields) {
|
|
6060
|
-
for (const o of (
|
|
6452
|
+
for (const { option: o } of walkFieldOptions(f)) {
|
|
6061
6453
|
ids.push(o.id);
|
|
6062
6454
|
}
|
|
6063
6455
|
}
|
|
6064
6456
|
return uniq(ids);
|
|
6065
6457
|
}
|
|
6066
6458
|
function visibleGroupPrimaries(tag, fields) {
|
|
6067
|
-
var _a;
|
|
6068
6459
|
const prim = [];
|
|
6069
6460
|
const tagSid = tag.service_id;
|
|
6070
6461
|
if (typeof tagSid === "string" || typeof tagSid === "number" && Number.isFinite(tagSid)) {
|
|
@@ -6075,7 +6466,7 @@ function visibleGroupPrimaries(tag, fields) {
|
|
|
6075
6466
|
if (typeof fsid === "string" || typeof fsid === "number" && Number.isFinite(fsid)) {
|
|
6076
6467
|
prim.push(fsid);
|
|
6077
6468
|
}
|
|
6078
|
-
for (const o of (
|
|
6469
|
+
for (const { option: o } of walkFieldOptions(f)) {
|
|
6079
6470
|
const osid = o.service_id;
|
|
6080
6471
|
if (typeof osid === "string" || typeof osid === "number" && Number.isFinite(osid)) {
|
|
6081
6472
|
prim.push(osid);
|
|
@@ -6299,6 +6690,7 @@ function validate(props, ctx = {}) {
|
|
|
6299
6690
|
validateStructure(v);
|
|
6300
6691
|
validateIdentity(v);
|
|
6301
6692
|
validateOptionMaps(v);
|
|
6693
|
+
validateVisibilityCycles(v);
|
|
6302
6694
|
validateOrderKinds(v);
|
|
6303
6695
|
v.fieldsVisibleUnder = createFieldsVisibleUnder(v);
|
|
6304
6696
|
const visSim = readVisibilitySimOpts(options);
|
|
@@ -6432,14 +6824,14 @@ var BuilderImpl = class {
|
|
|
6432
6824
|
const showOptions = showSet.has(f.id);
|
|
6433
6825
|
if (!showOptions) continue;
|
|
6434
6826
|
if (!Array.isArray(f.options)) continue;
|
|
6435
|
-
for (const o of f
|
|
6827
|
+
for (const { option: o, parentId } of walkFieldOptions(f)) {
|
|
6436
6828
|
nodes.push({
|
|
6437
6829
|
id: o.id,
|
|
6438
6830
|
kind: "option",
|
|
6439
6831
|
label: o.label
|
|
6440
6832
|
});
|
|
6441
6833
|
const e = {
|
|
6442
|
-
from: f.id,
|
|
6834
|
+
from: parentId != null ? parentId : f.id,
|
|
6443
6835
|
to: o.id,
|
|
6444
6836
|
kind: "option",
|
|
6445
6837
|
meta: { ownerField: f.id }
|
|
@@ -6486,7 +6878,7 @@ var BuilderImpl = class {
|
|
|
6486
6878
|
return { nodes, edges };
|
|
6487
6879
|
}
|
|
6488
6880
|
cleanedProps() {
|
|
6489
|
-
var _a, _b, _c, _d, _e;
|
|
6881
|
+
var _a, _b, _c, _d, _e, _f;
|
|
6490
6882
|
const fieldIds = new Set(this.props.fields.map((f) => f.id));
|
|
6491
6883
|
const optionIds = /* @__PURE__ */ new Set();
|
|
6492
6884
|
this.optionOwnerById.forEach((_v, oid) => optionIds.add(oid));
|
|
@@ -6498,6 +6890,7 @@ var BuilderImpl = class {
|
|
|
6498
6890
|
}
|
|
6499
6891
|
const incMap = (_c = this.props.includes_for_buttons) != null ? _c : {};
|
|
6500
6892
|
const excMap = (_d = this.props.excludes_for_buttons) != null ? _d : {};
|
|
6893
|
+
const effectMap = (_e = this.props.option_effects_for_buttons) != null ? _e : {};
|
|
6501
6894
|
const includedByButtons = /* @__PURE__ */ new Set();
|
|
6502
6895
|
const referencedKeys = /* @__PURE__ */ new Set();
|
|
6503
6896
|
const referencedOwnerFields = /* @__PURE__ */ new Set();
|
|
@@ -6517,6 +6910,14 @@ var BuilderImpl = class {
|
|
|
6517
6910
|
void fid;
|
|
6518
6911
|
}
|
|
6519
6912
|
}
|
|
6913
|
+
for (const [key, targets] of Object.entries(effectMap)) {
|
|
6914
|
+
referencedKeys.add(key);
|
|
6915
|
+
const owner = this.optionOwnerById.get(key);
|
|
6916
|
+
if (owner) referencedOwnerFields.add(owner.fieldId);
|
|
6917
|
+
for (const [fid, effect] of Object.entries(targets != null ? targets : {})) {
|
|
6918
|
+
if ((effect == null ? void 0 : effect.forceVisible) === true) includedByButtons.add(fid);
|
|
6919
|
+
}
|
|
6920
|
+
}
|
|
6520
6921
|
const boundIds = /* @__PURE__ */ new Set();
|
|
6521
6922
|
for (const f of this.props.fields) {
|
|
6522
6923
|
const b = f.bind_id;
|
|
@@ -6534,6 +6935,7 @@ var BuilderImpl = class {
|
|
|
6534
6935
|
return bound || included || referenced || !excluded;
|
|
6535
6936
|
});
|
|
6536
6937
|
const allowedTargets = new Set(fields.map((f) => f.id));
|
|
6938
|
+
const allowedFieldById = new Map(fields.map((f) => [f.id, f]));
|
|
6537
6939
|
const pruneButtons = (src) => {
|
|
6538
6940
|
if (!src) return void 0;
|
|
6539
6941
|
const out2 = {};
|
|
@@ -6553,13 +6955,52 @@ var BuilderImpl = class {
|
|
|
6553
6955
|
const excludes_for_buttons = pruneButtons(
|
|
6554
6956
|
this.props.excludes_for_buttons
|
|
6555
6957
|
);
|
|
6958
|
+
const pruneOptionEffects = (src) => {
|
|
6959
|
+
var _a2, _b2, _c2, _d2;
|
|
6960
|
+
if (!src) return void 0;
|
|
6961
|
+
const out2 = {};
|
|
6962
|
+
for (const [key, targets] of Object.entries(src)) {
|
|
6963
|
+
const keyIsValid = optionIds.has(key) || fieldIds.has(key);
|
|
6964
|
+
if (!keyIsValid) continue;
|
|
6965
|
+
const cleanedTargets = {};
|
|
6966
|
+
for (const [targetFieldId, effect] of Object.entries(
|
|
6967
|
+
targets != null ? targets : {}
|
|
6968
|
+
)) {
|
|
6969
|
+
const field = allowedFieldById.get(targetFieldId);
|
|
6970
|
+
if (!field || !effect) continue;
|
|
6971
|
+
const validOptionIds = fieldOptionIdSet(field);
|
|
6972
|
+
const include2 = Array.from(
|
|
6973
|
+
new Set((_a2 = effect.include) != null ? _a2 : [])
|
|
6974
|
+
).filter((optionId) => validOptionIds.has(optionId));
|
|
6975
|
+
const exclude2 = Array.from(
|
|
6976
|
+
new Set((_b2 = effect.exclude) != null ? _b2 : [])
|
|
6977
|
+
).filter((optionId) => validOptionIds.has(optionId));
|
|
6978
|
+
const next = {
|
|
6979
|
+
...effect.forceVisible === true ? { forceVisible: true } : {},
|
|
6980
|
+
...include2.length ? { include: include2 } : {},
|
|
6981
|
+
...exclude2.length ? { exclude: exclude2 } : {}
|
|
6982
|
+
};
|
|
6983
|
+
if (next.forceVisible === true || ((_c2 = next.include) == null ? void 0 : _c2.length) || ((_d2 = next.exclude) == null ? void 0 : _d2.length)) {
|
|
6984
|
+
cleanedTargets[targetFieldId] = next;
|
|
6985
|
+
}
|
|
6986
|
+
}
|
|
6987
|
+
if (Object.keys(cleanedTargets).length) {
|
|
6988
|
+
out2[key] = cleanedTargets;
|
|
6989
|
+
}
|
|
6990
|
+
}
|
|
6991
|
+
return Object.keys(out2).length ? out2 : void 0;
|
|
6992
|
+
};
|
|
6993
|
+
const option_effects_for_buttons = pruneOptionEffects(
|
|
6994
|
+
this.props.option_effects_for_buttons
|
|
6995
|
+
);
|
|
6556
6996
|
const out = {
|
|
6557
6997
|
filters: this.props.filters.slice(),
|
|
6558
6998
|
fields,
|
|
6559
6999
|
...this.props.orderKinds ? { orderKinds: this.props.orderKinds } : {},
|
|
6560
7000
|
...includes_for_buttons && { includes_for_buttons },
|
|
6561
7001
|
...excludes_for_buttons && { excludes_for_buttons },
|
|
6562
|
-
|
|
7002
|
+
...option_effects_for_buttons && { option_effects_for_buttons },
|
|
7003
|
+
schema_version: (_f = this.props.schema_version) != null ? _f : "1.0",
|
|
6563
7004
|
// keep fallbacks & other maps as-is
|
|
6564
7005
|
...this.props.fallbacks ? { fallbacks: this.props.fallbacks } : {}
|
|
6565
7006
|
};
|
|
@@ -6572,12 +7013,15 @@ var BuilderImpl = class {
|
|
|
6572
7013
|
return (0, import_lodash_es2.cloneDeep)(this.options);
|
|
6573
7014
|
}
|
|
6574
7015
|
visibleFields(tagId, selectedKeys) {
|
|
7016
|
+
return this.resolveVisibility(tagId, selectedKeys).fieldIds;
|
|
7017
|
+
}
|
|
7018
|
+
resolveVisibility(tagId, selectedKeys) {
|
|
6575
7019
|
var _a;
|
|
6576
|
-
return
|
|
6577
|
-
|
|
6578
|
-
|
|
6579
|
-
)
|
|
6580
|
-
|
|
7020
|
+
return resolveVisibility(
|
|
7021
|
+
this.props,
|
|
7022
|
+
tagId,
|
|
7023
|
+
(_a = selectedKeys != null ? selectedKeys : this.options.selectedOptionKeys) != null ? _a : []
|
|
7024
|
+
);
|
|
6581
7025
|
}
|
|
6582
7026
|
getNodeMap() {
|
|
6583
7027
|
if (!this._nodemap) this._nodemap = buildNodeMap(this.getProps());
|
|
@@ -6592,9 +7036,8 @@ var BuilderImpl = class {
|
|
|
6592
7036
|
for (const t of this.props.filters) this.tagById.set(t.id, t);
|
|
6593
7037
|
for (const f of this.props.fields) {
|
|
6594
7038
|
this.fieldById.set(f.id, f);
|
|
6595
|
-
|
|
6596
|
-
|
|
6597
|
-
this.optionOwnerById.set(o.id, { fieldId: f.id });
|
|
7039
|
+
for (const [optionId, owner] of optionOwnerMap([f])) {
|
|
7040
|
+
this.optionOwnerById.set(optionId, { fieldId: owner.fieldId });
|
|
6598
7041
|
}
|
|
6599
7042
|
}
|
|
6600
7043
|
}
|
|
@@ -7542,44 +7985,135 @@ function bumpSuffix(old) {
|
|
|
7542
7985
|
return `${stem}${parseInt(m[2], 10) + 1}`;
|
|
7543
7986
|
}
|
|
7544
7987
|
|
|
7545
|
-
// src/react/canvas/editor/editor-
|
|
7546
|
-
function
|
|
7547
|
-
|
|
7548
|
-
|
|
7549
|
-
|
|
7550
|
-
|
|
7551
|
-
newId2 = duplicateInPlace(ctx, ref, opts);
|
|
7552
|
-
});
|
|
7553
|
-
return newId2;
|
|
7554
|
-
} catch (err) {
|
|
7555
|
-
ctx.loadSnapshot(snapBefore, "undo");
|
|
7556
|
-
throw err;
|
|
7988
|
+
// src/react/canvas/editor/editor-utils.ts
|
|
7989
|
+
function ownerOfOption(props, optionId) {
|
|
7990
|
+
var _a;
|
|
7991
|
+
for (const f of (_a = props.fields) != null ? _a : []) {
|
|
7992
|
+
const found = findOptionLocationInField(f, optionId);
|
|
7993
|
+
if (found) return { fieldId: f.id, index: found.index };
|
|
7557
7994
|
}
|
|
7995
|
+
return null;
|
|
7558
7996
|
}
|
|
7559
|
-
function
|
|
7560
|
-
|
|
7561
|
-
|
|
7562
|
-
|
|
7563
|
-
|
|
7564
|
-
|
|
7565
|
-
|
|
7566
|
-
|
|
7567
|
-
|
|
7568
|
-
|
|
7569
|
-
|
|
7570
|
-
|
|
7571
|
-
|
|
7572
|
-
|
|
7573
|
-
|
|
7574
|
-
|
|
7575
|
-
|
|
7576
|
-
|
|
7577
|
-
|
|
7578
|
-
|
|
7579
|
-
|
|
7580
|
-
|
|
7581
|
-
|
|
7582
|
-
|
|
7997
|
+
function findMutableOption(props, optionId) {
|
|
7998
|
+
var _a;
|
|
7999
|
+
for (const field of (_a = props.fields) != null ? _a : []) {
|
|
8000
|
+
const found = findOptionLocationInField(field, optionId);
|
|
8001
|
+
if (found) return { field, ...found };
|
|
8002
|
+
}
|
|
8003
|
+
return void 0;
|
|
8004
|
+
}
|
|
8005
|
+
function collectFieldOptionIds(field) {
|
|
8006
|
+
const out = [];
|
|
8007
|
+
const visit = (options) => {
|
|
8008
|
+
for (const option of options != null ? options : []) {
|
|
8009
|
+
out.push(String(option.id));
|
|
8010
|
+
visit(option.children);
|
|
8011
|
+
}
|
|
8012
|
+
};
|
|
8013
|
+
visit(field == null ? void 0 : field.options);
|
|
8014
|
+
return out;
|
|
8015
|
+
}
|
|
8016
|
+
function findOptionLocationInField(field, optionId) {
|
|
8017
|
+
const visit = (siblings, parent) => {
|
|
8018
|
+
if (!siblings) return void 0;
|
|
8019
|
+
const index = siblings.findIndex((option) => option.id === optionId);
|
|
8020
|
+
if (index >= 0) {
|
|
8021
|
+
return {
|
|
8022
|
+
option: siblings[index],
|
|
8023
|
+
siblings,
|
|
8024
|
+
index,
|
|
8025
|
+
parent
|
|
8026
|
+
};
|
|
8027
|
+
}
|
|
8028
|
+
for (const option of siblings) {
|
|
8029
|
+
const found = visit(option.children, option);
|
|
8030
|
+
if (found) return found;
|
|
8031
|
+
}
|
|
8032
|
+
return void 0;
|
|
8033
|
+
};
|
|
8034
|
+
return visit(field.options);
|
|
8035
|
+
}
|
|
8036
|
+
function hasFieldOptions(field) {
|
|
8037
|
+
return Array.isArray(field == null ? void 0 : field.options) && field.options.length > 0;
|
|
8038
|
+
}
|
|
8039
|
+
function isActualButtonField(field) {
|
|
8040
|
+
return (field == null ? void 0 : field.button) === true && !hasFieldOptions(field);
|
|
8041
|
+
}
|
|
8042
|
+
function clearFieldButtonReceiverMaps(props, fieldId) {
|
|
8043
|
+
var _a, _b, _c;
|
|
8044
|
+
if ((_a = props.includes_for_buttons) == null ? void 0 : _a[fieldId]) {
|
|
8045
|
+
delete props.includes_for_buttons[fieldId];
|
|
8046
|
+
}
|
|
8047
|
+
if ((_b = props.excludes_for_buttons) == null ? void 0 : _b[fieldId]) {
|
|
8048
|
+
delete props.excludes_for_buttons[fieldId];
|
|
8049
|
+
}
|
|
8050
|
+
if (props.includes_for_buttons && Object.keys(props.includes_for_buttons).length === 0) {
|
|
8051
|
+
delete props.includes_for_buttons;
|
|
8052
|
+
}
|
|
8053
|
+
if (props.excludes_for_buttons && Object.keys(props.excludes_for_buttons).length === 0) {
|
|
8054
|
+
delete props.excludes_for_buttons;
|
|
8055
|
+
}
|
|
8056
|
+
if ((_c = props.option_effects_for_buttons) == null ? void 0 : _c[fieldId]) {
|
|
8057
|
+
delete props.option_effects_for_buttons[fieldId];
|
|
8058
|
+
}
|
|
8059
|
+
if (props.option_effects_for_buttons && Object.keys(props.option_effects_for_buttons).length === 0) {
|
|
8060
|
+
delete props.option_effects_for_buttons;
|
|
8061
|
+
}
|
|
8062
|
+
}
|
|
8063
|
+
function ensureServiceExists(opts, id) {
|
|
8064
|
+
if (typeof opts.serviceExists === "function") {
|
|
8065
|
+
if (!opts.serviceExists(id)) {
|
|
8066
|
+
throw new Error(`service_not_found:${String(id)}`);
|
|
8067
|
+
}
|
|
8068
|
+
return;
|
|
8069
|
+
}
|
|
8070
|
+
if (opts.serviceMap) {
|
|
8071
|
+
if (!Object.prototype.hasOwnProperty.call(opts.serviceMap, id)) {
|
|
8072
|
+
throw new Error(`service_not_found:${String(id)}`);
|
|
8073
|
+
}
|
|
8074
|
+
return;
|
|
8075
|
+
}
|
|
8076
|
+
throw new Error("service_checker_missing");
|
|
8077
|
+
}
|
|
8078
|
+
|
|
8079
|
+
// src/react/canvas/editor/editor-duplicate.ts
|
|
8080
|
+
function duplicate(ctx, ref, opts = {}) {
|
|
8081
|
+
const snapBefore = ctx.makeSnapshot("duplicate:before");
|
|
8082
|
+
try {
|
|
8083
|
+
let newId2 = "";
|
|
8084
|
+
ctx.transact("duplicate", () => {
|
|
8085
|
+
newId2 = duplicateInPlace(ctx, ref, opts);
|
|
8086
|
+
});
|
|
8087
|
+
return newId2;
|
|
8088
|
+
} catch (err) {
|
|
8089
|
+
ctx.loadSnapshot(snapBefore, "undo");
|
|
8090
|
+
throw err;
|
|
8091
|
+
}
|
|
8092
|
+
}
|
|
8093
|
+
function duplicateMany(ctx, ids, opts = {}) {
|
|
8094
|
+
const ordered = Array.from(new Set((ids != null ? ids : []).map((id) => String(id))));
|
|
8095
|
+
if (!ordered.length) return [];
|
|
8096
|
+
const snapBefore = ctx.makeSnapshot("duplicateMany:before");
|
|
8097
|
+
try {
|
|
8098
|
+
const created = [];
|
|
8099
|
+
ctx.transact("duplicateMany", () => {
|
|
8100
|
+
var _a, _b, _c;
|
|
8101
|
+
const props = ctx.getProps();
|
|
8102
|
+
const selectedFields = /* @__PURE__ */ new Set();
|
|
8103
|
+
for (const id of ordered) {
|
|
8104
|
+
if (ctx.isFieldId(id) && ((_a = props.fields) != null ? _a : []).some((f) => f.id === id)) {
|
|
8105
|
+
selectedFields.add(id);
|
|
8106
|
+
}
|
|
8107
|
+
}
|
|
8108
|
+
for (const id of ordered) {
|
|
8109
|
+
if (ctx.isTagId(id)) {
|
|
8110
|
+
if (!((_b = ctx.getProps().filters) != null ? _b : []).some((t) => t.id === id)) continue;
|
|
8111
|
+
created.push(
|
|
8112
|
+
duplicateInPlace(ctx, { kind: "tag", id }, opts)
|
|
8113
|
+
);
|
|
8114
|
+
continue;
|
|
8115
|
+
}
|
|
8116
|
+
if (ctx.isFieldId(id)) {
|
|
7583
8117
|
if (!((_c = ctx.getProps().fields) != null ? _c : []).some((f) => f.id === id)) continue;
|
|
7584
8118
|
created.push(
|
|
7585
8119
|
duplicateInPlace(ctx, { kind: "field", id }, opts)
|
|
@@ -7616,14 +8150,66 @@ function duplicateInPlace(ctx, ref, opts = {}) {
|
|
|
7616
8150
|
return duplicateOption(ctx, ref.fieldId, ref.id, opts);
|
|
7617
8151
|
}
|
|
7618
8152
|
function ownerFieldOfOption(props, optionId) {
|
|
7619
|
-
var _a
|
|
8153
|
+
var _a;
|
|
7620
8154
|
for (const field of (_a = props.fields) != null ? _a : []) {
|
|
7621
|
-
if ((
|
|
8155
|
+
if (findMutableOption({ ...props, fields: [field] }, optionId)) {
|
|
7622
8156
|
return { fieldId: field.id };
|
|
7623
8157
|
}
|
|
7624
8158
|
}
|
|
7625
8159
|
return null;
|
|
7626
8160
|
}
|
|
8161
|
+
function cloneOptionTree(ctx, fieldId, option, opts, optionIdMap) {
|
|
8162
|
+
var _a, _b, _c, _d;
|
|
8163
|
+
const newId2 = ctx.uniqueOptionId(
|
|
8164
|
+
fieldId,
|
|
8165
|
+
((_a = opts.optionIdStrategy) != null ? _a : defaultOptionIdStrategy)(option.id)
|
|
8166
|
+
);
|
|
8167
|
+
optionIdMap.set(option.id, newId2);
|
|
8168
|
+
const children = (_b = option.children) == null ? void 0 : _b.map(
|
|
8169
|
+
(child) => cloneOptionTree(ctx, fieldId, child, opts, optionIdMap)
|
|
8170
|
+
);
|
|
8171
|
+
return {
|
|
8172
|
+
...option,
|
|
8173
|
+
id: newId2,
|
|
8174
|
+
label: ((_c = opts.labelStrategy) != null ? _c : nextCopyLabel)((_d = option.label) != null ? _d : option.id),
|
|
8175
|
+
...(children == null ? void 0 : children.length) ? { children } : {}
|
|
8176
|
+
};
|
|
8177
|
+
}
|
|
8178
|
+
function remapEffect(effect, optionIdMap) {
|
|
8179
|
+
const remapList = (values) => values == null ? void 0 : values.map((value) => {
|
|
8180
|
+
var _a;
|
|
8181
|
+
return (_a = optionIdMap.get(value)) != null ? _a : value;
|
|
8182
|
+
});
|
|
8183
|
+
return {
|
|
8184
|
+
...effect,
|
|
8185
|
+
...effect.include ? { include: remapList(effect.include) } : {},
|
|
8186
|
+
...effect.exclude ? { exclude: remapList(effect.exclude) } : {}
|
|
8187
|
+
};
|
|
8188
|
+
}
|
|
8189
|
+
function copyOptionEffects(props, args) {
|
|
8190
|
+
var _a, _b, _c, _d, _e;
|
|
8191
|
+
const source = props.option_effects_for_buttons;
|
|
8192
|
+
if (!source) return;
|
|
8193
|
+
const next = {
|
|
8194
|
+
...source
|
|
8195
|
+
};
|
|
8196
|
+
const triggerIdMap = (_a = args.triggerIdMap) != null ? _a : /* @__PURE__ */ new Map();
|
|
8197
|
+
const targetFieldIdMap = (_b = args.targetFieldIdMap) != null ? _b : /* @__PURE__ */ new Map();
|
|
8198
|
+
const optionIdMap = (_c = args.optionIdMap) != null ? _c : /* @__PURE__ */ new Map();
|
|
8199
|
+
for (const [oldTriggerId, targetMap] of Object.entries(source)) {
|
|
8200
|
+
const newTriggerId = triggerIdMap.get(oldTriggerId);
|
|
8201
|
+
if (!newTriggerId) continue;
|
|
8202
|
+
const copiedTargets = {
|
|
8203
|
+
...(_d = next[newTriggerId]) != null ? _d : {}
|
|
8204
|
+
};
|
|
8205
|
+
for (const [oldTargetFieldId, effect] of Object.entries(targetMap != null ? targetMap : {})) {
|
|
8206
|
+
const newTargetFieldId = (_e = targetFieldIdMap.get(oldTargetFieldId)) != null ? _e : oldTargetFieldId;
|
|
8207
|
+
copiedTargets[newTargetFieldId] = remapEffect(effect, optionIdMap);
|
|
8208
|
+
}
|
|
8209
|
+
next[newTriggerId] = copiedTargets;
|
|
8210
|
+
}
|
|
8211
|
+
props.option_effects_for_buttons = next;
|
|
8212
|
+
}
|
|
7627
8213
|
function duplicateTag(ctx, tagId, opts) {
|
|
7628
8214
|
var _a, _b, _c, _d;
|
|
7629
8215
|
const props = ctx.getProps();
|
|
@@ -7679,7 +8265,7 @@ function duplicateTag(ctx, tagId, opts) {
|
|
|
7679
8265
|
return id;
|
|
7680
8266
|
}
|
|
7681
8267
|
function duplicateField(ctx, fieldId, opts) {
|
|
7682
|
-
var _a, _b, _c, _d, _e, _f
|
|
8268
|
+
var _a, _b, _c, _d, _e, _f;
|
|
7683
8269
|
const props = ctx.getProps();
|
|
7684
8270
|
const fields = (_a = props.fields) != null ? _a : [];
|
|
7685
8271
|
const src = fields.find((f) => f.id === fieldId);
|
|
@@ -7687,21 +8273,10 @@ function duplicateField(ctx, fieldId, opts) {
|
|
|
7687
8273
|
const id = (_b = opts.id) != null ? _b : ctx.uniqueId(src.id);
|
|
7688
8274
|
const label = ((_c = opts.labelStrategy) != null ? _c : nextCopyLabel)((_d = src.label) != null ? _d : id);
|
|
7689
8275
|
const name = opts.nameStrategy ? opts.nameStrategy(src.name) : nextCopyName(src.name);
|
|
7690
|
-
const
|
|
7691
|
-
|
|
7692
|
-
|
|
7693
|
-
|
|
7694
|
-
((_a2 = opts.optionIdStrategy) != null ? _a2 : defaultOptionIdStrategy)(old)
|
|
7695
|
-
);
|
|
7696
|
-
};
|
|
7697
|
-
const clonedOptions = ((_e = src.options) != null ? _e : []).map((o) => {
|
|
7698
|
-
var _a2, _b2;
|
|
7699
|
-
return {
|
|
7700
|
-
...o,
|
|
7701
|
-
id: optId(o.id),
|
|
7702
|
-
label: ((_a2 = opts.labelStrategy) != null ? _a2 : nextCopyLabel)((_b2 = o.label) != null ? _b2 : o.id)
|
|
7703
|
-
};
|
|
7704
|
-
});
|
|
8276
|
+
const optionIdMap = /* @__PURE__ */ new Map();
|
|
8277
|
+
const clonedOptions = ((_e = src.options) != null ? _e : []).map(
|
|
8278
|
+
(o) => cloneOptionTree(ctx, id, o, opts, optionIdMap)
|
|
8279
|
+
);
|
|
7705
8280
|
const cloned = {
|
|
7706
8281
|
...src,
|
|
7707
8282
|
id,
|
|
@@ -7710,14 +8285,8 @@ function duplicateField(ctx, fieldId, opts) {
|
|
|
7710
8285
|
bind_id: ((_f = opts.copyBindings) != null ? _f : true) ? src.bind_id : void 0,
|
|
7711
8286
|
options: clonedOptions
|
|
7712
8287
|
};
|
|
7713
|
-
const optionIdMap = /* @__PURE__ */ new Map();
|
|
7714
|
-
((_g = src.options) != null ? _g : []).forEach((o, i) => {
|
|
7715
|
-
var _a2, _b2;
|
|
7716
|
-
const newOptId = (_b2 = (_a2 = clonedOptions[i]) == null ? void 0 : _a2.id) != null ? _b2 : o.id;
|
|
7717
|
-
optionIdMap.set(o.id, newOptId);
|
|
7718
|
-
});
|
|
7719
8288
|
ctx.patchProps((p) => {
|
|
7720
|
-
var _a2, _b2, _c2, _d2, _e2, _f2,
|
|
8289
|
+
var _a2, _b2, _c2, _d2, _e2, _f2, _g;
|
|
7721
8290
|
const arr = (_a2 = p.fields) != null ? _a2 : [];
|
|
7722
8291
|
const idx = arr.findIndex((f) => f.id === fieldId);
|
|
7723
8292
|
arr.splice(idx + 1, 0, cloned);
|
|
@@ -7755,52 +8324,56 @@ function duplicateField(ctx, fieldId, opts) {
|
|
|
7755
8324
|
}
|
|
7756
8325
|
if (optionIdMap.has(key)) {
|
|
7757
8326
|
const newKey = optionIdMap.get(key);
|
|
7758
|
-
const merged = /* @__PURE__ */ new Set([...(
|
|
8327
|
+
const merged = /* @__PURE__ */ new Set([...(_g = nextMap[newKey]) != null ? _g : [], ...targets]);
|
|
7759
8328
|
nextMap[newKey] = Array.from(merged);
|
|
7760
8329
|
}
|
|
7761
8330
|
}
|
|
7762
8331
|
p[mapKey] = nextMap;
|
|
7763
8332
|
}
|
|
8333
|
+
copyOptionEffects(p, {
|
|
8334
|
+
triggerIdMap: new Map([
|
|
8335
|
+
[fieldId, id],
|
|
8336
|
+
...Array.from(optionIdMap.entries())
|
|
8337
|
+
]),
|
|
8338
|
+
targetFieldIdMap: /* @__PURE__ */ new Map([[fieldId, id]]),
|
|
8339
|
+
optionIdMap
|
|
8340
|
+
});
|
|
7764
8341
|
}
|
|
7765
8342
|
});
|
|
7766
8343
|
return id;
|
|
7767
8344
|
}
|
|
7768
8345
|
function duplicateOption(ctx, fieldId, optionId, opts) {
|
|
7769
|
-
var _a, _b, _c, _d, _e, _f;
|
|
7770
8346
|
const props = ctx.getProps();
|
|
7771
|
-
const
|
|
7772
|
-
|
|
7773
|
-
|
|
7774
|
-
const optIdx = ((_b = f.options) != null ? _b : []).findIndex((o) => o.id === optionId);
|
|
7775
|
-
if (optIdx < 0) {
|
|
7776
|
-
throw new Error(`Option not found: ${fieldId}::${optionId}`);
|
|
8347
|
+
const location = findMutableOption(props, optionId);
|
|
8348
|
+
if (!location || location.field.id !== fieldId) {
|
|
8349
|
+
throw new Error(`Option not found: ${fieldId}/${optionId}`);
|
|
7777
8350
|
}
|
|
7778
|
-
const src =
|
|
7779
|
-
const
|
|
7780
|
-
|
|
7781
|
-
|
|
7782
|
-
);
|
|
7783
|
-
const newLabel = ((_e = opts.labelStrategy) != null ? _e : nextCopyLabel)((_f = src.label) != null ? _f : src.id);
|
|
8351
|
+
const src = location.option;
|
|
8352
|
+
const optionIdMap = /* @__PURE__ */ new Map();
|
|
8353
|
+
const clone2 = cloneOptionTree(ctx, fieldId, src, opts, optionIdMap);
|
|
8354
|
+
const newId2 = clone2.id;
|
|
7784
8355
|
ctx.patchProps((p) => {
|
|
7785
|
-
var
|
|
7786
|
-
const
|
|
7787
|
-
|
|
7788
|
-
|
|
7789
|
-
arr.splice(optIdx + 1, 0, clone2);
|
|
7790
|
-
fld.options = arr;
|
|
8356
|
+
var _a;
|
|
8357
|
+
const current = findMutableOption(p, optionId);
|
|
8358
|
+
if (!current) return;
|
|
8359
|
+
current.siblings.splice(current.index + 1, 0, clone2);
|
|
7791
8360
|
if (opts.copyOptionMaps) {
|
|
7792
|
-
const oldKey = `${fieldId}::${optionId}`;
|
|
7793
|
-
const newKey = `${fieldId}::${newId2}`;
|
|
7794
8361
|
for (const mapKey of [
|
|
7795
8362
|
"includes_for_buttons",
|
|
7796
8363
|
"excludes_for_buttons"
|
|
7797
8364
|
]) {
|
|
7798
|
-
const m = (
|
|
7799
|
-
|
|
7800
|
-
|
|
7801
|
-
|
|
8365
|
+
const m = (_a = p[mapKey]) != null ? _a : {};
|
|
8366
|
+
for (const [oldKey, newKey] of optionIdMap.entries()) {
|
|
8367
|
+
if (m[oldKey]) {
|
|
8368
|
+
m[newKey] = Array.from(new Set(m[oldKey]));
|
|
8369
|
+
p[mapKey] = m;
|
|
8370
|
+
}
|
|
7802
8371
|
}
|
|
7803
8372
|
}
|
|
8373
|
+
copyOptionEffects(p, {
|
|
8374
|
+
triggerIdMap: optionIdMap,
|
|
8375
|
+
optionIdMap
|
|
8376
|
+
});
|
|
7804
8377
|
}
|
|
7805
8378
|
});
|
|
7806
8379
|
return newId2;
|
|
@@ -7862,54 +8435,6 @@ function removeNotice(ctx, id) {
|
|
|
7862
8435
|
|
|
7863
8436
|
// src/react/canvas/editor/editor-nodes.ts
|
|
7864
8437
|
var import_lodash_es3 = require("lodash-es");
|
|
7865
|
-
|
|
7866
|
-
// src/react/canvas/editor/editor-utils.ts
|
|
7867
|
-
function ownerOfOption(props, optionId) {
|
|
7868
|
-
var _a, _b;
|
|
7869
|
-
for (const f of (_a = props.fields) != null ? _a : []) {
|
|
7870
|
-
const idx = ((_b = f.options) != null ? _b : []).findIndex((o) => o.id === optionId);
|
|
7871
|
-
if (idx >= 0) return { fieldId: f.id, index: idx };
|
|
7872
|
-
}
|
|
7873
|
-
return null;
|
|
7874
|
-
}
|
|
7875
|
-
function hasFieldOptions(field) {
|
|
7876
|
-
return Array.isArray(field == null ? void 0 : field.options) && field.options.length > 0;
|
|
7877
|
-
}
|
|
7878
|
-
function isActualButtonField(field) {
|
|
7879
|
-
return (field == null ? void 0 : field.button) === true && !hasFieldOptions(field);
|
|
7880
|
-
}
|
|
7881
|
-
function clearFieldButtonReceiverMaps(props, fieldId) {
|
|
7882
|
-
var _a, _b;
|
|
7883
|
-
if ((_a = props.includes_for_buttons) == null ? void 0 : _a[fieldId]) {
|
|
7884
|
-
delete props.includes_for_buttons[fieldId];
|
|
7885
|
-
}
|
|
7886
|
-
if ((_b = props.excludes_for_buttons) == null ? void 0 : _b[fieldId]) {
|
|
7887
|
-
delete props.excludes_for_buttons[fieldId];
|
|
7888
|
-
}
|
|
7889
|
-
if (props.includes_for_buttons && Object.keys(props.includes_for_buttons).length === 0) {
|
|
7890
|
-
delete props.includes_for_buttons;
|
|
7891
|
-
}
|
|
7892
|
-
if (props.excludes_for_buttons && Object.keys(props.excludes_for_buttons).length === 0) {
|
|
7893
|
-
delete props.excludes_for_buttons;
|
|
7894
|
-
}
|
|
7895
|
-
}
|
|
7896
|
-
function ensureServiceExists(opts, id) {
|
|
7897
|
-
if (typeof opts.serviceExists === "function") {
|
|
7898
|
-
if (!opts.serviceExists(id)) {
|
|
7899
|
-
throw new Error(`service_not_found:${String(id)}`);
|
|
7900
|
-
}
|
|
7901
|
-
return;
|
|
7902
|
-
}
|
|
7903
|
-
if (opts.serviceMap) {
|
|
7904
|
-
if (!Object.prototype.hasOwnProperty.call(opts.serviceMap, id)) {
|
|
7905
|
-
throw new Error(`service_not_found:${String(id)}`);
|
|
7906
|
-
}
|
|
7907
|
-
return;
|
|
7908
|
-
}
|
|
7909
|
-
throw new Error("service_checker_missing");
|
|
7910
|
-
}
|
|
7911
|
-
|
|
7912
|
-
// src/react/canvas/editor/editor-nodes.ts
|
|
7913
8438
|
var RELATION_MAP_KEYS = [
|
|
7914
8439
|
"includes_for_buttons",
|
|
7915
8440
|
"excludes_for_buttons",
|
|
@@ -7969,6 +8494,43 @@ function cleanRelationMapsForDeleted(p, deleted) {
|
|
|
7969
8494
|
if (!Object.keys(map).length) delete p[key];
|
|
7970
8495
|
}
|
|
7971
8496
|
}
|
|
8497
|
+
function cleanOptionEffectsForDeleted(p, deleted) {
|
|
8498
|
+
var _a, _b;
|
|
8499
|
+
const map = p.option_effects_for_buttons;
|
|
8500
|
+
if (!map) return;
|
|
8501
|
+
for (const triggerId of Object.keys(map)) {
|
|
8502
|
+
if (deleted.has(String(triggerId))) {
|
|
8503
|
+
delete map[triggerId];
|
|
8504
|
+
continue;
|
|
8505
|
+
}
|
|
8506
|
+
const targets = map[triggerId];
|
|
8507
|
+
for (const targetFieldId of Object.keys(targets != null ? targets : {})) {
|
|
8508
|
+
if (deleted.has(String(targetFieldId))) {
|
|
8509
|
+
delete targets[targetFieldId];
|
|
8510
|
+
continue;
|
|
8511
|
+
}
|
|
8512
|
+
const effect = targets[targetFieldId];
|
|
8513
|
+
if (!effect) continue;
|
|
8514
|
+
if (effect.include) {
|
|
8515
|
+
effect.include = effect.include.filter(
|
|
8516
|
+
(optionId) => !deleted.has(String(optionId))
|
|
8517
|
+
);
|
|
8518
|
+
if (!effect.include.length) delete effect.include;
|
|
8519
|
+
}
|
|
8520
|
+
if (effect.exclude) {
|
|
8521
|
+
effect.exclude = effect.exclude.filter(
|
|
8522
|
+
(optionId) => !deleted.has(String(optionId))
|
|
8523
|
+
);
|
|
8524
|
+
if (!effect.exclude.length) delete effect.exclude;
|
|
8525
|
+
}
|
|
8526
|
+
if (effect.forceVisible !== true && !((_a = effect.include) == null ? void 0 : _a.length) && !((_b = effect.exclude) == null ? void 0 : _b.length)) {
|
|
8527
|
+
delete targets[targetFieldId];
|
|
8528
|
+
}
|
|
8529
|
+
}
|
|
8530
|
+
if (!Object.keys(targets != null ? targets : {}).length) delete map[triggerId];
|
|
8531
|
+
}
|
|
8532
|
+
if (!Object.keys(map).length) delete p.option_effects_for_buttons;
|
|
8533
|
+
}
|
|
7972
8534
|
function cleanOrderForTagsForDeleted(p, deleted) {
|
|
7973
8535
|
var _a, _b;
|
|
7974
8536
|
const map = p.order_for_tags;
|
|
@@ -8004,28 +8566,37 @@ function applyDeleteCleanup(p, deleted) {
|
|
|
8004
8566
|
cleanTagRelationsForDeleted(p, deleted);
|
|
8005
8567
|
cleanFieldBindsForDeleted(p, deleted);
|
|
8006
8568
|
cleanRelationMapsForDeleted(p, deleted);
|
|
8569
|
+
cleanOptionEffectsForDeleted(p, deleted);
|
|
8007
8570
|
cleanOrderForTagsForDeleted(p, deleted);
|
|
8008
8571
|
cleanNoticesForDeleted(p, deleted);
|
|
8009
8572
|
}
|
|
8573
|
+
function collectOptionSubtreeIds(option) {
|
|
8574
|
+
var _a;
|
|
8575
|
+
return [
|
|
8576
|
+
String(option.id),
|
|
8577
|
+
...((_a = option.children) != null ? _a : []).flatMap((child) => collectOptionSubtreeIds(child))
|
|
8578
|
+
];
|
|
8579
|
+
}
|
|
8010
8580
|
function removeOptionInPlace(p, optionId) {
|
|
8011
8581
|
var _a;
|
|
8012
|
-
const
|
|
8013
|
-
if (!
|
|
8014
|
-
const
|
|
8015
|
-
|
|
8016
|
-
|
|
8017
|
-
|
|
8018
|
-
|
|
8582
|
+
const found = findMutableOption(p, optionId);
|
|
8583
|
+
if (!found) return [];
|
|
8584
|
+
const deleted = collectOptionSubtreeIds(found.option);
|
|
8585
|
+
found.siblings.splice(found.index, 1);
|
|
8586
|
+
if (found.parent && ((_a = found.parent.children) == null ? void 0 : _a.length) === 0) {
|
|
8587
|
+
delete found.parent.children;
|
|
8588
|
+
}
|
|
8589
|
+
return deleted;
|
|
8019
8590
|
}
|
|
8020
8591
|
function removeFieldInPlace(p, fieldId) {
|
|
8021
|
-
var _a, _b, _c, _d
|
|
8592
|
+
var _a, _b, _c, _d;
|
|
8022
8593
|
const field = ((_a = p.fields) != null ? _a : []).find((f) => f.id === fieldId);
|
|
8023
8594
|
if (!field) return [];
|
|
8024
|
-
const deleted = [fieldId, ...(
|
|
8025
|
-
const before = ((
|
|
8026
|
-
p.fields = ((
|
|
8595
|
+
const deleted = [fieldId, ...collectFieldOptionIds(field)];
|
|
8596
|
+
const before = ((_b = p.fields) != null ? _b : []).length;
|
|
8597
|
+
p.fields = ((_c = p.fields) != null ? _c : []).filter((f) => f.id !== fieldId);
|
|
8027
8598
|
clearFieldButtonReceiverMaps(p, fieldId);
|
|
8028
|
-
return ((
|
|
8599
|
+
return ((_d = p.fields) != null ? _d : []).length !== before ? deleted : [];
|
|
8029
8600
|
}
|
|
8030
8601
|
function removeTagInPlace(p, tagId) {
|
|
8031
8602
|
var _a, _b, _c;
|
|
@@ -8038,7 +8609,7 @@ function reLabel(ctx, id, nextLabel) {
|
|
|
8038
8609
|
ctx.exec({
|
|
8039
8610
|
name: "reLabel",
|
|
8040
8611
|
do: () => ctx.patchProps((p) => {
|
|
8041
|
-
var _a, _b, _c, _d, _e, _f
|
|
8612
|
+
var _a, _b, _c, _d, _e, _f;
|
|
8042
8613
|
if (ctx.isTagId(id)) {
|
|
8043
8614
|
const t = ((_a = p.filters) != null ? _a : []).find((x) => x.id === id);
|
|
8044
8615
|
if (!t) return;
|
|
@@ -8048,19 +8619,16 @@ function reLabel(ctx, id, nextLabel) {
|
|
|
8048
8619
|
return;
|
|
8049
8620
|
}
|
|
8050
8621
|
if (ctx.isOptionId(id)) {
|
|
8051
|
-
const
|
|
8052
|
-
if (!own) return;
|
|
8053
|
-
const f = ((_c = p.fields) != null ? _c : []).find((x) => x.id === own.fieldId);
|
|
8054
|
-
const o = (_d = f == null ? void 0 : f.options) == null ? void 0 : _d.find((x) => x.id === id);
|
|
8622
|
+
const o = (_c = findMutableOption(p, id)) == null ? void 0 : _c.option;
|
|
8055
8623
|
if (!o) return;
|
|
8056
|
-
if (((
|
|
8624
|
+
if (((_d = o.label) != null ? _d : "") === label) return;
|
|
8057
8625
|
o.label = label;
|
|
8058
8626
|
ctx.api.refreshGraph();
|
|
8059
8627
|
return;
|
|
8060
8628
|
}
|
|
8061
|
-
const fld = ((
|
|
8629
|
+
const fld = ((_e = p.fields) != null ? _e : []).find((x) => x.id === id);
|
|
8062
8630
|
if (!fld) return;
|
|
8063
|
-
if (((
|
|
8631
|
+
if (((_f = fld.label) != null ? _f : "") === label) return;
|
|
8064
8632
|
fld.label = label;
|
|
8065
8633
|
ctx.api.refreshGraph();
|
|
8066
8634
|
}),
|
|
@@ -8150,11 +8718,7 @@ function updateOption(ctx, optionId, patch) {
|
|
|
8150
8718
|
name: "updateOption",
|
|
8151
8719
|
do: () => ctx.patchProps((p) => {
|
|
8152
8720
|
var _a;
|
|
8153
|
-
const
|
|
8154
|
-
if (!owner) return;
|
|
8155
|
-
const f = ((_a = p.fields) != null ? _a : []).find((x) => x.id === owner.fieldId);
|
|
8156
|
-
if (!(f == null ? void 0 : f.options)) return;
|
|
8157
|
-
const o = f.options.find((x) => x.id === optionId);
|
|
8721
|
+
const o = (_a = findMutableOption(p, optionId)) == null ? void 0 : _a.option;
|
|
8158
8722
|
if (o) Object.assign(o, patch);
|
|
8159
8723
|
}),
|
|
8160
8724
|
undo: () => ctx.undo()
|
|
@@ -8167,9 +8731,9 @@ function removeOption(ctx, optionId) {
|
|
|
8167
8731
|
ctx.exec({
|
|
8168
8732
|
name: "removeOption",
|
|
8169
8733
|
do: () => ctx.patchProps((p) => {
|
|
8170
|
-
const
|
|
8171
|
-
if (!
|
|
8172
|
-
applyDeleteCleanup(p,
|
|
8734
|
+
const removedIds = removeOptionInPlace(p, optionId);
|
|
8735
|
+
if (!removedIds.length) return;
|
|
8736
|
+
applyDeleteCleanup(p, new Set(removedIds));
|
|
8173
8737
|
}),
|
|
8174
8738
|
undo: () => ctx.undo()
|
|
8175
8739
|
});
|
|
@@ -8180,7 +8744,7 @@ function editLabel(ctx, id, label) {
|
|
|
8180
8744
|
ctx.exec({
|
|
8181
8745
|
name: "editLabel",
|
|
8182
8746
|
do: () => ctx.patchProps((p) => {
|
|
8183
|
-
var _a, _b, _c
|
|
8747
|
+
var _a, _b, _c;
|
|
8184
8748
|
if (ctx.isTagId(id)) {
|
|
8185
8749
|
const t = ((_a = p.filters) != null ? _a : []).find((x) => x.id === id);
|
|
8186
8750
|
if (t) t.label = next;
|
|
@@ -8192,10 +8756,7 @@ function editLabel(ctx, id, label) {
|
|
|
8192
8756
|
return;
|
|
8193
8757
|
}
|
|
8194
8758
|
if (ctx.isOptionId(id)) {
|
|
8195
|
-
const
|
|
8196
|
-
if (!own) return;
|
|
8197
|
-
const f = ((_c = p.fields) != null ? _c : []).find((x) => x.id === own.fieldId);
|
|
8198
|
-
const o = (_d = f == null ? void 0 : f.options) == null ? void 0 : _d.find((x) => x.id === id);
|
|
8759
|
+
const o = (_c = findMutableOption(p, id)) == null ? void 0 : _c.option;
|
|
8199
8760
|
if (o) o.label = next;
|
|
8200
8761
|
return;
|
|
8201
8762
|
}
|
|
@@ -8220,7 +8781,7 @@ function setService(ctx, id, input) {
|
|
|
8220
8781
|
ctx.exec({
|
|
8221
8782
|
name: "setService",
|
|
8222
8783
|
do: () => ctx.patchProps((p) => {
|
|
8223
|
-
var _a, _b, _c, _d, _e
|
|
8784
|
+
var _a, _b, _c, _d, _e;
|
|
8224
8785
|
const hasSidKey = Object.prototype.hasOwnProperty.call(
|
|
8225
8786
|
input,
|
|
8226
8787
|
"service_id"
|
|
@@ -8238,12 +8799,9 @@ function setService(ctx, id, input) {
|
|
|
8238
8799
|
return;
|
|
8239
8800
|
}
|
|
8240
8801
|
if (ctx.isOptionId(id)) {
|
|
8241
|
-
const
|
|
8242
|
-
if (!own) return;
|
|
8243
|
-
const f2 = ((_b = p.fields) != null ? _b : []).find((x) => x.id === own.fieldId);
|
|
8244
|
-
const o = (_c = f2 == null ? void 0 : f2.options) == null ? void 0 : _c.find((x) => x.id === id);
|
|
8802
|
+
const o = (_b = findMutableOption(p, id)) == null ? void 0 : _b.option;
|
|
8245
8803
|
if (!o) return;
|
|
8246
|
-
const currentRole = (
|
|
8804
|
+
const currentRole = (_c = o.pricing_role) != null ? _c : "base";
|
|
8247
8805
|
const role = nextRole != null ? nextRole : currentRole;
|
|
8248
8806
|
if (role === "utility") {
|
|
8249
8807
|
if (hasSidKey && sid !== void 0) {
|
|
@@ -8264,7 +8822,7 @@ function setService(ctx, id, input) {
|
|
|
8264
8822
|
}
|
|
8265
8823
|
return;
|
|
8266
8824
|
}
|
|
8267
|
-
const f = ((
|
|
8825
|
+
const f = ((_d = p.fields) != null ? _d : []).find((x) => x.id === id);
|
|
8268
8826
|
if (!f) {
|
|
8269
8827
|
throw new Error(
|
|
8270
8828
|
'setService only supports tag ("t:*"), option ("o:*"), or field ("f:*") ids'
|
|
@@ -8275,7 +8833,7 @@ function setService(ctx, id, input) {
|
|
|
8275
8833
|
if (nextRole) {
|
|
8276
8834
|
f.pricing_role = nextRole;
|
|
8277
8835
|
}
|
|
8278
|
-
const effectiveRole = (
|
|
8836
|
+
const effectiveRole = (_e = f.pricing_role) != null ? _e : "base";
|
|
8279
8837
|
if (isOptionBased) {
|
|
8280
8838
|
if (hasSidKey) {
|
|
8281
8839
|
ctx.api.emit("error", {
|
|
@@ -8387,13 +8945,15 @@ function updateField(ctx, id, patch) {
|
|
|
8387
8945
|
let prev;
|
|
8388
8946
|
let prevIncludesForButton;
|
|
8389
8947
|
let prevExcludesForButton;
|
|
8948
|
+
let prevOptionEffectsForButton;
|
|
8390
8949
|
ctx.exec({
|
|
8391
8950
|
name: "updateField",
|
|
8392
8951
|
do: () => ctx.patchProps((p) => {
|
|
8393
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
8952
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
8394
8953
|
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;
|
|
8395
8954
|
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;
|
|
8396
|
-
|
|
8955
|
+
prevOptionEffectsForButton = ((_g = p.option_effects_for_buttons) == null ? void 0 : _g[id]) ? (0, import_lodash_es3.cloneDeep)(p.option_effects_for_buttons[id]) : void 0;
|
|
8956
|
+
p.fields = ((_h = p.fields) != null ? _h : []).map((f) => {
|
|
8397
8957
|
if (f.id !== id) return f;
|
|
8398
8958
|
prev = (0, import_lodash_es3.cloneDeep)(f);
|
|
8399
8959
|
const nextField = { ...f, ...patch };
|
|
@@ -8404,7 +8964,7 @@ function updateField(ctx, id, patch) {
|
|
|
8404
8964
|
});
|
|
8405
8965
|
}),
|
|
8406
8966
|
undo: () => ctx.patchProps((p) => {
|
|
8407
|
-
var _a, _b, _c;
|
|
8967
|
+
var _a, _b, _c, _d;
|
|
8408
8968
|
p.fields = ((_a = p.fields) != null ? _a : []).map(
|
|
8409
8969
|
(f) => f.id === id && prev ? prev : f
|
|
8410
8970
|
);
|
|
@@ -8422,6 +8982,12 @@ function updateField(ctx, id, patch) {
|
|
|
8422
8982
|
[id]: [...prevExcludesForButton]
|
|
8423
8983
|
};
|
|
8424
8984
|
}
|
|
8985
|
+
if (prevOptionEffectsForButton) {
|
|
8986
|
+
p.option_effects_for_buttons = {
|
|
8987
|
+
...(_d = p.option_effects_for_buttons) != null ? _d : {},
|
|
8988
|
+
[id]: (0, import_lodash_es3.cloneDeep)(prevOptionEffectsForButton)
|
|
8989
|
+
};
|
|
8990
|
+
}
|
|
8425
8991
|
})
|
|
8426
8992
|
});
|
|
8427
8993
|
}
|
|
@@ -8468,9 +9034,9 @@ function remove(ctx, id) {
|
|
|
8468
9034
|
ctx.exec({
|
|
8469
9035
|
name: "removeOption",
|
|
8470
9036
|
do: () => ctx.patchProps((p) => {
|
|
8471
|
-
const
|
|
8472
|
-
if (!
|
|
8473
|
-
applyDeleteCleanup(p,
|
|
9037
|
+
const removedIds = removeOptionInPlace(p, key);
|
|
9038
|
+
if (!removedIds.length) return;
|
|
9039
|
+
applyDeleteCleanup(p, new Set(removedIds));
|
|
8474
9040
|
}),
|
|
8475
9041
|
undo: () => ctx.undo()
|
|
8476
9042
|
});
|
|
@@ -8487,10 +9053,7 @@ function removeMany(ctx, ids) {
|
|
|
8487
9053
|
const existingFieldIds = new Set(((_a = p.fields) != null ? _a : []).map((f) => String(f.id)));
|
|
8488
9054
|
const existingTagIds = new Set(((_b = p.filters) != null ? _b : []).map((t) => String(t.id)));
|
|
8489
9055
|
const existingOptionIds = new Set(
|
|
8490
|
-
((_c = p.fields) != null ? _c : []).flatMap((f) =>
|
|
8491
|
-
var _a2;
|
|
8492
|
-
return ((_a2 = f.options) != null ? _a2 : []).map((o) => String(o.id));
|
|
8493
|
-
})
|
|
9056
|
+
((_c = p.fields) != null ? _c : []).flatMap((f) => collectFieldOptionIds(f))
|
|
8494
9057
|
);
|
|
8495
9058
|
const fieldIds = ordered.filter((id) => ctx.isFieldId(id) && existingFieldIds.has(id));
|
|
8496
9059
|
const fieldIdSet = new Set(fieldIds);
|
|
@@ -8503,7 +9066,9 @@ function removeMany(ctx, ids) {
|
|
|
8503
9066
|
});
|
|
8504
9067
|
const deleted = /* @__PURE__ */ new Set();
|
|
8505
9068
|
for (const optionId of optionIds) {
|
|
8506
|
-
|
|
9069
|
+
for (const removedId of removeOptionInPlace(p, optionId)) {
|
|
9070
|
+
deleted.add(removedId);
|
|
9071
|
+
}
|
|
8507
9072
|
}
|
|
8508
9073
|
for (const fieldId of fieldIds) {
|
|
8509
9074
|
const removedIds = removeFieldInPlace(p, fieldId);
|
|
@@ -8518,7 +9083,7 @@ function removeMany(ctx, ids) {
|
|
|
8518
9083
|
});
|
|
8519
9084
|
}
|
|
8520
9085
|
function getNode(ctx, id) {
|
|
8521
|
-
var _a, _b, _c
|
|
9086
|
+
var _a, _b, _c;
|
|
8522
9087
|
const props = ctx.getProps();
|
|
8523
9088
|
if (ctx.isTagId(id)) {
|
|
8524
9089
|
const t = ((_a = props.filters) != null ? _a : []).find((x) => x.id === id);
|
|
@@ -8535,8 +9100,7 @@ function getNode(ctx, id) {
|
|
|
8535
9100
|
}
|
|
8536
9101
|
if (ctx.isOptionId(id)) {
|
|
8537
9102
|
const own = ownerOfOption(props, id);
|
|
8538
|
-
const
|
|
8539
|
-
const o = (_d = f == null ? void 0 : f.options) == null ? void 0 : _d.find((x) => x.id === id);
|
|
9103
|
+
const o = (_c = findMutableOption(props, id)) == null ? void 0 : _c.option;
|
|
8540
9104
|
return {
|
|
8541
9105
|
kind: "option",
|
|
8542
9106
|
data: o,
|
|
@@ -9073,7 +9637,7 @@ function connect(ctx, kind, fromId, toId2) {
|
|
|
9073
9637
|
ctx.exec({
|
|
9074
9638
|
name: `connect:${kind}`,
|
|
9075
9639
|
do: () => ctx.patchProps((p) => {
|
|
9076
|
-
var _a, _b, _c, _d, _e, _f, _g
|
|
9640
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
9077
9641
|
if (kind === "bind") {
|
|
9078
9642
|
if (ctx.isTagId(fromId) && ctx.isTagId(toId2)) {
|
|
9079
9643
|
if (wouldCreateTagCycle(ctx, p, fromId, toId2)) {
|
|
@@ -9153,12 +9717,10 @@ function connect(ctx, kind, fromId, toId2) {
|
|
|
9153
9717
|
return;
|
|
9154
9718
|
}
|
|
9155
9719
|
if (toId2.startsWith("o:")) {
|
|
9156
|
-
|
|
9157
|
-
|
|
9158
|
-
|
|
9159
|
-
|
|
9160
|
-
return;
|
|
9161
|
-
}
|
|
9720
|
+
const o = (_g = findMutableOption(p, toId2)) == null ? void 0 : _g.option;
|
|
9721
|
+
if (o) {
|
|
9722
|
+
o.service_id = fromId;
|
|
9723
|
+
return;
|
|
9162
9724
|
}
|
|
9163
9725
|
return;
|
|
9164
9726
|
}
|
|
@@ -9175,7 +9737,7 @@ function disconnect(ctx, kind, fromId, toId2) {
|
|
|
9175
9737
|
ctx.exec({
|
|
9176
9738
|
name: `disconnect:${kind}`,
|
|
9177
9739
|
do: () => ctx.patchProps((p) => {
|
|
9178
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i
|
|
9740
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
9179
9741
|
if (kind === "bind") {
|
|
9180
9742
|
if (ctx.isTagId(fromId) && ctx.isTagId(toId2)) {
|
|
9181
9743
|
const child = ((_a = p.filters) != null ? _a : []).find(
|
|
@@ -9251,12 +9813,10 @@ function disconnect(ctx, kind, fromId, toId2) {
|
|
|
9251
9813
|
return;
|
|
9252
9814
|
}
|
|
9253
9815
|
if (toId2.startsWith("o:")) {
|
|
9254
|
-
|
|
9255
|
-
|
|
9256
|
-
|
|
9257
|
-
|
|
9258
|
-
return;
|
|
9259
|
-
}
|
|
9816
|
+
const o = (_i = findMutableOption(p, toId2)) == null ? void 0 : _i.option;
|
|
9817
|
+
if (o) {
|
|
9818
|
+
delete o.service_id;
|
|
9819
|
+
return;
|
|
9260
9820
|
}
|
|
9261
9821
|
return;
|
|
9262
9822
|
}
|
|
@@ -9279,6 +9839,250 @@ function addMappedField(p, mapKey, fromId, toId2) {
|
|
|
9279
9839
|
p[mapKey] = maps;
|
|
9280
9840
|
}
|
|
9281
9841
|
|
|
9842
|
+
// src/react/canvas/editor/editor-option-effects.ts
|
|
9843
|
+
function assertCanonicalId(id, label) {
|
|
9844
|
+
if (!id || id.includes("::") || id.includes("/")) {
|
|
9845
|
+
throw new Error(
|
|
9846
|
+
`${label}: expected a raw field or option id, not a composite/path id`
|
|
9847
|
+
);
|
|
9848
|
+
}
|
|
9849
|
+
}
|
|
9850
|
+
function assertTrigger(ctx, triggerId) {
|
|
9851
|
+
assertCanonicalId(triggerId, "option effect trigger");
|
|
9852
|
+
const trigger = ctx.getNode(triggerId);
|
|
9853
|
+
if (trigger.kind === "option" && trigger.data) return;
|
|
9854
|
+
if (trigger.kind === "field" && trigger.data && isActualButtonField(trigger.data)) {
|
|
9855
|
+
return;
|
|
9856
|
+
}
|
|
9857
|
+
throw new Error(
|
|
9858
|
+
"option effect trigger must be an option id or button field id"
|
|
9859
|
+
);
|
|
9860
|
+
}
|
|
9861
|
+
function assertTargetField(props, targetFieldId) {
|
|
9862
|
+
var _a;
|
|
9863
|
+
assertCanonicalId(targetFieldId, "option effect target");
|
|
9864
|
+
const field = ((_a = props.fields) != null ? _a : []).find((item) => item.id === targetFieldId);
|
|
9865
|
+
if (!field) {
|
|
9866
|
+
throw new Error(`option effect target field not found: ${targetFieldId}`);
|
|
9867
|
+
}
|
|
9868
|
+
return field;
|
|
9869
|
+
}
|
|
9870
|
+
function dedupe2(values) {
|
|
9871
|
+
if (!values) return void 0;
|
|
9872
|
+
const out = [];
|
|
9873
|
+
for (const value of values) {
|
|
9874
|
+
const id = String(value);
|
|
9875
|
+
if (!id || out.includes(id)) continue;
|
|
9876
|
+
out.push(id);
|
|
9877
|
+
}
|
|
9878
|
+
return out.length ? out : void 0;
|
|
9879
|
+
}
|
|
9880
|
+
function assertTargetOptions(props, targetFieldId, ids, kind) {
|
|
9881
|
+
if (!(ids == null ? void 0 : ids.length)) return;
|
|
9882
|
+
const field = assertTargetField(props, targetFieldId);
|
|
9883
|
+
const valid = fieldOptionIdSet(field);
|
|
9884
|
+
for (const id of ids) {
|
|
9885
|
+
assertCanonicalId(String(id), `option effect ${kind} option`);
|
|
9886
|
+
if (!valid.has(String(id))) {
|
|
9887
|
+
throw new Error(
|
|
9888
|
+
`option effect ${kind} option not found under ${targetFieldId}: ${String(id)}`
|
|
9889
|
+
);
|
|
9890
|
+
}
|
|
9891
|
+
}
|
|
9892
|
+
}
|
|
9893
|
+
function normalizeEffect(effect) {
|
|
9894
|
+
var _a;
|
|
9895
|
+
if (!effect) return void 0;
|
|
9896
|
+
const exclude2 = dedupe2(effect.exclude);
|
|
9897
|
+
const excluded = new Set(exclude2 != null ? exclude2 : []);
|
|
9898
|
+
const include2 = (_a = dedupe2(effect.include)) == null ? void 0 : _a.filter((id) => !excluded.has(id));
|
|
9899
|
+
const out = {};
|
|
9900
|
+
if (effect.forceVisible === true) out.forceVisible = true;
|
|
9901
|
+
if (include2 == null ? void 0 : include2.length) out.include = include2;
|
|
9902
|
+
if (exclude2 == null ? void 0 : exclude2.length) out.exclude = exclude2;
|
|
9903
|
+
return Object.keys(out).length ? out : void 0;
|
|
9904
|
+
}
|
|
9905
|
+
function ensureTargetMap(props, triggerId) {
|
|
9906
|
+
var _a, _b, _c;
|
|
9907
|
+
(_a = props.option_effects_for_buttons) != null ? _a : props.option_effects_for_buttons = {};
|
|
9908
|
+
(_c = (_b = props.option_effects_for_buttons)[triggerId]) != null ? _c : _b[triggerId] = {};
|
|
9909
|
+
return props.option_effects_for_buttons[triggerId];
|
|
9910
|
+
}
|
|
9911
|
+
function pruneEffectMap(props, triggerId) {
|
|
9912
|
+
const map = props.option_effects_for_buttons;
|
|
9913
|
+
if (!map) return;
|
|
9914
|
+
const keys = triggerId ? [triggerId] : Object.keys(map);
|
|
9915
|
+
for (const key of keys) {
|
|
9916
|
+
const targets = map[key];
|
|
9917
|
+
if (!targets || Object.keys(targets).length === 0) delete map[key];
|
|
9918
|
+
}
|
|
9919
|
+
if (Object.keys(map).length === 0) delete props.option_effects_for_buttons;
|
|
9920
|
+
}
|
|
9921
|
+
function validateEffect(ctx, props, triggerId, targetFieldId, effect) {
|
|
9922
|
+
assertTrigger(ctx, triggerId);
|
|
9923
|
+
assertTargetField(props, targetFieldId);
|
|
9924
|
+
assertTargetOptions(props, targetFieldId, effect == null ? void 0 : effect.include, "include");
|
|
9925
|
+
assertTargetOptions(props, targetFieldId, effect == null ? void 0 : effect.exclude, "exclude");
|
|
9926
|
+
return normalizeEffect(effect);
|
|
9927
|
+
}
|
|
9928
|
+
function setOptionEffect(ctx, triggerId, targetFieldId, effect) {
|
|
9929
|
+
ctx.exec({
|
|
9930
|
+
name: "setOptionEffect",
|
|
9931
|
+
do: () => ctx.patchProps((props) => {
|
|
9932
|
+
var _a;
|
|
9933
|
+
const normalized = validateEffect(
|
|
9934
|
+
ctx,
|
|
9935
|
+
props,
|
|
9936
|
+
triggerId,
|
|
9937
|
+
targetFieldId,
|
|
9938
|
+
effect
|
|
9939
|
+
);
|
|
9940
|
+
if (!normalized) {
|
|
9941
|
+
const map = (_a = props.option_effects_for_buttons) == null ? void 0 : _a[triggerId];
|
|
9942
|
+
if (map) delete map[targetFieldId];
|
|
9943
|
+
pruneEffectMap(props, triggerId);
|
|
9944
|
+
return;
|
|
9945
|
+
}
|
|
9946
|
+
ensureTargetMap(props, triggerId)[targetFieldId] = normalized;
|
|
9947
|
+
}),
|
|
9948
|
+
undo: () => ctx.undo()
|
|
9949
|
+
});
|
|
9950
|
+
}
|
|
9951
|
+
function patchOptionEffect(ctx, triggerId, targetFieldId, patch) {
|
|
9952
|
+
ctx.exec({
|
|
9953
|
+
name: "patchOptionEffect",
|
|
9954
|
+
do: () => ctx.patchProps((props) => {
|
|
9955
|
+
var _a, _b, _c, _d;
|
|
9956
|
+
const current = (_c = (_b = (_a = props.option_effects_for_buttons) == null ? void 0 : _a[triggerId]) == null ? void 0 : _b[targetFieldId]) != null ? _c : {};
|
|
9957
|
+
const merged = {
|
|
9958
|
+
...current,
|
|
9959
|
+
...patch
|
|
9960
|
+
};
|
|
9961
|
+
const normalized = validateEffect(
|
|
9962
|
+
ctx,
|
|
9963
|
+
props,
|
|
9964
|
+
triggerId,
|
|
9965
|
+
targetFieldId,
|
|
9966
|
+
merged
|
|
9967
|
+
);
|
|
9968
|
+
if (!normalized) {
|
|
9969
|
+
const map = (_d = props.option_effects_for_buttons) == null ? void 0 : _d[triggerId];
|
|
9970
|
+
if (map) delete map[targetFieldId];
|
|
9971
|
+
pruneEffectMap(props, triggerId);
|
|
9972
|
+
return;
|
|
9973
|
+
}
|
|
9974
|
+
ensureTargetMap(props, triggerId)[targetFieldId] = normalized;
|
|
9975
|
+
}),
|
|
9976
|
+
undo: () => ctx.undo()
|
|
9977
|
+
});
|
|
9978
|
+
}
|
|
9979
|
+
function clearOptionEffect(ctx, triggerId, targetFieldId) {
|
|
9980
|
+
ctx.exec({
|
|
9981
|
+
name: "clearOptionEffect",
|
|
9982
|
+
do: () => ctx.patchProps((props) => {
|
|
9983
|
+
var _a;
|
|
9984
|
+
const map = (_a = props.option_effects_for_buttons) == null ? void 0 : _a[triggerId];
|
|
9985
|
+
if (!map) return;
|
|
9986
|
+
delete map[targetFieldId];
|
|
9987
|
+
pruneEffectMap(props, triggerId);
|
|
9988
|
+
}),
|
|
9989
|
+
undo: () => ctx.undo()
|
|
9990
|
+
});
|
|
9991
|
+
}
|
|
9992
|
+
function clearOptionEffectsForTrigger(ctx, triggerId) {
|
|
9993
|
+
ctx.exec({
|
|
9994
|
+
name: "clearOptionEffectsForTrigger",
|
|
9995
|
+
do: () => ctx.patchProps((props) => {
|
|
9996
|
+
if (!props.option_effects_for_buttons) return;
|
|
9997
|
+
delete props.option_effects_for_buttons[triggerId];
|
|
9998
|
+
pruneEffectMap(props);
|
|
9999
|
+
}),
|
|
10000
|
+
undo: () => ctx.undo()
|
|
10001
|
+
});
|
|
10002
|
+
}
|
|
10003
|
+
function clearOptionEffectsForTarget(ctx, targetFieldId) {
|
|
10004
|
+
ctx.exec({
|
|
10005
|
+
name: "clearOptionEffectsForTarget",
|
|
10006
|
+
do: () => ctx.patchProps((props) => {
|
|
10007
|
+
var _a;
|
|
10008
|
+
const map = props.option_effects_for_buttons;
|
|
10009
|
+
if (!map) return;
|
|
10010
|
+
for (const triggerId of Object.keys(map)) {
|
|
10011
|
+
(_a = map[triggerId]) == null ? true : delete _a[targetFieldId];
|
|
10012
|
+
}
|
|
10013
|
+
pruneEffectMap(props);
|
|
10014
|
+
}),
|
|
10015
|
+
undo: () => ctx.undo()
|
|
10016
|
+
});
|
|
10017
|
+
}
|
|
10018
|
+
function addOptionEffectOptions(ctx, triggerId, targetFieldId, kind, optionIds) {
|
|
10019
|
+
var _a;
|
|
10020
|
+
const additions = (_a = dedupe2(optionIds)) != null ? _a : [];
|
|
10021
|
+
if (!additions.length) return;
|
|
10022
|
+
ctx.exec({
|
|
10023
|
+
name: "addOptionEffectOptions",
|
|
10024
|
+
do: () => ctx.patchProps((props) => {
|
|
10025
|
+
var _a2, _b, _c, _d;
|
|
10026
|
+
const current = (_c = (_b = (_a2 = props.option_effects_for_buttons) == null ? void 0 : _a2[triggerId]) == null ? void 0 : _b[targetFieldId]) != null ? _c : {};
|
|
10027
|
+
const nextValues = dedupe2([
|
|
10028
|
+
...(_d = current[kind]) != null ? _d : [],
|
|
10029
|
+
...additions
|
|
10030
|
+
]);
|
|
10031
|
+
const normalized = validateEffect(
|
|
10032
|
+
ctx,
|
|
10033
|
+
props,
|
|
10034
|
+
triggerId,
|
|
10035
|
+
targetFieldId,
|
|
10036
|
+
{
|
|
10037
|
+
...current,
|
|
10038
|
+
[kind]: nextValues
|
|
10039
|
+
}
|
|
10040
|
+
);
|
|
10041
|
+
if (!normalized) return;
|
|
10042
|
+
ensureTargetMap(props, triggerId)[targetFieldId] = normalized;
|
|
10043
|
+
}),
|
|
10044
|
+
undo: () => ctx.undo()
|
|
10045
|
+
});
|
|
10046
|
+
}
|
|
10047
|
+
function removeOptionEffectOptions(ctx, triggerId, targetFieldId, kind, optionIds) {
|
|
10048
|
+
var _a;
|
|
10049
|
+
const removals = new Set((_a = dedupe2(optionIds)) != null ? _a : []);
|
|
10050
|
+
if (!removals.size) return;
|
|
10051
|
+
ctx.exec({
|
|
10052
|
+
name: "removeOptionEffectOptions",
|
|
10053
|
+
do: () => ctx.patchProps((props) => {
|
|
10054
|
+
var _a2, _b, _c, _d, _e;
|
|
10055
|
+
const current = (_b = (_a2 = props.option_effects_for_buttons) == null ? void 0 : _a2[triggerId]) == null ? void 0 : _b[targetFieldId];
|
|
10056
|
+
if (!current) return;
|
|
10057
|
+
const next = {
|
|
10058
|
+
...current,
|
|
10059
|
+
[kind]: ((_c = current[kind]) != null ? _c : []).filter(
|
|
10060
|
+
(optionId) => !removals.has(optionId)
|
|
10061
|
+
)
|
|
10062
|
+
};
|
|
10063
|
+
const normalized = validateEffect(
|
|
10064
|
+
ctx,
|
|
10065
|
+
props,
|
|
10066
|
+
triggerId,
|
|
10067
|
+
targetFieldId,
|
|
10068
|
+
next
|
|
10069
|
+
);
|
|
10070
|
+
if (!normalized) {
|
|
10071
|
+
(_e = (_d = props.option_effects_for_buttons) == null ? void 0 : _d[triggerId]) == null ? true : delete _e[targetFieldId];
|
|
10072
|
+
pruneEffectMap(props, triggerId);
|
|
10073
|
+
return;
|
|
10074
|
+
}
|
|
10075
|
+
ensureTargetMap(props, triggerId)[targetFieldId] = normalized;
|
|
10076
|
+
}),
|
|
10077
|
+
undo: () => ctx.undo()
|
|
10078
|
+
});
|
|
10079
|
+
}
|
|
10080
|
+
function setOptionEffectForceVisible(ctx, triggerId, targetFieldId, forceVisible) {
|
|
10081
|
+
patchOptionEffect(ctx, triggerId, targetFieldId, {
|
|
10082
|
+
forceVisible: forceVisible === true ? true : void 0
|
|
10083
|
+
});
|
|
10084
|
+
}
|
|
10085
|
+
|
|
9282
10086
|
// src/react/canvas/editor/editor-service-filter.ts
|
|
9283
10087
|
function filterServicesForVisibleGroup2(ctx, candidates, input) {
|
|
9284
10088
|
const coreInput = {
|
|
@@ -9865,7 +10669,7 @@ var Editor = class {
|
|
|
9865
10669
|
if (!ordered.length) return;
|
|
9866
10670
|
this.transact("clearServiceMany", () => {
|
|
9867
10671
|
this.patchProps((p) => {
|
|
9868
|
-
var _a, _b
|
|
10672
|
+
var _a, _b;
|
|
9869
10673
|
for (const id of ordered) {
|
|
9870
10674
|
if (this.isTagId(id)) {
|
|
9871
10675
|
const t = ((_a = p.filters) != null ? _a : []).find((x) => x.id === id);
|
|
@@ -9878,10 +10682,8 @@ var Editor = class {
|
|
|
9878
10682
|
continue;
|
|
9879
10683
|
}
|
|
9880
10684
|
if (this.isOptionId(id)) {
|
|
9881
|
-
const
|
|
9882
|
-
|
|
9883
|
-
const f = ((_c = p.fields) != null ? _c : []).find((x) => x.id === own.fieldId);
|
|
9884
|
-
const o = (_d = f == null ? void 0 : f.options) == null ? void 0 : _d.find((x) => x.id === id);
|
|
10685
|
+
const found = findMutableOption(p, id);
|
|
10686
|
+
const o = found == null ? void 0 : found.option;
|
|
9885
10687
|
if (o && "service_id" in o) delete o.service_id;
|
|
9886
10688
|
}
|
|
9887
10689
|
}
|
|
@@ -9930,7 +10732,7 @@ var Editor = class {
|
|
|
9930
10732
|
if (!selected.size) return;
|
|
9931
10733
|
this.transact("clearRelationsMany", () => {
|
|
9932
10734
|
this.patchProps((p) => {
|
|
9933
|
-
var _a, _b, _c;
|
|
10735
|
+
var _a, _b, _c, _d, _e;
|
|
9934
10736
|
const clearOwned = mode === "owned" || mode === "both";
|
|
9935
10737
|
const clearIncoming = mode === "incoming" || mode === "both";
|
|
9936
10738
|
for (const t of (_a = p.filters) != null ? _a : []) {
|
|
@@ -9970,6 +10772,44 @@ var Editor = class {
|
|
|
9970
10772
|
}
|
|
9971
10773
|
if (!Object.keys(map).length) delete p[k];
|
|
9972
10774
|
}
|
|
10775
|
+
const effectMap = p.option_effects_for_buttons;
|
|
10776
|
+
if (effectMap) {
|
|
10777
|
+
for (const triggerId of Object.keys(effectMap)) {
|
|
10778
|
+
if (clearOwned && selected.has(String(triggerId))) {
|
|
10779
|
+
delete effectMap[triggerId];
|
|
10780
|
+
continue;
|
|
10781
|
+
}
|
|
10782
|
+
const targets = effectMap[triggerId];
|
|
10783
|
+
if (!targets || !clearIncoming) continue;
|
|
10784
|
+
for (const targetFieldId of Object.keys(targets)) {
|
|
10785
|
+
if (selected.has(String(targetFieldId))) {
|
|
10786
|
+
delete targets[targetFieldId];
|
|
10787
|
+
continue;
|
|
10788
|
+
}
|
|
10789
|
+
const effect = targets[targetFieldId];
|
|
10790
|
+
if (!effect) continue;
|
|
10791
|
+
if (effect.include) {
|
|
10792
|
+
effect.include = effect.include.filter(
|
|
10793
|
+
(optionId) => !selected.has(String(optionId))
|
|
10794
|
+
);
|
|
10795
|
+
if (!effect.include.length) delete effect.include;
|
|
10796
|
+
}
|
|
10797
|
+
if (effect.exclude) {
|
|
10798
|
+
effect.exclude = effect.exclude.filter(
|
|
10799
|
+
(optionId) => !selected.has(String(optionId))
|
|
10800
|
+
);
|
|
10801
|
+
if (!effect.exclude.length) delete effect.exclude;
|
|
10802
|
+
}
|
|
10803
|
+
if (effect.forceVisible !== true && !((_d = effect.include) == null ? void 0 : _d.length) && !((_e = effect.exclude) == null ? void 0 : _e.length)) {
|
|
10804
|
+
delete targets[targetFieldId];
|
|
10805
|
+
}
|
|
10806
|
+
}
|
|
10807
|
+
if (!Object.keys(targets).length) delete effectMap[triggerId];
|
|
10808
|
+
}
|
|
10809
|
+
if (!Object.keys(effectMap).length) {
|
|
10810
|
+
delete p.option_effects_for_buttons;
|
|
10811
|
+
}
|
|
10812
|
+
}
|
|
9973
10813
|
});
|
|
9974
10814
|
});
|
|
9975
10815
|
}
|
|
@@ -9981,7 +10821,7 @@ var Editor = class {
|
|
|
9981
10821
|
const suffix = (_b = input.suffix) != null ? _b : "";
|
|
9982
10822
|
this.transact("renameLabelsMany", () => {
|
|
9983
10823
|
this.patchProps((p) => {
|
|
9984
|
-
var _a2, _b2, _c, _d, _e, _f
|
|
10824
|
+
var _a2, _b2, _c, _d, _e, _f;
|
|
9985
10825
|
for (const id of ordered) {
|
|
9986
10826
|
if (this.isTagId(id)) {
|
|
9987
10827
|
const t = ((_a2 = p.filters) != null ? _a2 : []).find((x) => x.id === id);
|
|
@@ -9994,11 +10834,8 @@ var Editor = class {
|
|
|
9994
10834
|
continue;
|
|
9995
10835
|
}
|
|
9996
10836
|
if (this.isOptionId(id)) {
|
|
9997
|
-
const
|
|
9998
|
-
if (
|
|
9999
|
-
const f = ((_e = p.fields) != null ? _e : []).find((x) => x.id === own.fieldId);
|
|
10000
|
-
const o = (_f = f == null ? void 0 : f.options) == null ? void 0 : _f.find((x) => x.id === id);
|
|
10001
|
-
if (o) o.label = `${prefix}${(_g = o.label) != null ? _g : ""}${suffix}`.trim();
|
|
10837
|
+
const o = (_e = findMutableOption(p, id)) == null ? void 0 : _e.option;
|
|
10838
|
+
if (o) o.label = `${prefix}${(_f = o.label) != null ? _f : ""}${suffix}`.trim();
|
|
10002
10839
|
}
|
|
10003
10840
|
}
|
|
10004
10841
|
});
|
|
@@ -10151,6 +10988,57 @@ var Editor = class {
|
|
|
10151
10988
|
exclude(receiverId, idOrIds) {
|
|
10152
10989
|
return exclude(this.moduleCtx(), receiverId, idOrIds);
|
|
10153
10990
|
}
|
|
10991
|
+
setOptionEffect(triggerId, targetFieldId, effect) {
|
|
10992
|
+
return setOptionEffect(
|
|
10993
|
+
this.moduleCtx(),
|
|
10994
|
+
triggerId,
|
|
10995
|
+
targetFieldId,
|
|
10996
|
+
effect
|
|
10997
|
+
);
|
|
10998
|
+
}
|
|
10999
|
+
patchOptionEffect(triggerId, targetFieldId, patch) {
|
|
11000
|
+
return patchOptionEffect(
|
|
11001
|
+
this.moduleCtx(),
|
|
11002
|
+
triggerId,
|
|
11003
|
+
targetFieldId,
|
|
11004
|
+
patch
|
|
11005
|
+
);
|
|
11006
|
+
}
|
|
11007
|
+
clearOptionEffect(triggerId, targetFieldId) {
|
|
11008
|
+
return clearOptionEffect(this.moduleCtx(), triggerId, targetFieldId);
|
|
11009
|
+
}
|
|
11010
|
+
clearOptionEffectsForTrigger(triggerId) {
|
|
11011
|
+
return clearOptionEffectsForTrigger(this.moduleCtx(), triggerId);
|
|
11012
|
+
}
|
|
11013
|
+
clearOptionEffectsForTarget(targetFieldId) {
|
|
11014
|
+
return clearOptionEffectsForTarget(this.moduleCtx(), targetFieldId);
|
|
11015
|
+
}
|
|
11016
|
+
addOptionEffectOptions(triggerId, targetFieldId, kind, optionIds) {
|
|
11017
|
+
return addOptionEffectOptions(
|
|
11018
|
+
this.moduleCtx(),
|
|
11019
|
+
triggerId,
|
|
11020
|
+
targetFieldId,
|
|
11021
|
+
kind,
|
|
11022
|
+
optionIds
|
|
11023
|
+
);
|
|
11024
|
+
}
|
|
11025
|
+
removeOptionEffectOptions(triggerId, targetFieldId, kind, optionIds) {
|
|
11026
|
+
return removeOptionEffectOptions(
|
|
11027
|
+
this.moduleCtx(),
|
|
11028
|
+
triggerId,
|
|
11029
|
+
targetFieldId,
|
|
11030
|
+
kind,
|
|
11031
|
+
optionIds
|
|
11032
|
+
);
|
|
11033
|
+
}
|
|
11034
|
+
setOptionEffectForceVisible(triggerId, targetFieldId, forceVisible) {
|
|
11035
|
+
return setOptionEffectForceVisible(
|
|
11036
|
+
this.moduleCtx(),
|
|
11037
|
+
triggerId,
|
|
11038
|
+
targetFieldId,
|
|
11039
|
+
forceVisible
|
|
11040
|
+
);
|
|
11041
|
+
}
|
|
10154
11042
|
connect(kind, fromId, toId2) {
|
|
10155
11043
|
return connect(this.moduleCtx(), kind, fromId, toId2);
|
|
10156
11044
|
}
|
|
@@ -10519,11 +11407,10 @@ var Selection = class {
|
|
|
10519
11407
|
* What counts as a "button selection" (trigger key):
|
|
10520
11408
|
* - field key where the field has button === true (e.g. "f:dripfeed")
|
|
10521
11409
|
* - option key (e.g. "o:fast")
|
|
10522
|
-
* - composite key "fieldId::optionId" (e.g. "f:speed::o:fast")
|
|
10523
11410
|
*
|
|
10524
11411
|
* Grouping:
|
|
10525
11412
|
* - button-field trigger groups under its own fieldId
|
|
10526
|
-
* - option
|
|
11413
|
+
* - option trigger groups under the option's owning fieldId (from nodeMap)
|
|
10527
11414
|
*
|
|
10528
11415
|
* Deterministic:
|
|
10529
11416
|
* - preserves selection insertion order
|
|
@@ -10540,15 +11427,6 @@ var Selection = class {
|
|
|
10540
11427
|
};
|
|
10541
11428
|
for (const key of this.set) {
|
|
10542
11429
|
if (!key) continue;
|
|
10543
|
-
const idx = key.indexOf("::");
|
|
10544
|
-
if (idx !== -1) {
|
|
10545
|
-
const optionId = key.slice(idx + 2);
|
|
10546
|
-
const optRef = nodeMap.get(optionId);
|
|
10547
|
-
if ((optRef == null ? void 0 : optRef.kind) === "option" && typeof optRef.fieldId === "string") {
|
|
10548
|
-
push(optRef.fieldId, key);
|
|
10549
|
-
}
|
|
10550
|
-
continue;
|
|
10551
|
-
}
|
|
10552
11430
|
const ref = nodeMap.get(key);
|
|
10553
11431
|
if (!ref) continue;
|
|
10554
11432
|
if (ref.kind === "option" && typeof ref.fieldId === "string") {
|
|
@@ -10569,7 +11447,6 @@ var Selection = class {
|
|
|
10569
11447
|
* Returns only selection keys that are valid "trigger buttons":
|
|
10570
11448
|
* - field keys where field.button === true
|
|
10571
11449
|
* - option keys
|
|
10572
|
-
* - composite keys "fieldId::optionId" (validated by optionId)
|
|
10573
11450
|
* Excludes tags and non-button fields.
|
|
10574
11451
|
*/
|
|
10575
11452
|
selectedButtons() {
|
|
@@ -10585,13 +11462,6 @@ var Selection = class {
|
|
|
10585
11462
|
};
|
|
10586
11463
|
for (const key of this.set) {
|
|
10587
11464
|
if (!key) continue;
|
|
10588
|
-
const idx = key.indexOf("::");
|
|
10589
|
-
if (idx !== -1) {
|
|
10590
|
-
const optionId = key.slice(idx + 2);
|
|
10591
|
-
const optRef = nodeMap.get(optionId);
|
|
10592
|
-
if ((optRef == null ? void 0 : optRef.kind) === "option") push(key);
|
|
10593
|
-
continue;
|
|
10594
|
-
}
|
|
10595
11465
|
const ref = nodeMap.get(key);
|
|
10596
11466
|
if (!ref) continue;
|
|
10597
11467
|
if (ref.kind === "option") {
|
|
@@ -10630,17 +11500,7 @@ var Selection = class {
|
|
|
10630
11500
|
const direct = fields.find((x) => x.id === id);
|
|
10631
11501
|
if (direct) return direct;
|
|
10632
11502
|
if (this.builder.isOptionId(id)) {
|
|
10633
|
-
return fields
|
|
10634
|
-
(x) => {
|
|
10635
|
-
var _a2;
|
|
10636
|
-
return ((_a2 = x.options) != null ? _a2 : []).some((o) => o.id === id);
|
|
10637
|
-
}
|
|
10638
|
-
);
|
|
10639
|
-
}
|
|
10640
|
-
if (id.includes("::")) {
|
|
10641
|
-
const [fieldId] = id.split("::");
|
|
10642
|
-
if (!fieldId) return void 0;
|
|
10643
|
-
return fields.find((x) => x.id === fieldId);
|
|
11503
|
+
return findOptionOwnerField(fields, id);
|
|
10644
11504
|
}
|
|
10645
11505
|
return void 0;
|
|
10646
11506
|
};
|
|
@@ -10671,18 +11531,7 @@ var Selection = class {
|
|
|
10671
11531
|
}
|
|
10672
11532
|
for (const id of this.set) {
|
|
10673
11533
|
if (this.builder.isOptionId(id)) {
|
|
10674
|
-
const host = fields
|
|
10675
|
-
(x) => {
|
|
10676
|
-
var _a2;
|
|
10677
|
-
return ((_a2 = x.options) != null ? _a2 : []).some((o) => o.id === id);
|
|
10678
|
-
}
|
|
10679
|
-
);
|
|
10680
|
-
if (host == null ? void 0 : host.bind_id)
|
|
10681
|
-
return Array.isArray(host.bind_id) ? host.bind_id[0] : host.bind_id;
|
|
10682
|
-
}
|
|
10683
|
-
if (id.includes("::")) {
|
|
10684
|
-
const [fid] = id.split("::");
|
|
10685
|
-
const host = fields.find((x) => x.id === fid);
|
|
11534
|
+
const host = findOptionOwnerField(fields, id);
|
|
10686
11535
|
if (host == null ? void 0 : host.bind_id)
|
|
10687
11536
|
return Array.isArray(host.bind_id) ? host.bind_id[0] : host.bind_id;
|
|
10688
11537
|
}
|
|
@@ -10696,7 +11545,11 @@ var Selection = class {
|
|
|
10696
11545
|
const tagById = new Map(tags.map((t) => [t.id, t]));
|
|
10697
11546
|
const tag = tagById.get(tagId);
|
|
10698
11547
|
const selectedTriggerIds = this.selectedButtons();
|
|
10699
|
-
const
|
|
11548
|
+
const visibility = this.builder.resolveVisibility(
|
|
11549
|
+
tagId,
|
|
11550
|
+
selectedTriggerIds
|
|
11551
|
+
);
|
|
11552
|
+
const fieldIds = visibility.fieldIds;
|
|
10700
11553
|
const fieldById = new Map(fields.map((f) => [f.id, f]));
|
|
10701
11554
|
const visible = fieldIds.map((id) => fieldById.get(id)).filter(Boolean);
|
|
10702
11555
|
const parentTags = [];
|
|
@@ -10722,6 +11575,14 @@ var Selection = class {
|
|
|
10722
11575
|
let baseOverridden = false;
|
|
10723
11576
|
for (const selId of this.set) {
|
|
10724
11577
|
const opt = this.findOptionById(fields, selId);
|
|
11578
|
+
if (opt && !this.isSelectedOptionVisible(
|
|
11579
|
+
fields,
|
|
11580
|
+
selId,
|
|
11581
|
+
fieldIds,
|
|
11582
|
+
visibility.optionsByFieldId
|
|
11583
|
+
)) {
|
|
11584
|
+
continue;
|
|
11585
|
+
}
|
|
10725
11586
|
if ((opt == null ? void 0 : opt.service_id) != null) {
|
|
10726
11587
|
const role = (_d = opt.pricing_role) != null ? _d : "base";
|
|
10727
11588
|
const cap = (_e = resolve == null ? void 0 : resolve(opt.service_id)) != null ? _e : { id: opt.service_id };
|
|
@@ -10752,6 +11613,8 @@ var Selection = class {
|
|
|
10752
11613
|
tag,
|
|
10753
11614
|
fields: visible,
|
|
10754
11615
|
fieldIds,
|
|
11616
|
+
optionsByFieldId: visibility.optionsByFieldId,
|
|
11617
|
+
forcedFieldIds: visibility.forcedFieldIds,
|
|
10755
11618
|
parentTags,
|
|
10756
11619
|
childrenTags,
|
|
10757
11620
|
services
|
|
@@ -10775,21 +11638,19 @@ var Selection = class {
|
|
|
10775
11638
|
return baseOverridden;
|
|
10776
11639
|
}
|
|
10777
11640
|
findOptionById(fields, selId) {
|
|
10778
|
-
var _a, _b;
|
|
10779
11641
|
if (this.builder.isOptionId(selId)) {
|
|
10780
|
-
|
|
10781
|
-
|
|
10782
|
-
if (o) return o;
|
|
10783
|
-
}
|
|
10784
|
-
}
|
|
10785
|
-
if (selId.includes("::")) {
|
|
10786
|
-
const [fid, oid] = selId.split("::");
|
|
10787
|
-
const f = fields.find((x) => x.id === fid);
|
|
10788
|
-
const o = (_b = f == null ? void 0 : f.options) == null ? void 0 : _b.find((x) => x.id === oid || x.id === selId);
|
|
10789
|
-
if (o) return o;
|
|
11642
|
+
const field = findOptionOwnerField(fields, selId);
|
|
11643
|
+
return findFieldOption(field, selId);
|
|
10790
11644
|
}
|
|
10791
11645
|
return void 0;
|
|
10792
11646
|
}
|
|
11647
|
+
isSelectedOptionVisible(fields, selId, visibleFieldIds, optionsByFieldId) {
|
|
11648
|
+
const visibleFields = new Set(visibleFieldIds);
|
|
11649
|
+
const field = findOptionOwnerField(fields, selId);
|
|
11650
|
+
if (!field || !visibleFields.has(field.id)) return false;
|
|
11651
|
+
const allowed = optionsByFieldId[field.id];
|
|
11652
|
+
return !allowed || allowed.includes(selId);
|
|
11653
|
+
}
|
|
10793
11654
|
};
|
|
10794
11655
|
|
|
10795
11656
|
// src/react/canvas/api.ts
|