@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.js
CHANGED
|
@@ -332,6 +332,7 @@ function templateTime(template) {
|
|
|
332
332
|
return (_a = parseTimestamp(template.updatedAt)) != null ? _a : parseTimestamp(template.createdAt);
|
|
333
333
|
}
|
|
334
334
|
function shouldReplaceTemplates(params) {
|
|
335
|
+
var _a;
|
|
335
336
|
if (!params.requestedSince) return true;
|
|
336
337
|
if (!params.lastUpdatedAt) return false;
|
|
337
338
|
const requested = parseTimestamp(params.requestedSince);
|
|
@@ -339,7 +340,9 @@ function shouldReplaceTemplates(params) {
|
|
|
339
340
|
if (requested === void 0 || last === void 0) {
|
|
340
341
|
return false;
|
|
341
342
|
}
|
|
342
|
-
|
|
343
|
+
const currentTimes = ((_a = params.current) != null ? _a : []).map((template) => templateTime(template)).filter((time) => time !== void 0);
|
|
344
|
+
if (!currentTimes.length) return requested < last;
|
|
345
|
+
return requested < Math.min(...currentTimes);
|
|
343
346
|
}
|
|
344
347
|
function pickNewestTemplate(current, incoming) {
|
|
345
348
|
const currentTime = templateTime(current);
|
|
@@ -347,7 +350,8 @@ function pickNewestTemplate(current, incoming) {
|
|
|
347
350
|
if (currentTime !== void 0 && incomingTime !== void 0) {
|
|
348
351
|
return incomingTime >= currentTime ? incoming : current;
|
|
349
352
|
}
|
|
350
|
-
if (currentTime === void 0 && incomingTime !== void 0)
|
|
353
|
+
if (currentTime === void 0 && incomingTime !== void 0)
|
|
354
|
+
return incoming;
|
|
351
355
|
if (currentTime !== void 0 && incomingTime === void 0) return current;
|
|
352
356
|
return incoming;
|
|
353
357
|
}
|
|
@@ -420,7 +424,8 @@ function useTemplatesSlice(params) {
|
|
|
420
424
|
setTemplates((current) => {
|
|
421
425
|
const replace = shouldReplaceTemplates({
|
|
422
426
|
requestedSince,
|
|
423
|
-
lastUpdatedAt: current.updatedAt
|
|
427
|
+
lastUpdatedAt: current.updatedAt,
|
|
428
|
+
current: current.data
|
|
424
429
|
});
|
|
425
430
|
return {
|
|
426
431
|
data: replace ? res.value : mergeTemplates(current.data, res.value, {
|
|
@@ -519,7 +524,9 @@ function useTemplatesSlice(params) {
|
|
|
519
524
|
var _a, _b;
|
|
520
525
|
return {
|
|
521
526
|
...current,
|
|
522
|
-
data: (_b = (_a = current.data) == null ? void 0 : _a.filter(
|
|
527
|
+
data: (_b = (_a = current.data) == null ? void 0 : _a.filter(
|
|
528
|
+
(template) => template.id !== id
|
|
529
|
+
)) != null ? _b : current.data,
|
|
523
530
|
updatedAt: deleteRefreshSince
|
|
524
531
|
};
|
|
525
532
|
});
|
|
@@ -3590,6 +3597,9 @@ function normalise(input, opts = {}) {
|
|
|
3590
3597
|
const excludes_for_buttons = toStringArrayMap(
|
|
3591
3598
|
obj.excludes_for_buttons
|
|
3592
3599
|
);
|
|
3600
|
+
const option_effects_for_buttons = toOptionEffectMap(
|
|
3601
|
+
obj.option_effects_for_buttons
|
|
3602
|
+
);
|
|
3593
3603
|
const orderKinds = toStringMap(obj.orderKinds);
|
|
3594
3604
|
const notices = toNoticeArray(obj.notices);
|
|
3595
3605
|
let filters = rawFilters.map((t) => coerceTag(t, constraints));
|
|
@@ -3605,6 +3615,9 @@ function normalise(input, opts = {}) {
|
|
|
3605
3615
|
...isNonEmpty(orderKinds) && { orderKinds },
|
|
3606
3616
|
...isNonEmpty(includes_for_buttons) && { includes_for_buttons },
|
|
3607
3617
|
...isNonEmpty(excludes_for_buttons) && { excludes_for_buttons },
|
|
3618
|
+
...isNonEmpty(option_effects_for_buttons) && {
|
|
3619
|
+
option_effects_for_buttons
|
|
3620
|
+
},
|
|
3608
3621
|
...fallbacks && (isNonEmpty(fallbacks.nodes) || isNonEmpty(fallbacks.global)) && {
|
|
3609
3622
|
fallbacks
|
|
3610
3623
|
},
|
|
@@ -3759,6 +3772,7 @@ function coerceOption(src, inheritRole) {
|
|
|
3759
3772
|
const value = typeof src.value === "string" || typeof src.value === "number" ? src.value : void 0;
|
|
3760
3773
|
const pricing_role = src.pricing_role === "utility" || src.pricing_role === "base" ? src.pricing_role : inheritRole;
|
|
3761
3774
|
const meta = src.meta && typeof src.meta === "object" ? src.meta : void 0;
|
|
3775
|
+
const children = Array.isArray(src.children) ? src.children.map((child) => coerceOption(child, pricing_role)) : void 0;
|
|
3762
3776
|
const option = {
|
|
3763
3777
|
id: "",
|
|
3764
3778
|
label: "",
|
|
@@ -3767,7 +3781,8 @@ function coerceOption(src, inheritRole) {
|
|
|
3767
3781
|
...value !== void 0 && { value },
|
|
3768
3782
|
...service_id !== void 0 && { service_id },
|
|
3769
3783
|
pricing_role,
|
|
3770
|
-
...meta && { meta }
|
|
3784
|
+
...meta && { meta },
|
|
3785
|
+
...children && children.length && { children }
|
|
3771
3786
|
};
|
|
3772
3787
|
return option;
|
|
3773
3788
|
}
|
|
@@ -3832,6 +3847,35 @@ function toStringArrayMap(src) {
|
|
|
3832
3847
|
}
|
|
3833
3848
|
return Object.keys(out).length ? out : void 0;
|
|
3834
3849
|
}
|
|
3850
|
+
function toOptionEffectMap(src) {
|
|
3851
|
+
var _a, _b;
|
|
3852
|
+
if (!src || typeof src !== "object") return void 0;
|
|
3853
|
+
const out = {};
|
|
3854
|
+
for (const [triggerId, rawTargets] of Object.entries(src)) {
|
|
3855
|
+
if (!triggerId || !rawTargets || typeof rawTargets !== "object") {
|
|
3856
|
+
continue;
|
|
3857
|
+
}
|
|
3858
|
+
const targets = {};
|
|
3859
|
+
for (const [fieldId, rawEffect] of Object.entries(rawTargets)) {
|
|
3860
|
+
if (!fieldId || !rawEffect || typeof rawEffect !== "object") {
|
|
3861
|
+
continue;
|
|
3862
|
+
}
|
|
3863
|
+
const effect = rawEffect;
|
|
3864
|
+
const include2 = toStringArray(effect.include);
|
|
3865
|
+
const exclude2 = toStringArray(effect.exclude);
|
|
3866
|
+
const next = {
|
|
3867
|
+
...effect.forceVisible === true ? { forceVisible: true } : {},
|
|
3868
|
+
...include2.length ? { include: dedupe(include2) } : {},
|
|
3869
|
+
...exclude2.length ? { exclude: dedupe(exclude2) } : {}
|
|
3870
|
+
};
|
|
3871
|
+
if (next.forceVisible === true || ((_a = next.include) == null ? void 0 : _a.length) || ((_b = next.exclude) == null ? void 0 : _b.length)) {
|
|
3872
|
+
targets[fieldId] = next;
|
|
3873
|
+
}
|
|
3874
|
+
}
|
|
3875
|
+
if (Object.keys(targets).length) out[triggerId] = targets;
|
|
3876
|
+
}
|
|
3877
|
+
return Object.keys(out).length ? out : void 0;
|
|
3878
|
+
}
|
|
3835
3879
|
function toStringArray(v) {
|
|
3836
3880
|
if (!Array.isArray(v)) return [];
|
|
3837
3881
|
return v.map((x) => String(x)).filter((s) => !!s && s.trim().length > 0);
|
|
@@ -3906,6 +3950,57 @@ function normalizeFieldValidation(input) {
|
|
|
3906
3950
|
return one ? [one] : void 0;
|
|
3907
3951
|
}
|
|
3908
3952
|
|
|
3953
|
+
// src/core/options.ts
|
|
3954
|
+
function walkFieldOptions(field) {
|
|
3955
|
+
const out = [];
|
|
3956
|
+
const visit = (options, depth, parentId) => {
|
|
3957
|
+
for (const option of options != null ? options : []) {
|
|
3958
|
+
out.push({
|
|
3959
|
+
field,
|
|
3960
|
+
fieldId: field.id,
|
|
3961
|
+
option,
|
|
3962
|
+
optionId: option.id,
|
|
3963
|
+
depth,
|
|
3964
|
+
parentId
|
|
3965
|
+
});
|
|
3966
|
+
visit(option.children, depth + 1, option.id);
|
|
3967
|
+
}
|
|
3968
|
+
};
|
|
3969
|
+
visit(field.options, 0);
|
|
3970
|
+
return out;
|
|
3971
|
+
}
|
|
3972
|
+
function fieldOptionIds(field) {
|
|
3973
|
+
return walkFieldOptions(field).map((visit) => visit.optionId);
|
|
3974
|
+
}
|
|
3975
|
+
function fieldOptionIdSet(field) {
|
|
3976
|
+
return new Set(fieldOptionIds(field));
|
|
3977
|
+
}
|
|
3978
|
+
function findFieldOption(field, optionId) {
|
|
3979
|
+
var _a;
|
|
3980
|
+
if (!field) return void 0;
|
|
3981
|
+
return (_a = walkFieldOptions(field).find((visit) => visit.optionId === optionId)) == null ? void 0 : _a.option;
|
|
3982
|
+
}
|
|
3983
|
+
function findOptionOwnerField(fields, optionId) {
|
|
3984
|
+
for (const field of fields) {
|
|
3985
|
+
if (findFieldOption(field, optionId)) return field;
|
|
3986
|
+
}
|
|
3987
|
+
return void 0;
|
|
3988
|
+
}
|
|
3989
|
+
function optionOwnerMap(fields) {
|
|
3990
|
+
const out = /* @__PURE__ */ new Map();
|
|
3991
|
+
for (const field of fields) {
|
|
3992
|
+
for (const visit of walkFieldOptions(field)) {
|
|
3993
|
+
if (!out.has(visit.optionId)) {
|
|
3994
|
+
out.set(visit.optionId, {
|
|
3995
|
+
fieldId: field.id,
|
|
3996
|
+
option: visit.option
|
|
3997
|
+
});
|
|
3998
|
+
}
|
|
3999
|
+
}
|
|
4000
|
+
}
|
|
4001
|
+
return out;
|
|
4002
|
+
}
|
|
4003
|
+
|
|
3909
4004
|
// src/core/validate/shared.ts
|
|
3910
4005
|
function isFiniteNumber(v) {
|
|
3911
4006
|
return typeof v === "number" && Number.isFinite(v);
|
|
@@ -3914,8 +4009,9 @@ function isServiceIdRef(v) {
|
|
|
3914
4009
|
return typeof v === "string" && v.trim().length > 0 || typeof v === "number" && Number.isFinite(v);
|
|
3915
4010
|
}
|
|
3916
4011
|
function hasAnyServiceOption(f) {
|
|
3917
|
-
|
|
3918
|
-
|
|
4012
|
+
return walkFieldOptions(f).some(
|
|
4013
|
+
(visit) => isServiceIdRef(visit.option.service_id)
|
|
4014
|
+
);
|
|
3919
4015
|
}
|
|
3920
4016
|
function getByPath(obj, path) {
|
|
3921
4017
|
if (!path) return void 0;
|
|
@@ -4004,14 +4100,14 @@ function withAffected(details, ids) {
|
|
|
4004
4100
|
|
|
4005
4101
|
// src/core/node-map.ts
|
|
4006
4102
|
function buildNodeMap(props) {
|
|
4007
|
-
var _a, _b
|
|
4103
|
+
var _a, _b;
|
|
4008
4104
|
const map = /* @__PURE__ */ new Map();
|
|
4009
4105
|
for (const t of (_a = props.filters) != null ? _a : []) {
|
|
4010
4106
|
if (!map.has(t.id)) map.set(t.id, { kind: "tag", id: t.id, node: t });
|
|
4011
4107
|
}
|
|
4012
4108
|
for (const f of (_b = props.fields) != null ? _b : []) {
|
|
4013
4109
|
if (!map.has(f.id)) map.set(f.id, { kind: "field", id: f.id, node: f });
|
|
4014
|
-
for (const o of (
|
|
4110
|
+
for (const { option: o } of walkFieldOptions(f)) {
|
|
4015
4111
|
if (!map.has(o.id))
|
|
4016
4112
|
map.set(o.id, {
|
|
4017
4113
|
kind: "option",
|
|
@@ -4024,12 +4120,6 @@ function buildNodeMap(props) {
|
|
|
4024
4120
|
return map;
|
|
4025
4121
|
}
|
|
4026
4122
|
function resolveTrigger(trigger, nodeMap) {
|
|
4027
|
-
const idx = trigger.indexOf("::");
|
|
4028
|
-
if (idx !== -1) {
|
|
4029
|
-
const fieldId = trigger.slice(0, idx);
|
|
4030
|
-
const optionId = trigger.slice(idx + 2);
|
|
4031
|
-
return { kind: "composite", triggerKey: trigger, fieldId, optionId };
|
|
4032
|
-
}
|
|
4033
4123
|
const direct = nodeMap.get(trigger);
|
|
4034
4124
|
if (!direct) return void 0;
|
|
4035
4125
|
if (direct.kind === "option") {
|
|
@@ -4081,11 +4171,6 @@ function visibleFieldIdsUnder(props, tagId, opts = {}) {
|
|
|
4081
4171
|
const ownerDepthForTriggerKey = (triggerKey) => {
|
|
4082
4172
|
const t = resolveTrigger(triggerKey, nodeMap);
|
|
4083
4173
|
if (!t) return void 0;
|
|
4084
|
-
if (t.kind === "composite") {
|
|
4085
|
-
const f = fieldById.get(t.fieldId);
|
|
4086
|
-
if (!f) return void 0;
|
|
4087
|
-
return ownerDepthForField(f);
|
|
4088
|
-
}
|
|
4089
4174
|
if (t.kind === "field") {
|
|
4090
4175
|
const f = fieldById.get(t.id);
|
|
4091
4176
|
if (!f || f.button !== true) return void 0;
|
|
@@ -4168,6 +4253,84 @@ function visibleFieldsUnder(props, tagId, opts = {}) {
|
|
|
4168
4253
|
const fieldById = new Map(((_a = props.fields) != null ? _a : []).map((f) => [f.id, f]));
|
|
4169
4254
|
return ids.map((id) => fieldById.get(id)).filter(Boolean);
|
|
4170
4255
|
}
|
|
4256
|
+
function resolveVisibility(props, tagId, selectedKeys) {
|
|
4257
|
+
var _a, _b, _c, _d;
|
|
4258
|
+
const selected = new Set(selectedKeys != null ? selectedKeys : []);
|
|
4259
|
+
const baseFieldIds = visibleFieldIdsUnder(props, tagId, { selectedKeys: selected });
|
|
4260
|
+
const fieldById = new Map(((_a = props.fields) != null ? _a : []).map((field) => [field.id, field]));
|
|
4261
|
+
const visible = new Set(baseFieldIds);
|
|
4262
|
+
const forced = /* @__PURE__ */ new Set();
|
|
4263
|
+
const optionsByFieldId = {};
|
|
4264
|
+
const optionIdsByFieldId = /* @__PURE__ */ new Map();
|
|
4265
|
+
const getOptionIds = (field) => {
|
|
4266
|
+
let ids = optionIdsByFieldId.get(field.id);
|
|
4267
|
+
if (!ids) {
|
|
4268
|
+
ids = fieldOptionIds(field);
|
|
4269
|
+
optionIdsByFieldId.set(field.id, ids);
|
|
4270
|
+
}
|
|
4271
|
+
return ids;
|
|
4272
|
+
};
|
|
4273
|
+
const ensureOptions = (field) => {
|
|
4274
|
+
const ids = getOptionIds(field);
|
|
4275
|
+
if (!ids.length) return void 0;
|
|
4276
|
+
if (!optionsByFieldId[field.id]) optionsByFieldId[field.id] = [...ids];
|
|
4277
|
+
return optionsByFieldId[field.id];
|
|
4278
|
+
};
|
|
4279
|
+
for (const fieldId of baseFieldIds) {
|
|
4280
|
+
const field = fieldById.get(fieldId);
|
|
4281
|
+
if (field) ensureOptions(field);
|
|
4282
|
+
}
|
|
4283
|
+
const effects = (_b = props.option_effects_for_buttons) != null ? _b : {};
|
|
4284
|
+
for (const triggerId of selected) {
|
|
4285
|
+
const targetRules = effects[triggerId];
|
|
4286
|
+
if (!targetRules) continue;
|
|
4287
|
+
for (const [targetFieldId, rule] of Object.entries(targetRules)) {
|
|
4288
|
+
const field = fieldById.get(targetFieldId);
|
|
4289
|
+
if (!field) continue;
|
|
4290
|
+
const isVisible = visible.has(targetFieldId);
|
|
4291
|
+
if (!isVisible && rule.forceVisible !== true) continue;
|
|
4292
|
+
if (!isVisible && rule.forceVisible === true) {
|
|
4293
|
+
visible.add(targetFieldId);
|
|
4294
|
+
forced.add(targetFieldId);
|
|
4295
|
+
}
|
|
4296
|
+
const orderedOptionIds = getOptionIds(field);
|
|
4297
|
+
if (!orderedOptionIds.length) continue;
|
|
4298
|
+
const known = new Set(orderedOptionIds);
|
|
4299
|
+
let allowed = (_c = optionsByFieldId[targetFieldId]) != null ? _c : [...orderedOptionIds];
|
|
4300
|
+
if (Array.isArray(rule.include) && rule.include.length) {
|
|
4301
|
+
const include2 = new Set(
|
|
4302
|
+
rule.include.filter((optionId) => known.has(optionId))
|
|
4303
|
+
);
|
|
4304
|
+
allowed = orderedOptionIds.filter(
|
|
4305
|
+
(optionId) => include2.has(optionId) && allowed.includes(optionId)
|
|
4306
|
+
);
|
|
4307
|
+
}
|
|
4308
|
+
if (Array.isArray(rule.exclude) && rule.exclude.length) {
|
|
4309
|
+
const exclude2 = new Set(
|
|
4310
|
+
rule.exclude.filter((optionId) => known.has(optionId))
|
|
4311
|
+
);
|
|
4312
|
+
allowed = allowed.filter((optionId) => !exclude2.has(optionId));
|
|
4313
|
+
}
|
|
4314
|
+
optionsByFieldId[targetFieldId] = allowed;
|
|
4315
|
+
}
|
|
4316
|
+
}
|
|
4317
|
+
const visibleFieldIds = baseFieldIds.filter((fieldId) => visible.has(fieldId));
|
|
4318
|
+
const seen = new Set(visibleFieldIds);
|
|
4319
|
+
for (const field of (_d = props.fields) != null ? _d : []) {
|
|
4320
|
+
if (!visible.has(field.id) || seen.has(field.id)) continue;
|
|
4321
|
+
seen.add(field.id);
|
|
4322
|
+
visibleFieldIds.push(field.id);
|
|
4323
|
+
ensureOptions(field);
|
|
4324
|
+
}
|
|
4325
|
+
for (const fieldId of Object.keys(optionsByFieldId)) {
|
|
4326
|
+
if (!visible.has(fieldId)) delete optionsByFieldId[fieldId];
|
|
4327
|
+
}
|
|
4328
|
+
return {
|
|
4329
|
+
fieldIds: visibleFieldIds,
|
|
4330
|
+
optionsByFieldId,
|
|
4331
|
+
forcedFieldIds: visibleFieldIds.filter((fieldId) => forced.has(fieldId))
|
|
4332
|
+
};
|
|
4333
|
+
}
|
|
4171
4334
|
|
|
4172
4335
|
// src/core/validate/steps/visibility.ts
|
|
4173
4336
|
function createFieldsVisibleUnder(v) {
|
|
@@ -4185,7 +4348,6 @@ function resolveRootTags(tags) {
|
|
|
4185
4348
|
return roots.length ? roots : tags.slice(0, 1);
|
|
4186
4349
|
}
|
|
4187
4350
|
function collectSelectableTriggersInContext(v, tagId, selectedKeys, effectfulKeys) {
|
|
4188
|
-
var _a;
|
|
4189
4351
|
const visible = visibleFieldsUnder(v.props, tagId, {
|
|
4190
4352
|
selectedKeys
|
|
4191
4353
|
});
|
|
@@ -4195,7 +4357,7 @@ function collectSelectableTriggersInContext(v, tagId, selectedKeys, effectfulKey
|
|
|
4195
4357
|
const t = f.id;
|
|
4196
4358
|
if (effectfulKeys.has(t)) triggers.push(t);
|
|
4197
4359
|
}
|
|
4198
|
-
for (const o of (
|
|
4360
|
+
for (const { option: o } of walkFieldOptions(f)) {
|
|
4199
4361
|
const t = o.id;
|
|
4200
4362
|
if (effectfulKeys.has(t)) triggers.push(t);
|
|
4201
4363
|
}
|
|
@@ -4204,7 +4366,7 @@ function collectSelectableTriggersInContext(v, tagId, selectedKeys, effectfulKey
|
|
|
4204
4366
|
return triggers;
|
|
4205
4367
|
}
|
|
4206
4368
|
function runVisibilityRulesOnce(v) {
|
|
4207
|
-
var _a, _b, _c, _d
|
|
4369
|
+
var _a, _b, _c, _d;
|
|
4208
4370
|
for (const t of v.tags) {
|
|
4209
4371
|
const visible = v.fieldsVisibleUnder(t.id);
|
|
4210
4372
|
const seen = /* @__PURE__ */ new Map();
|
|
@@ -4254,9 +4416,9 @@ function runVisibilityRulesOnce(v) {
|
|
|
4254
4416
|
let hasUtility = false;
|
|
4255
4417
|
const utilityOptionIds = [];
|
|
4256
4418
|
for (const f of visible) {
|
|
4257
|
-
for (const o of (
|
|
4419
|
+
for (const { option: o } of walkFieldOptions(f)) {
|
|
4258
4420
|
if (!isServiceIdRef(o.service_id)) continue;
|
|
4259
|
-
const role = (
|
|
4421
|
+
const role = (_d = (_c = o.pricing_role) != null ? _c : f.pricing_role) != null ? _d : "base";
|
|
4260
4422
|
if (role === "base") hasBase = true;
|
|
4261
4423
|
else if (role === "utility") {
|
|
4262
4424
|
hasUtility = true;
|
|
@@ -4297,7 +4459,7 @@ function dedupeErrorsInPlace(v, startIndex) {
|
|
|
4297
4459
|
v.errors.splice(startIndex, v.errors.length - startIndex, ...kept);
|
|
4298
4460
|
}
|
|
4299
4461
|
function validateVisibility(v, options = {}) {
|
|
4300
|
-
var _a, _b, _c, _d, _e;
|
|
4462
|
+
var _a, _b, _c, _d, _e, _f;
|
|
4301
4463
|
v.simulatedVisibilityContexts = [];
|
|
4302
4464
|
const simulate = options.simulate === true;
|
|
4303
4465
|
if (!simulate) {
|
|
@@ -4322,10 +4484,13 @@ function validateVisibility(v, options = {}) {
|
|
|
4322
4484
|
for (const key of Object.keys((_d = v.props.excludes_for_buttons) != null ? _d : {})) {
|
|
4323
4485
|
effectfulKeys.add(key);
|
|
4324
4486
|
}
|
|
4487
|
+
for (const key of Object.keys((_e = v.props.option_effects_for_buttons) != null ? _e : {})) {
|
|
4488
|
+
effectfulKeys.add(key);
|
|
4489
|
+
}
|
|
4325
4490
|
}
|
|
4326
4491
|
const roots = resolveRootTags(v.tags);
|
|
4327
4492
|
const rootTags = options.simulateAllRoots ? roots : roots.slice(0, 1);
|
|
4328
|
-
const originalSelected = new Set((
|
|
4493
|
+
const originalSelected = new Set((_f = v.selectedKeys) != null ? _f : []);
|
|
4329
4494
|
const errorsStart = v.errors.length;
|
|
4330
4495
|
const visited = /* @__PURE__ */ new Set();
|
|
4331
4496
|
const seenContexts = /* @__PURE__ */ new Set();
|
|
@@ -4466,7 +4631,7 @@ function validateStructure(v) {
|
|
|
4466
4631
|
|
|
4467
4632
|
// src/core/validate/steps/identity.ts
|
|
4468
4633
|
function validateIdentity(v) {
|
|
4469
|
-
var _a
|
|
4634
|
+
var _a;
|
|
4470
4635
|
const tags = v.tags;
|
|
4471
4636
|
const fields = v.fields;
|
|
4472
4637
|
{
|
|
@@ -4566,7 +4731,7 @@ function validateIdentity(v) {
|
|
|
4566
4731
|
}
|
|
4567
4732
|
}
|
|
4568
4733
|
for (const f of fields) {
|
|
4569
|
-
for (const o of (
|
|
4734
|
+
for (const { option: o } of walkFieldOptions(f)) {
|
|
4570
4735
|
if (!o.label || !o.label.trim()) {
|
|
4571
4736
|
v.errors.push({
|
|
4572
4737
|
code: "label_missing",
|
|
@@ -4581,25 +4746,11 @@ function validateIdentity(v) {
|
|
|
4581
4746
|
}
|
|
4582
4747
|
|
|
4583
4748
|
// src/core/validate/steps/option-maps.ts
|
|
4584
|
-
function parseFieldOptionKey(key) {
|
|
4585
|
-
const idx = key.indexOf("::");
|
|
4586
|
-
if (idx === -1) return null;
|
|
4587
|
-
const fieldId = key.slice(0, idx).trim();
|
|
4588
|
-
const optionId = key.slice(idx + 2).trim();
|
|
4589
|
-
if (!fieldId || !optionId) return null;
|
|
4590
|
-
return { fieldId, optionId };
|
|
4591
|
-
}
|
|
4592
|
-
function hasOption(v, fid, oid) {
|
|
4593
|
-
var _a;
|
|
4594
|
-
const f = v.fieldById.get(fid);
|
|
4595
|
-
if (!f) return false;
|
|
4596
|
-
return !!((_a = f.options) != null ? _a : []).find((o) => o.id === oid);
|
|
4597
|
-
}
|
|
4598
4749
|
function validateOptionMaps(v) {
|
|
4599
|
-
var _a, _b;
|
|
4750
|
+
var _a, _b, _c;
|
|
4600
4751
|
const incMap = (_a = v.props.includes_for_buttons) != null ? _a : {};
|
|
4601
4752
|
const excMap = (_b = v.props.excludes_for_buttons) != null ? _b : {};
|
|
4602
|
-
const badKeyMessage = (key) => `Invalid trigger-map key "${key}". Expected a known
|
|
4753
|
+
const badKeyMessage = (key) => `Invalid trigger-map key "${key}". Expected a known option id or button-field id.`;
|
|
4603
4754
|
const validateTriggerKey = (key) => {
|
|
4604
4755
|
const ref = v.nodeMap.get(key);
|
|
4605
4756
|
if (ref) {
|
|
@@ -4618,19 +4769,7 @@ function validateOptionMaps(v) {
|
|
|
4618
4769
|
}
|
|
4619
4770
|
return { ok: false, nodeId: ref.id, affected: [ref.id] };
|
|
4620
4771
|
}
|
|
4621
|
-
|
|
4622
|
-
if (!p) return { ok: false };
|
|
4623
|
-
if (!hasOption(v, p.fieldId, p.optionId))
|
|
4624
|
-
return {
|
|
4625
|
-
ok: false,
|
|
4626
|
-
nodeId: p.fieldId,
|
|
4627
|
-
affected: [p.fieldId, p.optionId]
|
|
4628
|
-
};
|
|
4629
|
-
return {
|
|
4630
|
-
ok: true,
|
|
4631
|
-
nodeId: p.fieldId,
|
|
4632
|
-
affected: [p.fieldId, p.optionId]
|
|
4633
|
-
};
|
|
4772
|
+
return { ok: false };
|
|
4634
4773
|
};
|
|
4635
4774
|
for (const k of Object.keys(incMap)) {
|
|
4636
4775
|
const r = validateTriggerKey(k);
|
|
@@ -4656,6 +4795,57 @@ function validateOptionMaps(v) {
|
|
|
4656
4795
|
});
|
|
4657
4796
|
}
|
|
4658
4797
|
}
|
|
4798
|
+
const effectMap = (_c = v.props.option_effects_for_buttons) != null ? _c : {};
|
|
4799
|
+
for (const [triggerKey, targets] of Object.entries(effectMap)) {
|
|
4800
|
+
const trigger = validateTriggerKey(triggerKey);
|
|
4801
|
+
if (!trigger.ok) {
|
|
4802
|
+
v.errors.push({
|
|
4803
|
+
code: "bad_option_effect_key",
|
|
4804
|
+
severity: "error",
|
|
4805
|
+
message: badKeyMessage(triggerKey),
|
|
4806
|
+
nodeId: trigger.nodeId,
|
|
4807
|
+
details: withAffected({ key: triggerKey }, trigger.affected)
|
|
4808
|
+
});
|
|
4809
|
+
}
|
|
4810
|
+
for (const [targetFieldId, effect] of Object.entries(targets != null ? targets : {})) {
|
|
4811
|
+
const field = v.fieldById.get(targetFieldId);
|
|
4812
|
+
if (!field) {
|
|
4813
|
+
v.errors.push({
|
|
4814
|
+
code: "bad_option_effect_target",
|
|
4815
|
+
severity: "error",
|
|
4816
|
+
message: `Option effect trigger "${triggerKey}" targets unknown field "${targetFieldId}".`,
|
|
4817
|
+
details: withAffected(
|
|
4818
|
+
{ key: triggerKey, targetFieldId },
|
|
4819
|
+
trigger.affected
|
|
4820
|
+
)
|
|
4821
|
+
});
|
|
4822
|
+
continue;
|
|
4823
|
+
}
|
|
4824
|
+
const validOptionIds = fieldOptionIdSet(field);
|
|
4825
|
+
const checkTargetOptions = (kind, optionIds) => {
|
|
4826
|
+
for (const optionId of optionIds != null ? optionIds : []) {
|
|
4827
|
+
if (validOptionIds.has(optionId)) continue;
|
|
4828
|
+
v.errors.push({
|
|
4829
|
+
code: "bad_option_effect_option",
|
|
4830
|
+
severity: "error",
|
|
4831
|
+
message: `Option effect trigger "${triggerKey}" references unknown ${kind} option "${optionId}" for field "${targetFieldId}".`,
|
|
4832
|
+
nodeId: targetFieldId,
|
|
4833
|
+
details: withAffected(
|
|
4834
|
+
{
|
|
4835
|
+
key: triggerKey,
|
|
4836
|
+
targetFieldId,
|
|
4837
|
+
optionId,
|
|
4838
|
+
kind
|
|
4839
|
+
},
|
|
4840
|
+
[targetFieldId, optionId]
|
|
4841
|
+
)
|
|
4842
|
+
});
|
|
4843
|
+
}
|
|
4844
|
+
};
|
|
4845
|
+
checkTargetOptions("include", effect == null ? void 0 : effect.include);
|
|
4846
|
+
checkTargetOptions("exclude", effect == null ? void 0 : effect.exclude);
|
|
4847
|
+
}
|
|
4848
|
+
}
|
|
4659
4849
|
for (const k of Object.keys(incMap)) {
|
|
4660
4850
|
if (!(k in excMap)) continue;
|
|
4661
4851
|
const r = validateTriggerKey(k);
|
|
@@ -4669,27 +4859,231 @@ function validateOptionMaps(v) {
|
|
|
4669
4859
|
}
|
|
4670
4860
|
}
|
|
4671
4861
|
|
|
4672
|
-
// src/
|
|
4673
|
-
|
|
4674
|
-
|
|
4675
|
-
const
|
|
4676
|
-
if (
|
|
4677
|
-
|
|
4678
|
-
|
|
4679
|
-
|
|
4680
|
-
|
|
4681
|
-
|
|
4682
|
-
|
|
4862
|
+
// src/core/validate/steps/visibility-cycles.ts
|
|
4863
|
+
var MAX_VISIBILITY_CYCLE_DEPTH = 20;
|
|
4864
|
+
function validateVisibilityCycles(v) {
|
|
4865
|
+
const triggerById = buildTriggerIndex(v.fields);
|
|
4866
|
+
if (!triggerById.size) return;
|
|
4867
|
+
const fieldTriggers = buildFieldTriggerIndex(v.fields);
|
|
4868
|
+
const revealTargetsByTrigger = buildRevealIndex(v, triggerById);
|
|
4869
|
+
const reported = /* @__PURE__ */ new Set();
|
|
4870
|
+
for (const rootTriggerId of Array.from(triggerById.keys()).sort()) {
|
|
4871
|
+
const required = makeRequiredState(triggerById, [rootTriggerId]);
|
|
4872
|
+
walkFromTrigger({
|
|
4873
|
+
v,
|
|
4874
|
+
triggerById,
|
|
4875
|
+
fieldTriggers,
|
|
4876
|
+
revealTargetsByTrigger,
|
|
4877
|
+
rootTriggerId,
|
|
4878
|
+
currentTriggerId: rootTriggerId,
|
|
4879
|
+
required,
|
|
4880
|
+
path: [rootTriggerId],
|
|
4881
|
+
visited: /* @__PURE__ */ new Set(),
|
|
4882
|
+
reported,
|
|
4883
|
+
depth: 0
|
|
4884
|
+
});
|
|
4885
|
+
}
|
|
4886
|
+
}
|
|
4887
|
+
function buildTriggerIndex(fields) {
|
|
4888
|
+
const out = /* @__PURE__ */ new Map();
|
|
4889
|
+
const owners = optionOwnerMap(fields);
|
|
4890
|
+
for (const field of fields) {
|
|
4891
|
+
if (field.button === true) {
|
|
4892
|
+
out.set(field.id, {
|
|
4893
|
+
kind: "field",
|
|
4894
|
+
id: field.id,
|
|
4895
|
+
ownerFieldId: field.id
|
|
4896
|
+
});
|
|
4897
|
+
}
|
|
4898
|
+
}
|
|
4899
|
+
for (const [optionId, owner] of owners) {
|
|
4900
|
+
out.set(optionId, {
|
|
4901
|
+
kind: "option",
|
|
4902
|
+
id: optionId,
|
|
4903
|
+
ownerFieldId: owner.fieldId
|
|
4904
|
+
});
|
|
4905
|
+
}
|
|
4906
|
+
return out;
|
|
4907
|
+
}
|
|
4908
|
+
function buildFieldTriggerIndex(fields) {
|
|
4909
|
+
const out = /* @__PURE__ */ new Map();
|
|
4910
|
+
for (const field of fields) {
|
|
4911
|
+
const triggers = [];
|
|
4912
|
+
if (field.button === true) triggers.push(field.id);
|
|
4913
|
+
for (const visit of walkFieldOptions(field)) {
|
|
4914
|
+
triggers.push(visit.optionId);
|
|
4915
|
+
}
|
|
4916
|
+
out.set(field.id, triggers);
|
|
4917
|
+
}
|
|
4918
|
+
return out;
|
|
4919
|
+
}
|
|
4920
|
+
function buildRevealIndex(v, triggerById) {
|
|
4921
|
+
var _a, _b;
|
|
4922
|
+
const out = /* @__PURE__ */ new Map();
|
|
4923
|
+
const addReveal = (triggerId, targetFieldId) => {
|
|
4924
|
+
var _a2;
|
|
4925
|
+
if (!triggerById.has(triggerId)) return;
|
|
4926
|
+
if (!v.fieldById.has(targetFieldId)) return;
|
|
4927
|
+
const set = (_a2 = out.get(triggerId)) != null ? _a2 : /* @__PURE__ */ new Set();
|
|
4928
|
+
set.add(targetFieldId);
|
|
4929
|
+
out.set(triggerId, set);
|
|
4930
|
+
};
|
|
4931
|
+
for (const [triggerId, targetIds] of Object.entries(
|
|
4932
|
+
(_a = v.props.includes_for_buttons) != null ? _a : {}
|
|
4933
|
+
)) {
|
|
4934
|
+
for (const targetId of targetIds != null ? targetIds : []) addReveal(triggerId, targetId);
|
|
4935
|
+
}
|
|
4936
|
+
for (const [triggerId, targets] of Object.entries(
|
|
4937
|
+
(_b = v.props.option_effects_for_buttons) != null ? _b : {}
|
|
4938
|
+
)) {
|
|
4939
|
+
for (const [targetFieldId, effect] of Object.entries(targets != null ? targets : {})) {
|
|
4940
|
+
if ((effect == null ? void 0 : effect.forceVisible) === true)
|
|
4941
|
+
addReveal(triggerId, targetFieldId);
|
|
4942
|
+
}
|
|
4943
|
+
}
|
|
4944
|
+
return new Map(
|
|
4945
|
+
Array.from(out.entries()).map(([triggerId, fieldIds]) => [
|
|
4946
|
+
triggerId,
|
|
4947
|
+
Array.from(fieldIds).sort()
|
|
4948
|
+
])
|
|
4949
|
+
);
|
|
4950
|
+
}
|
|
4951
|
+
function walkFromTrigger(args) {
|
|
4952
|
+
var _a, _b, _c;
|
|
4953
|
+
if (args.depth >= MAX_VISIBILITY_CYCLE_DEPTH) return;
|
|
4954
|
+
const visitedKey = `${args.rootTriggerId}::${args.currentTriggerId}::${args.path.join(">")}`;
|
|
4955
|
+
if (args.visited.has(visitedKey)) return;
|
|
4956
|
+
args.visited.add(visitedKey);
|
|
4957
|
+
const revealedFieldIds = (_a = args.revealTargetsByTrigger.get(args.currentTriggerId)) != null ? _a : [];
|
|
4958
|
+
for (const revealedFieldId of revealedFieldIds) {
|
|
4959
|
+
const reachableTriggers = (_c = (_b = args.fieldTriggers.get(revealedFieldId)) == null ? void 0 : _b.slice().sort()) != null ? _c : [];
|
|
4960
|
+
for (const reachableTriggerId of reachableTriggers) {
|
|
4961
|
+
const invalidation = invalidatesRequiredPath(
|
|
4962
|
+
args.v,
|
|
4963
|
+
args.triggerById,
|
|
4964
|
+
reachableTriggerId,
|
|
4965
|
+
args.required
|
|
4966
|
+
);
|
|
4967
|
+
if (invalidation) {
|
|
4968
|
+
emitCycleError({
|
|
4969
|
+
v: args.v,
|
|
4970
|
+
rootTriggerId: args.rootTriggerId,
|
|
4971
|
+
revealedFieldId,
|
|
4972
|
+
conflictingTriggerId: reachableTriggerId,
|
|
4973
|
+
invalidatedId: invalidation.invalidatedId,
|
|
4974
|
+
path: [...args.path, reachableTriggerId],
|
|
4975
|
+
reported: args.reported
|
|
4976
|
+
});
|
|
4683
4977
|
}
|
|
4978
|
+
if (args.path.includes(reachableTriggerId)) continue;
|
|
4979
|
+
walkFromTrigger({
|
|
4980
|
+
...args,
|
|
4981
|
+
currentTriggerId: reachableTriggerId,
|
|
4982
|
+
required: addRequiredTrigger(
|
|
4983
|
+
args.triggerById,
|
|
4984
|
+
args.required,
|
|
4985
|
+
reachableTriggerId
|
|
4986
|
+
),
|
|
4987
|
+
path: [...args.path, reachableTriggerId],
|
|
4988
|
+
depth: args.depth + 1
|
|
4989
|
+
});
|
|
4684
4990
|
}
|
|
4685
|
-
|
|
4686
|
-
|
|
4687
|
-
|
|
4688
|
-
|
|
4991
|
+
}
|
|
4992
|
+
}
|
|
4993
|
+
function makeRequiredState(triggerById, triggerIds) {
|
|
4994
|
+
let required = {
|
|
4995
|
+
triggers: /* @__PURE__ */ new Set(),
|
|
4996
|
+
ownerFields: /* @__PURE__ */ new Set()
|
|
4997
|
+
};
|
|
4998
|
+
for (const triggerId of triggerIds) {
|
|
4999
|
+
required = addRequiredTrigger(triggerById, required, triggerId);
|
|
5000
|
+
}
|
|
5001
|
+
return required;
|
|
5002
|
+
}
|
|
5003
|
+
function addRequiredTrigger(triggerById, current, triggerId) {
|
|
5004
|
+
const next = {
|
|
5005
|
+
triggers: new Set(current.triggers),
|
|
5006
|
+
ownerFields: new Set(current.ownerFields)
|
|
5007
|
+
};
|
|
5008
|
+
const trigger = triggerById.get(triggerId);
|
|
5009
|
+
if (!trigger) return next;
|
|
5010
|
+
next.triggers.add(triggerId);
|
|
5011
|
+
next.ownerFields.add(trigger.ownerFieldId);
|
|
5012
|
+
return next;
|
|
5013
|
+
}
|
|
5014
|
+
function invalidatesRequiredPath(v, triggerById, conflictingTriggerId, required) {
|
|
5015
|
+
var _a, _b, _c, _d, _e, _f;
|
|
5016
|
+
for (const targetId of (_b = (_a = v.props.excludes_for_buttons) == null ? void 0 : _a[conflictingTriggerId]) != null ? _b : []) {
|
|
5017
|
+
if (required.ownerFields.has(targetId)) {
|
|
5018
|
+
return { invalidatedId: targetId };
|
|
5019
|
+
}
|
|
5020
|
+
const targetTrigger = triggerById.get(targetId);
|
|
5021
|
+
if ((targetTrigger == null ? void 0 : targetTrigger.kind) === "option" && required.triggers.has(targetId)) {
|
|
5022
|
+
return { invalidatedId: targetId };
|
|
5023
|
+
}
|
|
5024
|
+
}
|
|
5025
|
+
const effects = (_d = (_c = v.props.option_effects_for_buttons) == null ? void 0 : _c[conflictingTriggerId]) != null ? _d : {};
|
|
5026
|
+
for (const [targetFieldId, effect] of Object.entries(effects)) {
|
|
5027
|
+
if (!v.fieldById.has(targetFieldId)) continue;
|
|
5028
|
+
if ((_e = effect == null ? void 0 : effect.exclude) == null ? void 0 : _e.length) {
|
|
5029
|
+
const excluded = new Set(effect.exclude);
|
|
5030
|
+
for (const requiredTriggerId of required.triggers) {
|
|
5031
|
+
const requiredTrigger = triggerById.get(requiredTriggerId);
|
|
5032
|
+
if ((requiredTrigger == null ? void 0 : requiredTrigger.kind) !== "option") continue;
|
|
5033
|
+
if (requiredTrigger.ownerFieldId !== targetFieldId) continue;
|
|
5034
|
+
if (excluded.has(requiredTriggerId)) {
|
|
5035
|
+
return { invalidatedId: requiredTriggerId };
|
|
5036
|
+
}
|
|
5037
|
+
}
|
|
5038
|
+
}
|
|
5039
|
+
if ((_f = effect == null ? void 0 : effect.include) == null ? void 0 : _f.length) {
|
|
5040
|
+
const included = new Set(effect.include);
|
|
5041
|
+
for (const requiredTriggerId of required.triggers) {
|
|
5042
|
+
const requiredTrigger = triggerById.get(requiredTriggerId);
|
|
5043
|
+
if ((requiredTrigger == null ? void 0 : requiredTrigger.kind) !== "option") continue;
|
|
5044
|
+
if (requiredTrigger.ownerFieldId !== targetFieldId) continue;
|
|
5045
|
+
if (!included.has(requiredTriggerId)) {
|
|
5046
|
+
return { invalidatedId: requiredTriggerId };
|
|
5047
|
+
}
|
|
4689
5048
|
}
|
|
4690
5049
|
}
|
|
4691
|
-
return void 0;
|
|
4692
5050
|
}
|
|
5051
|
+
return void 0;
|
|
5052
|
+
}
|
|
5053
|
+
function emitCycleError(args) {
|
|
5054
|
+
const key = [
|
|
5055
|
+
args.rootTriggerId,
|
|
5056
|
+
args.conflictingTriggerId,
|
|
5057
|
+
args.invalidatedId,
|
|
5058
|
+
args.path.join(">")
|
|
5059
|
+
].join("::");
|
|
5060
|
+
if (args.reported.has(key)) return;
|
|
5061
|
+
args.reported.add(key);
|
|
5062
|
+
args.v.errors.push({
|
|
5063
|
+
code: "visibility_dependency_cycle",
|
|
5064
|
+
severity: "error",
|
|
5065
|
+
message: `Visibility dependency cycle: trigger "${args.rootTriggerId}" reveals "${args.revealedFieldId}", but reachable trigger "${args.conflictingTriggerId}" can hide or remove "${args.invalidatedId}".`,
|
|
5066
|
+
nodeId: args.conflictingTriggerId,
|
|
5067
|
+
details: withAffected(
|
|
5068
|
+
{
|
|
5069
|
+
rootTriggerId: args.rootTriggerId,
|
|
5070
|
+
conflictingTriggerId: args.conflictingTriggerId,
|
|
5071
|
+
invalidatedId: args.invalidatedId,
|
|
5072
|
+
path: args.path
|
|
5073
|
+
},
|
|
5074
|
+
[
|
|
5075
|
+
args.rootTriggerId,
|
|
5076
|
+
args.revealedFieldId,
|
|
5077
|
+
args.conflictingTriggerId,
|
|
5078
|
+
args.invalidatedId
|
|
5079
|
+
]
|
|
5080
|
+
)
|
|
5081
|
+
});
|
|
5082
|
+
}
|
|
5083
|
+
|
|
5084
|
+
// src/utils/order-kind.ts
|
|
5085
|
+
function normalizeSelectedTriggerKey(key, nodeMap) {
|
|
5086
|
+
if (!key) return void 0;
|
|
4693
5087
|
const ref = nodeMap.get(key);
|
|
4694
5088
|
if (!ref) return void 0;
|
|
4695
5089
|
if (ref.kind !== "field" && ref.kind !== "option") return void 0;
|
|
@@ -4848,8 +5242,7 @@ function validateUtilityMarkers(v) {
|
|
|
4848
5242
|
"percent"
|
|
4849
5243
|
]);
|
|
4850
5244
|
for (const f of v.fields) {
|
|
4851
|
-
const
|
|
4852
|
-
for (const o of optsArr) {
|
|
5245
|
+
for (const { option: o } of walkFieldOptions(f)) {
|
|
4853
5246
|
const role = (_b = (_a = o.pricing_role) != null ? _a : f.pricing_role) != null ? _b : "base";
|
|
4854
5247
|
const hasService = isServiceIdRef(o.service_id);
|
|
4855
5248
|
const util = (_c = o.meta) == null ? void 0 : _c.utility;
|
|
@@ -5071,13 +5464,13 @@ function normalizeServiceRef(value) {
|
|
|
5071
5464
|
|
|
5072
5465
|
// src/core/validate/steps/rates.ts
|
|
5073
5466
|
function validateRates(v) {
|
|
5074
|
-
var _a, _b
|
|
5467
|
+
var _a, _b;
|
|
5075
5468
|
const ratePolicy = normalizeRatePolicy(v.options.ratePolicy);
|
|
5076
5469
|
for (const f of v.fields) {
|
|
5077
5470
|
if (!isMultiField(f)) continue;
|
|
5078
5471
|
const baseRates = [];
|
|
5079
|
-
for (const o of (
|
|
5080
|
-
const role = (
|
|
5472
|
+
for (const { option: o } of walkFieldOptions(f)) {
|
|
5473
|
+
const role = (_b = (_a = o.pricing_role) != null ? _a : f.pricing_role) != null ? _b : "base";
|
|
5081
5474
|
if (role !== "base") continue;
|
|
5082
5475
|
const sid = o.service_id;
|
|
5083
5476
|
if (!isServiceIdRef(sid)) continue;
|
|
@@ -5488,7 +5881,7 @@ function effectiveConstraints(v, tagId) {
|
|
|
5488
5881
|
return out;
|
|
5489
5882
|
}
|
|
5490
5883
|
function validateConstraints(v) {
|
|
5491
|
-
var _a
|
|
5884
|
+
var _a;
|
|
5492
5885
|
for (const t of v.tags) {
|
|
5493
5886
|
const eff = effectiveConstraints(v, t.id);
|
|
5494
5887
|
const hasAnyRequired = Object.values(eff).some(
|
|
@@ -5497,7 +5890,7 @@ function validateConstraints(v) {
|
|
|
5497
5890
|
if (!hasAnyRequired) continue;
|
|
5498
5891
|
const visible = v.fieldsVisibleUnder(t.id);
|
|
5499
5892
|
for (const f of visible) {
|
|
5500
|
-
for (const o of (
|
|
5893
|
+
for (const { option: o } of walkFieldOptions(f)) {
|
|
5501
5894
|
if (!isServiceIdRef(o.service_id)) continue;
|
|
5502
5895
|
const svc = getServiceCapability(v.serviceMap, o.service_id);
|
|
5503
5896
|
if (!svc || typeof svc !== "object") continue;
|
|
@@ -5551,7 +5944,7 @@ function validateConstraints(v) {
|
|
|
5551
5944
|
if (!row) continue;
|
|
5552
5945
|
const from = row.from === true;
|
|
5553
5946
|
const to = row.to === true;
|
|
5554
|
-
const origin = String((
|
|
5947
|
+
const origin = String((_a = row.origin) != null ? _a : "");
|
|
5555
5948
|
v.errors.push({
|
|
5556
5949
|
code: "constraint_overridden",
|
|
5557
5950
|
severity: "warning",
|
|
@@ -5585,14 +5978,14 @@ function validateCustomFields(v) {
|
|
|
5585
5978
|
|
|
5586
5979
|
// src/core/validate/steps/global-utility-guard.ts
|
|
5587
5980
|
function validateGlobalUtilityGuard(v) {
|
|
5588
|
-
var _a, _b
|
|
5981
|
+
var _a, _b;
|
|
5589
5982
|
if (!v.options.globalUtilityGuard) return;
|
|
5590
5983
|
let hasUtility = false;
|
|
5591
5984
|
let hasBase = false;
|
|
5592
5985
|
for (const f of v.fields) {
|
|
5593
|
-
for (const o of (
|
|
5986
|
+
for (const { option: o } of walkFieldOptions(f)) {
|
|
5594
5987
|
if (!isServiceIdRef(o.service_id)) continue;
|
|
5595
|
-
const role = (
|
|
5988
|
+
const role = (_b = (_a = o.pricing_role) != null ? _a : f.pricing_role) != null ? _b : "base";
|
|
5596
5989
|
if (role === "base") hasBase = true;
|
|
5597
5990
|
else if (role === "utility") hasUtility = true;
|
|
5598
5991
|
if (hasUtility && hasBase) break;
|
|
@@ -5794,7 +6187,7 @@ function applyFilterAllowLists(tagId, fieldId, filter) {
|
|
|
5794
6187
|
return true;
|
|
5795
6188
|
}
|
|
5796
6189
|
function collectServiceItems(args) {
|
|
5797
|
-
var _a, _b, _c, _d
|
|
6190
|
+
var _a, _b, _c, _d;
|
|
5798
6191
|
const filter = args.filter;
|
|
5799
6192
|
const roleFilter = (_a = filter == null ? void 0 : filter.role) != null ? _a : "both";
|
|
5800
6193
|
const where = filter == null ? void 0 : filter.where;
|
|
@@ -5844,7 +6237,7 @@ function collectServiceItems(args) {
|
|
|
5844
6237
|
affectedIds: [`field:${f.id}`, `service:${String(fSid)}`]
|
|
5845
6238
|
});
|
|
5846
6239
|
}
|
|
5847
|
-
for (const o of (
|
|
6240
|
+
for (const { option: o } of walkFieldOptions(f)) {
|
|
5848
6241
|
const oSid = o.service_id;
|
|
5849
6242
|
if (!isServiceIdRef2(oSid)) continue;
|
|
5850
6243
|
const role = fieldRoleOf(f, o);
|
|
@@ -5929,7 +6322,7 @@ function collectServiceItems(args) {
|
|
|
5929
6322
|
}
|
|
5930
6323
|
} else if (includeGroupFallbacks) {
|
|
5931
6324
|
const allowPrimaries = new Set(
|
|
5932
|
-
((
|
|
6325
|
+
((_d = args.visiblePrimaries) != null ? _d : []).map((x) => String(x))
|
|
5933
6326
|
);
|
|
5934
6327
|
for (const primaryKey of allowPrimaries) {
|
|
5935
6328
|
const list = globalFb[primaryKey];
|
|
@@ -6010,17 +6403,15 @@ function affectedFromItems(items) {
|
|
|
6010
6403
|
return uniq(ids);
|
|
6011
6404
|
}
|
|
6012
6405
|
function visibleGroupNodeIds(tag, fields) {
|
|
6013
|
-
var _a;
|
|
6014
6406
|
const ids = [tag.id];
|
|
6015
6407
|
for (const f of fields) {
|
|
6016
|
-
for (const o of (
|
|
6408
|
+
for (const { option: o } of walkFieldOptions(f)) {
|
|
6017
6409
|
ids.push(o.id);
|
|
6018
6410
|
}
|
|
6019
6411
|
}
|
|
6020
6412
|
return uniq(ids);
|
|
6021
6413
|
}
|
|
6022
6414
|
function visibleGroupPrimaries(tag, fields) {
|
|
6023
|
-
var _a;
|
|
6024
6415
|
const prim = [];
|
|
6025
6416
|
const tagSid = tag.service_id;
|
|
6026
6417
|
if (typeof tagSid === "string" || typeof tagSid === "number" && Number.isFinite(tagSid)) {
|
|
@@ -6031,7 +6422,7 @@ function visibleGroupPrimaries(tag, fields) {
|
|
|
6031
6422
|
if (typeof fsid === "string" || typeof fsid === "number" && Number.isFinite(fsid)) {
|
|
6032
6423
|
prim.push(fsid);
|
|
6033
6424
|
}
|
|
6034
|
-
for (const o of (
|
|
6425
|
+
for (const { option: o } of walkFieldOptions(f)) {
|
|
6035
6426
|
const osid = o.service_id;
|
|
6036
6427
|
if (typeof osid === "string" || typeof osid === "number" && Number.isFinite(osid)) {
|
|
6037
6428
|
prim.push(osid);
|
|
@@ -6255,6 +6646,7 @@ function validate(props, ctx = {}) {
|
|
|
6255
6646
|
validateStructure(v);
|
|
6256
6647
|
validateIdentity(v);
|
|
6257
6648
|
validateOptionMaps(v);
|
|
6649
|
+
validateVisibilityCycles(v);
|
|
6258
6650
|
validateOrderKinds(v);
|
|
6259
6651
|
v.fieldsVisibleUnder = createFieldsVisibleUnder(v);
|
|
6260
6652
|
const visSim = readVisibilitySimOpts(options);
|
|
@@ -6388,14 +6780,14 @@ var BuilderImpl = class {
|
|
|
6388
6780
|
const showOptions = showSet.has(f.id);
|
|
6389
6781
|
if (!showOptions) continue;
|
|
6390
6782
|
if (!Array.isArray(f.options)) continue;
|
|
6391
|
-
for (const o of f
|
|
6783
|
+
for (const { option: o, parentId } of walkFieldOptions(f)) {
|
|
6392
6784
|
nodes.push({
|
|
6393
6785
|
id: o.id,
|
|
6394
6786
|
kind: "option",
|
|
6395
6787
|
label: o.label
|
|
6396
6788
|
});
|
|
6397
6789
|
const e = {
|
|
6398
|
-
from: f.id,
|
|
6790
|
+
from: parentId != null ? parentId : f.id,
|
|
6399
6791
|
to: o.id,
|
|
6400
6792
|
kind: "option",
|
|
6401
6793
|
meta: { ownerField: f.id }
|
|
@@ -6442,7 +6834,7 @@ var BuilderImpl = class {
|
|
|
6442
6834
|
return { nodes, edges };
|
|
6443
6835
|
}
|
|
6444
6836
|
cleanedProps() {
|
|
6445
|
-
var _a, _b, _c, _d, _e;
|
|
6837
|
+
var _a, _b, _c, _d, _e, _f;
|
|
6446
6838
|
const fieldIds = new Set(this.props.fields.map((f) => f.id));
|
|
6447
6839
|
const optionIds = /* @__PURE__ */ new Set();
|
|
6448
6840
|
this.optionOwnerById.forEach((_v, oid) => optionIds.add(oid));
|
|
@@ -6454,6 +6846,7 @@ var BuilderImpl = class {
|
|
|
6454
6846
|
}
|
|
6455
6847
|
const incMap = (_c = this.props.includes_for_buttons) != null ? _c : {};
|
|
6456
6848
|
const excMap = (_d = this.props.excludes_for_buttons) != null ? _d : {};
|
|
6849
|
+
const effectMap = (_e = this.props.option_effects_for_buttons) != null ? _e : {};
|
|
6457
6850
|
const includedByButtons = /* @__PURE__ */ new Set();
|
|
6458
6851
|
const referencedKeys = /* @__PURE__ */ new Set();
|
|
6459
6852
|
const referencedOwnerFields = /* @__PURE__ */ new Set();
|
|
@@ -6473,6 +6866,14 @@ var BuilderImpl = class {
|
|
|
6473
6866
|
void fid;
|
|
6474
6867
|
}
|
|
6475
6868
|
}
|
|
6869
|
+
for (const [key, targets] of Object.entries(effectMap)) {
|
|
6870
|
+
referencedKeys.add(key);
|
|
6871
|
+
const owner = this.optionOwnerById.get(key);
|
|
6872
|
+
if (owner) referencedOwnerFields.add(owner.fieldId);
|
|
6873
|
+
for (const [fid, effect] of Object.entries(targets != null ? targets : {})) {
|
|
6874
|
+
if ((effect == null ? void 0 : effect.forceVisible) === true) includedByButtons.add(fid);
|
|
6875
|
+
}
|
|
6876
|
+
}
|
|
6476
6877
|
const boundIds = /* @__PURE__ */ new Set();
|
|
6477
6878
|
for (const f of this.props.fields) {
|
|
6478
6879
|
const b = f.bind_id;
|
|
@@ -6490,6 +6891,7 @@ var BuilderImpl = class {
|
|
|
6490
6891
|
return bound || included || referenced || !excluded;
|
|
6491
6892
|
});
|
|
6492
6893
|
const allowedTargets = new Set(fields.map((f) => f.id));
|
|
6894
|
+
const allowedFieldById = new Map(fields.map((f) => [f.id, f]));
|
|
6493
6895
|
const pruneButtons = (src) => {
|
|
6494
6896
|
if (!src) return void 0;
|
|
6495
6897
|
const out2 = {};
|
|
@@ -6509,13 +6911,52 @@ var BuilderImpl = class {
|
|
|
6509
6911
|
const excludes_for_buttons = pruneButtons(
|
|
6510
6912
|
this.props.excludes_for_buttons
|
|
6511
6913
|
);
|
|
6914
|
+
const pruneOptionEffects = (src) => {
|
|
6915
|
+
var _a2, _b2, _c2, _d2;
|
|
6916
|
+
if (!src) return void 0;
|
|
6917
|
+
const out2 = {};
|
|
6918
|
+
for (const [key, targets] of Object.entries(src)) {
|
|
6919
|
+
const keyIsValid = optionIds.has(key) || fieldIds.has(key);
|
|
6920
|
+
if (!keyIsValid) continue;
|
|
6921
|
+
const cleanedTargets = {};
|
|
6922
|
+
for (const [targetFieldId, effect] of Object.entries(
|
|
6923
|
+
targets != null ? targets : {}
|
|
6924
|
+
)) {
|
|
6925
|
+
const field = allowedFieldById.get(targetFieldId);
|
|
6926
|
+
if (!field || !effect) continue;
|
|
6927
|
+
const validOptionIds = fieldOptionIdSet(field);
|
|
6928
|
+
const include2 = Array.from(
|
|
6929
|
+
new Set((_a2 = effect.include) != null ? _a2 : [])
|
|
6930
|
+
).filter((optionId) => validOptionIds.has(optionId));
|
|
6931
|
+
const exclude2 = Array.from(
|
|
6932
|
+
new Set((_b2 = effect.exclude) != null ? _b2 : [])
|
|
6933
|
+
).filter((optionId) => validOptionIds.has(optionId));
|
|
6934
|
+
const next = {
|
|
6935
|
+
...effect.forceVisible === true ? { forceVisible: true } : {},
|
|
6936
|
+
...include2.length ? { include: include2 } : {},
|
|
6937
|
+
...exclude2.length ? { exclude: exclude2 } : {}
|
|
6938
|
+
};
|
|
6939
|
+
if (next.forceVisible === true || ((_c2 = next.include) == null ? void 0 : _c2.length) || ((_d2 = next.exclude) == null ? void 0 : _d2.length)) {
|
|
6940
|
+
cleanedTargets[targetFieldId] = next;
|
|
6941
|
+
}
|
|
6942
|
+
}
|
|
6943
|
+
if (Object.keys(cleanedTargets).length) {
|
|
6944
|
+
out2[key] = cleanedTargets;
|
|
6945
|
+
}
|
|
6946
|
+
}
|
|
6947
|
+
return Object.keys(out2).length ? out2 : void 0;
|
|
6948
|
+
};
|
|
6949
|
+
const option_effects_for_buttons = pruneOptionEffects(
|
|
6950
|
+
this.props.option_effects_for_buttons
|
|
6951
|
+
);
|
|
6512
6952
|
const out = {
|
|
6513
6953
|
filters: this.props.filters.slice(),
|
|
6514
6954
|
fields,
|
|
6515
6955
|
...this.props.orderKinds ? { orderKinds: this.props.orderKinds } : {},
|
|
6516
6956
|
...includes_for_buttons && { includes_for_buttons },
|
|
6517
6957
|
...excludes_for_buttons && { excludes_for_buttons },
|
|
6518
|
-
|
|
6958
|
+
...option_effects_for_buttons && { option_effects_for_buttons },
|
|
6959
|
+
schema_version: (_f = this.props.schema_version) != null ? _f : "1.0",
|
|
6519
6960
|
// keep fallbacks & other maps as-is
|
|
6520
6961
|
...this.props.fallbacks ? { fallbacks: this.props.fallbacks } : {}
|
|
6521
6962
|
};
|
|
@@ -6528,12 +6969,15 @@ var BuilderImpl = class {
|
|
|
6528
6969
|
return cloneDeep2(this.options);
|
|
6529
6970
|
}
|
|
6530
6971
|
visibleFields(tagId, selectedKeys) {
|
|
6972
|
+
return this.resolveVisibility(tagId, selectedKeys).fieldIds;
|
|
6973
|
+
}
|
|
6974
|
+
resolveVisibility(tagId, selectedKeys) {
|
|
6531
6975
|
var _a;
|
|
6532
|
-
return
|
|
6533
|
-
|
|
6534
|
-
|
|
6535
|
-
)
|
|
6536
|
-
|
|
6976
|
+
return resolveVisibility(
|
|
6977
|
+
this.props,
|
|
6978
|
+
tagId,
|
|
6979
|
+
(_a = selectedKeys != null ? selectedKeys : this.options.selectedOptionKeys) != null ? _a : []
|
|
6980
|
+
);
|
|
6537
6981
|
}
|
|
6538
6982
|
getNodeMap() {
|
|
6539
6983
|
if (!this._nodemap) this._nodemap = buildNodeMap(this.getProps());
|
|
@@ -6548,9 +6992,8 @@ var BuilderImpl = class {
|
|
|
6548
6992
|
for (const t of this.props.filters) this.tagById.set(t.id, t);
|
|
6549
6993
|
for (const f of this.props.fields) {
|
|
6550
6994
|
this.fieldById.set(f.id, f);
|
|
6551
|
-
|
|
6552
|
-
|
|
6553
|
-
this.optionOwnerById.set(o.id, { fieldId: f.id });
|
|
6995
|
+
for (const [optionId, owner] of optionOwnerMap([f])) {
|
|
6996
|
+
this.optionOwnerById.set(optionId, { fieldId: owner.fieldId });
|
|
6554
6997
|
}
|
|
6555
6998
|
}
|
|
6556
6999
|
}
|
|
@@ -7498,44 +7941,135 @@ function bumpSuffix(old) {
|
|
|
7498
7941
|
return `${stem}${parseInt(m[2], 10) + 1}`;
|
|
7499
7942
|
}
|
|
7500
7943
|
|
|
7501
|
-
// src/react/canvas/editor/editor-
|
|
7502
|
-
function
|
|
7503
|
-
|
|
7504
|
-
|
|
7505
|
-
|
|
7506
|
-
|
|
7507
|
-
newId2 = duplicateInPlace(ctx, ref, opts);
|
|
7508
|
-
});
|
|
7509
|
-
return newId2;
|
|
7510
|
-
} catch (err) {
|
|
7511
|
-
ctx.loadSnapshot(snapBefore, "undo");
|
|
7512
|
-
throw err;
|
|
7944
|
+
// src/react/canvas/editor/editor-utils.ts
|
|
7945
|
+
function ownerOfOption(props, optionId) {
|
|
7946
|
+
var _a;
|
|
7947
|
+
for (const f of (_a = props.fields) != null ? _a : []) {
|
|
7948
|
+
const found = findOptionLocationInField(f, optionId);
|
|
7949
|
+
if (found) return { fieldId: f.id, index: found.index };
|
|
7513
7950
|
}
|
|
7951
|
+
return null;
|
|
7514
7952
|
}
|
|
7515
|
-
function
|
|
7516
|
-
|
|
7517
|
-
|
|
7518
|
-
|
|
7519
|
-
|
|
7520
|
-
|
|
7521
|
-
|
|
7522
|
-
|
|
7523
|
-
|
|
7524
|
-
|
|
7525
|
-
|
|
7526
|
-
|
|
7527
|
-
|
|
7528
|
-
|
|
7529
|
-
|
|
7530
|
-
|
|
7531
|
-
|
|
7532
|
-
|
|
7533
|
-
|
|
7534
|
-
|
|
7535
|
-
|
|
7536
|
-
|
|
7537
|
-
|
|
7538
|
-
|
|
7953
|
+
function findMutableOption(props, optionId) {
|
|
7954
|
+
var _a;
|
|
7955
|
+
for (const field of (_a = props.fields) != null ? _a : []) {
|
|
7956
|
+
const found = findOptionLocationInField(field, optionId);
|
|
7957
|
+
if (found) return { field, ...found };
|
|
7958
|
+
}
|
|
7959
|
+
return void 0;
|
|
7960
|
+
}
|
|
7961
|
+
function collectFieldOptionIds(field) {
|
|
7962
|
+
const out = [];
|
|
7963
|
+
const visit = (options) => {
|
|
7964
|
+
for (const option of options != null ? options : []) {
|
|
7965
|
+
out.push(String(option.id));
|
|
7966
|
+
visit(option.children);
|
|
7967
|
+
}
|
|
7968
|
+
};
|
|
7969
|
+
visit(field == null ? void 0 : field.options);
|
|
7970
|
+
return out;
|
|
7971
|
+
}
|
|
7972
|
+
function findOptionLocationInField(field, optionId) {
|
|
7973
|
+
const visit = (siblings, parent) => {
|
|
7974
|
+
if (!siblings) return void 0;
|
|
7975
|
+
const index = siblings.findIndex((option) => option.id === optionId);
|
|
7976
|
+
if (index >= 0) {
|
|
7977
|
+
return {
|
|
7978
|
+
option: siblings[index],
|
|
7979
|
+
siblings,
|
|
7980
|
+
index,
|
|
7981
|
+
parent
|
|
7982
|
+
};
|
|
7983
|
+
}
|
|
7984
|
+
for (const option of siblings) {
|
|
7985
|
+
const found = visit(option.children, option);
|
|
7986
|
+
if (found) return found;
|
|
7987
|
+
}
|
|
7988
|
+
return void 0;
|
|
7989
|
+
};
|
|
7990
|
+
return visit(field.options);
|
|
7991
|
+
}
|
|
7992
|
+
function hasFieldOptions(field) {
|
|
7993
|
+
return Array.isArray(field == null ? void 0 : field.options) && field.options.length > 0;
|
|
7994
|
+
}
|
|
7995
|
+
function isActualButtonField(field) {
|
|
7996
|
+
return (field == null ? void 0 : field.button) === true && !hasFieldOptions(field);
|
|
7997
|
+
}
|
|
7998
|
+
function clearFieldButtonReceiverMaps(props, fieldId) {
|
|
7999
|
+
var _a, _b, _c;
|
|
8000
|
+
if ((_a = props.includes_for_buttons) == null ? void 0 : _a[fieldId]) {
|
|
8001
|
+
delete props.includes_for_buttons[fieldId];
|
|
8002
|
+
}
|
|
8003
|
+
if ((_b = props.excludes_for_buttons) == null ? void 0 : _b[fieldId]) {
|
|
8004
|
+
delete props.excludes_for_buttons[fieldId];
|
|
8005
|
+
}
|
|
8006
|
+
if (props.includes_for_buttons && Object.keys(props.includes_for_buttons).length === 0) {
|
|
8007
|
+
delete props.includes_for_buttons;
|
|
8008
|
+
}
|
|
8009
|
+
if (props.excludes_for_buttons && Object.keys(props.excludes_for_buttons).length === 0) {
|
|
8010
|
+
delete props.excludes_for_buttons;
|
|
8011
|
+
}
|
|
8012
|
+
if ((_c = props.option_effects_for_buttons) == null ? void 0 : _c[fieldId]) {
|
|
8013
|
+
delete props.option_effects_for_buttons[fieldId];
|
|
8014
|
+
}
|
|
8015
|
+
if (props.option_effects_for_buttons && Object.keys(props.option_effects_for_buttons).length === 0) {
|
|
8016
|
+
delete props.option_effects_for_buttons;
|
|
8017
|
+
}
|
|
8018
|
+
}
|
|
8019
|
+
function ensureServiceExists(opts, id) {
|
|
8020
|
+
if (typeof opts.serviceExists === "function") {
|
|
8021
|
+
if (!opts.serviceExists(id)) {
|
|
8022
|
+
throw new Error(`service_not_found:${String(id)}`);
|
|
8023
|
+
}
|
|
8024
|
+
return;
|
|
8025
|
+
}
|
|
8026
|
+
if (opts.serviceMap) {
|
|
8027
|
+
if (!Object.prototype.hasOwnProperty.call(opts.serviceMap, id)) {
|
|
8028
|
+
throw new Error(`service_not_found:${String(id)}`);
|
|
8029
|
+
}
|
|
8030
|
+
return;
|
|
8031
|
+
}
|
|
8032
|
+
throw new Error("service_checker_missing");
|
|
8033
|
+
}
|
|
8034
|
+
|
|
8035
|
+
// src/react/canvas/editor/editor-duplicate.ts
|
|
8036
|
+
function duplicate(ctx, ref, opts = {}) {
|
|
8037
|
+
const snapBefore = ctx.makeSnapshot("duplicate:before");
|
|
8038
|
+
try {
|
|
8039
|
+
let newId2 = "";
|
|
8040
|
+
ctx.transact("duplicate", () => {
|
|
8041
|
+
newId2 = duplicateInPlace(ctx, ref, opts);
|
|
8042
|
+
});
|
|
8043
|
+
return newId2;
|
|
8044
|
+
} catch (err) {
|
|
8045
|
+
ctx.loadSnapshot(snapBefore, "undo");
|
|
8046
|
+
throw err;
|
|
8047
|
+
}
|
|
8048
|
+
}
|
|
8049
|
+
function duplicateMany(ctx, ids, opts = {}) {
|
|
8050
|
+
const ordered = Array.from(new Set((ids != null ? ids : []).map((id) => String(id))));
|
|
8051
|
+
if (!ordered.length) return [];
|
|
8052
|
+
const snapBefore = ctx.makeSnapshot("duplicateMany:before");
|
|
8053
|
+
try {
|
|
8054
|
+
const created = [];
|
|
8055
|
+
ctx.transact("duplicateMany", () => {
|
|
8056
|
+
var _a, _b, _c;
|
|
8057
|
+
const props = ctx.getProps();
|
|
8058
|
+
const selectedFields = /* @__PURE__ */ new Set();
|
|
8059
|
+
for (const id of ordered) {
|
|
8060
|
+
if (ctx.isFieldId(id) && ((_a = props.fields) != null ? _a : []).some((f) => f.id === id)) {
|
|
8061
|
+
selectedFields.add(id);
|
|
8062
|
+
}
|
|
8063
|
+
}
|
|
8064
|
+
for (const id of ordered) {
|
|
8065
|
+
if (ctx.isTagId(id)) {
|
|
8066
|
+
if (!((_b = ctx.getProps().filters) != null ? _b : []).some((t) => t.id === id)) continue;
|
|
8067
|
+
created.push(
|
|
8068
|
+
duplicateInPlace(ctx, { kind: "tag", id }, opts)
|
|
8069
|
+
);
|
|
8070
|
+
continue;
|
|
8071
|
+
}
|
|
8072
|
+
if (ctx.isFieldId(id)) {
|
|
7539
8073
|
if (!((_c = ctx.getProps().fields) != null ? _c : []).some((f) => f.id === id)) continue;
|
|
7540
8074
|
created.push(
|
|
7541
8075
|
duplicateInPlace(ctx, { kind: "field", id }, opts)
|
|
@@ -7572,14 +8106,66 @@ function duplicateInPlace(ctx, ref, opts = {}) {
|
|
|
7572
8106
|
return duplicateOption(ctx, ref.fieldId, ref.id, opts);
|
|
7573
8107
|
}
|
|
7574
8108
|
function ownerFieldOfOption(props, optionId) {
|
|
7575
|
-
var _a
|
|
8109
|
+
var _a;
|
|
7576
8110
|
for (const field of (_a = props.fields) != null ? _a : []) {
|
|
7577
|
-
if ((
|
|
8111
|
+
if (findMutableOption({ ...props, fields: [field] }, optionId)) {
|
|
7578
8112
|
return { fieldId: field.id };
|
|
7579
8113
|
}
|
|
7580
8114
|
}
|
|
7581
8115
|
return null;
|
|
7582
8116
|
}
|
|
8117
|
+
function cloneOptionTree(ctx, fieldId, option, opts, optionIdMap) {
|
|
8118
|
+
var _a, _b, _c, _d;
|
|
8119
|
+
const newId2 = ctx.uniqueOptionId(
|
|
8120
|
+
fieldId,
|
|
8121
|
+
((_a = opts.optionIdStrategy) != null ? _a : defaultOptionIdStrategy)(option.id)
|
|
8122
|
+
);
|
|
8123
|
+
optionIdMap.set(option.id, newId2);
|
|
8124
|
+
const children = (_b = option.children) == null ? void 0 : _b.map(
|
|
8125
|
+
(child) => cloneOptionTree(ctx, fieldId, child, opts, optionIdMap)
|
|
8126
|
+
);
|
|
8127
|
+
return {
|
|
8128
|
+
...option,
|
|
8129
|
+
id: newId2,
|
|
8130
|
+
label: ((_c = opts.labelStrategy) != null ? _c : nextCopyLabel)((_d = option.label) != null ? _d : option.id),
|
|
8131
|
+
...(children == null ? void 0 : children.length) ? { children } : {}
|
|
8132
|
+
};
|
|
8133
|
+
}
|
|
8134
|
+
function remapEffect(effect, optionIdMap) {
|
|
8135
|
+
const remapList = (values) => values == null ? void 0 : values.map((value) => {
|
|
8136
|
+
var _a;
|
|
8137
|
+
return (_a = optionIdMap.get(value)) != null ? _a : value;
|
|
8138
|
+
});
|
|
8139
|
+
return {
|
|
8140
|
+
...effect,
|
|
8141
|
+
...effect.include ? { include: remapList(effect.include) } : {},
|
|
8142
|
+
...effect.exclude ? { exclude: remapList(effect.exclude) } : {}
|
|
8143
|
+
};
|
|
8144
|
+
}
|
|
8145
|
+
function copyOptionEffects(props, args) {
|
|
8146
|
+
var _a, _b, _c, _d, _e;
|
|
8147
|
+
const source = props.option_effects_for_buttons;
|
|
8148
|
+
if (!source) return;
|
|
8149
|
+
const next = {
|
|
8150
|
+
...source
|
|
8151
|
+
};
|
|
8152
|
+
const triggerIdMap = (_a = args.triggerIdMap) != null ? _a : /* @__PURE__ */ new Map();
|
|
8153
|
+
const targetFieldIdMap = (_b = args.targetFieldIdMap) != null ? _b : /* @__PURE__ */ new Map();
|
|
8154
|
+
const optionIdMap = (_c = args.optionIdMap) != null ? _c : /* @__PURE__ */ new Map();
|
|
8155
|
+
for (const [oldTriggerId, targetMap] of Object.entries(source)) {
|
|
8156
|
+
const newTriggerId = triggerIdMap.get(oldTriggerId);
|
|
8157
|
+
if (!newTriggerId) continue;
|
|
8158
|
+
const copiedTargets = {
|
|
8159
|
+
...(_d = next[newTriggerId]) != null ? _d : {}
|
|
8160
|
+
};
|
|
8161
|
+
for (const [oldTargetFieldId, effect] of Object.entries(targetMap != null ? targetMap : {})) {
|
|
8162
|
+
const newTargetFieldId = (_e = targetFieldIdMap.get(oldTargetFieldId)) != null ? _e : oldTargetFieldId;
|
|
8163
|
+
copiedTargets[newTargetFieldId] = remapEffect(effect, optionIdMap);
|
|
8164
|
+
}
|
|
8165
|
+
next[newTriggerId] = copiedTargets;
|
|
8166
|
+
}
|
|
8167
|
+
props.option_effects_for_buttons = next;
|
|
8168
|
+
}
|
|
7583
8169
|
function duplicateTag(ctx, tagId, opts) {
|
|
7584
8170
|
var _a, _b, _c, _d;
|
|
7585
8171
|
const props = ctx.getProps();
|
|
@@ -7635,7 +8221,7 @@ function duplicateTag(ctx, tagId, opts) {
|
|
|
7635
8221
|
return id;
|
|
7636
8222
|
}
|
|
7637
8223
|
function duplicateField(ctx, fieldId, opts) {
|
|
7638
|
-
var _a, _b, _c, _d, _e, _f
|
|
8224
|
+
var _a, _b, _c, _d, _e, _f;
|
|
7639
8225
|
const props = ctx.getProps();
|
|
7640
8226
|
const fields = (_a = props.fields) != null ? _a : [];
|
|
7641
8227
|
const src = fields.find((f) => f.id === fieldId);
|
|
@@ -7643,21 +8229,10 @@ function duplicateField(ctx, fieldId, opts) {
|
|
|
7643
8229
|
const id = (_b = opts.id) != null ? _b : ctx.uniqueId(src.id);
|
|
7644
8230
|
const label = ((_c = opts.labelStrategy) != null ? _c : nextCopyLabel)((_d = src.label) != null ? _d : id);
|
|
7645
8231
|
const name = opts.nameStrategy ? opts.nameStrategy(src.name) : nextCopyName(src.name);
|
|
7646
|
-
const
|
|
7647
|
-
|
|
7648
|
-
|
|
7649
|
-
|
|
7650
|
-
((_a2 = opts.optionIdStrategy) != null ? _a2 : defaultOptionIdStrategy)(old)
|
|
7651
|
-
);
|
|
7652
|
-
};
|
|
7653
|
-
const clonedOptions = ((_e = src.options) != null ? _e : []).map((o) => {
|
|
7654
|
-
var _a2, _b2;
|
|
7655
|
-
return {
|
|
7656
|
-
...o,
|
|
7657
|
-
id: optId(o.id),
|
|
7658
|
-
label: ((_a2 = opts.labelStrategy) != null ? _a2 : nextCopyLabel)((_b2 = o.label) != null ? _b2 : o.id)
|
|
7659
|
-
};
|
|
7660
|
-
});
|
|
8232
|
+
const optionIdMap = /* @__PURE__ */ new Map();
|
|
8233
|
+
const clonedOptions = ((_e = src.options) != null ? _e : []).map(
|
|
8234
|
+
(o) => cloneOptionTree(ctx, id, o, opts, optionIdMap)
|
|
8235
|
+
);
|
|
7661
8236
|
const cloned = {
|
|
7662
8237
|
...src,
|
|
7663
8238
|
id,
|
|
@@ -7666,14 +8241,8 @@ function duplicateField(ctx, fieldId, opts) {
|
|
|
7666
8241
|
bind_id: ((_f = opts.copyBindings) != null ? _f : true) ? src.bind_id : void 0,
|
|
7667
8242
|
options: clonedOptions
|
|
7668
8243
|
};
|
|
7669
|
-
const optionIdMap = /* @__PURE__ */ new Map();
|
|
7670
|
-
((_g = src.options) != null ? _g : []).forEach((o, i) => {
|
|
7671
|
-
var _a2, _b2;
|
|
7672
|
-
const newOptId = (_b2 = (_a2 = clonedOptions[i]) == null ? void 0 : _a2.id) != null ? _b2 : o.id;
|
|
7673
|
-
optionIdMap.set(o.id, newOptId);
|
|
7674
|
-
});
|
|
7675
8244
|
ctx.patchProps((p) => {
|
|
7676
|
-
var _a2, _b2, _c2, _d2, _e2, _f2,
|
|
8245
|
+
var _a2, _b2, _c2, _d2, _e2, _f2, _g;
|
|
7677
8246
|
const arr = (_a2 = p.fields) != null ? _a2 : [];
|
|
7678
8247
|
const idx = arr.findIndex((f) => f.id === fieldId);
|
|
7679
8248
|
arr.splice(idx + 1, 0, cloned);
|
|
@@ -7711,52 +8280,56 @@ function duplicateField(ctx, fieldId, opts) {
|
|
|
7711
8280
|
}
|
|
7712
8281
|
if (optionIdMap.has(key)) {
|
|
7713
8282
|
const newKey = optionIdMap.get(key);
|
|
7714
|
-
const merged = /* @__PURE__ */ new Set([...(
|
|
8283
|
+
const merged = /* @__PURE__ */ new Set([...(_g = nextMap[newKey]) != null ? _g : [], ...targets]);
|
|
7715
8284
|
nextMap[newKey] = Array.from(merged);
|
|
7716
8285
|
}
|
|
7717
8286
|
}
|
|
7718
8287
|
p[mapKey] = nextMap;
|
|
7719
8288
|
}
|
|
8289
|
+
copyOptionEffects(p, {
|
|
8290
|
+
triggerIdMap: new Map([
|
|
8291
|
+
[fieldId, id],
|
|
8292
|
+
...Array.from(optionIdMap.entries())
|
|
8293
|
+
]),
|
|
8294
|
+
targetFieldIdMap: /* @__PURE__ */ new Map([[fieldId, id]]),
|
|
8295
|
+
optionIdMap
|
|
8296
|
+
});
|
|
7720
8297
|
}
|
|
7721
8298
|
});
|
|
7722
8299
|
return id;
|
|
7723
8300
|
}
|
|
7724
8301
|
function duplicateOption(ctx, fieldId, optionId, opts) {
|
|
7725
|
-
var _a, _b, _c, _d, _e, _f;
|
|
7726
8302
|
const props = ctx.getProps();
|
|
7727
|
-
const
|
|
7728
|
-
|
|
7729
|
-
|
|
7730
|
-
const optIdx = ((_b = f.options) != null ? _b : []).findIndex((o) => o.id === optionId);
|
|
7731
|
-
if (optIdx < 0) {
|
|
7732
|
-
throw new Error(`Option not found: ${fieldId}::${optionId}`);
|
|
8303
|
+
const location = findMutableOption(props, optionId);
|
|
8304
|
+
if (!location || location.field.id !== fieldId) {
|
|
8305
|
+
throw new Error(`Option not found: ${fieldId}/${optionId}`);
|
|
7733
8306
|
}
|
|
7734
|
-
const src =
|
|
7735
|
-
const
|
|
7736
|
-
|
|
7737
|
-
|
|
7738
|
-
);
|
|
7739
|
-
const newLabel = ((_e = opts.labelStrategy) != null ? _e : nextCopyLabel)((_f = src.label) != null ? _f : src.id);
|
|
8307
|
+
const src = location.option;
|
|
8308
|
+
const optionIdMap = /* @__PURE__ */ new Map();
|
|
8309
|
+
const clone2 = cloneOptionTree(ctx, fieldId, src, opts, optionIdMap);
|
|
8310
|
+
const newId2 = clone2.id;
|
|
7740
8311
|
ctx.patchProps((p) => {
|
|
7741
|
-
var
|
|
7742
|
-
const
|
|
7743
|
-
|
|
7744
|
-
|
|
7745
|
-
arr.splice(optIdx + 1, 0, clone2);
|
|
7746
|
-
fld.options = arr;
|
|
8312
|
+
var _a;
|
|
8313
|
+
const current = findMutableOption(p, optionId);
|
|
8314
|
+
if (!current) return;
|
|
8315
|
+
current.siblings.splice(current.index + 1, 0, clone2);
|
|
7747
8316
|
if (opts.copyOptionMaps) {
|
|
7748
|
-
const oldKey = `${fieldId}::${optionId}`;
|
|
7749
|
-
const newKey = `${fieldId}::${newId2}`;
|
|
7750
8317
|
for (const mapKey of [
|
|
7751
8318
|
"includes_for_buttons",
|
|
7752
8319
|
"excludes_for_buttons"
|
|
7753
8320
|
]) {
|
|
7754
|
-
const m = (
|
|
7755
|
-
|
|
7756
|
-
|
|
7757
|
-
|
|
8321
|
+
const m = (_a = p[mapKey]) != null ? _a : {};
|
|
8322
|
+
for (const [oldKey, newKey] of optionIdMap.entries()) {
|
|
8323
|
+
if (m[oldKey]) {
|
|
8324
|
+
m[newKey] = Array.from(new Set(m[oldKey]));
|
|
8325
|
+
p[mapKey] = m;
|
|
8326
|
+
}
|
|
7758
8327
|
}
|
|
7759
8328
|
}
|
|
8329
|
+
copyOptionEffects(p, {
|
|
8330
|
+
triggerIdMap: optionIdMap,
|
|
8331
|
+
optionIdMap
|
|
8332
|
+
});
|
|
7760
8333
|
}
|
|
7761
8334
|
});
|
|
7762
8335
|
return newId2;
|
|
@@ -7818,54 +8391,6 @@ function removeNotice(ctx, id) {
|
|
|
7818
8391
|
|
|
7819
8392
|
// src/react/canvas/editor/editor-nodes.ts
|
|
7820
8393
|
import { cloneDeep as cloneDeep3 } from "lodash-es";
|
|
7821
|
-
|
|
7822
|
-
// src/react/canvas/editor/editor-utils.ts
|
|
7823
|
-
function ownerOfOption(props, optionId) {
|
|
7824
|
-
var _a, _b;
|
|
7825
|
-
for (const f of (_a = props.fields) != null ? _a : []) {
|
|
7826
|
-
const idx = ((_b = f.options) != null ? _b : []).findIndex((o) => o.id === optionId);
|
|
7827
|
-
if (idx >= 0) return { fieldId: f.id, index: idx };
|
|
7828
|
-
}
|
|
7829
|
-
return null;
|
|
7830
|
-
}
|
|
7831
|
-
function hasFieldOptions(field) {
|
|
7832
|
-
return Array.isArray(field == null ? void 0 : field.options) && field.options.length > 0;
|
|
7833
|
-
}
|
|
7834
|
-
function isActualButtonField(field) {
|
|
7835
|
-
return (field == null ? void 0 : field.button) === true && !hasFieldOptions(field);
|
|
7836
|
-
}
|
|
7837
|
-
function clearFieldButtonReceiverMaps(props, fieldId) {
|
|
7838
|
-
var _a, _b;
|
|
7839
|
-
if ((_a = props.includes_for_buttons) == null ? void 0 : _a[fieldId]) {
|
|
7840
|
-
delete props.includes_for_buttons[fieldId];
|
|
7841
|
-
}
|
|
7842
|
-
if ((_b = props.excludes_for_buttons) == null ? void 0 : _b[fieldId]) {
|
|
7843
|
-
delete props.excludes_for_buttons[fieldId];
|
|
7844
|
-
}
|
|
7845
|
-
if (props.includes_for_buttons && Object.keys(props.includes_for_buttons).length === 0) {
|
|
7846
|
-
delete props.includes_for_buttons;
|
|
7847
|
-
}
|
|
7848
|
-
if (props.excludes_for_buttons && Object.keys(props.excludes_for_buttons).length === 0) {
|
|
7849
|
-
delete props.excludes_for_buttons;
|
|
7850
|
-
}
|
|
7851
|
-
}
|
|
7852
|
-
function ensureServiceExists(opts, id) {
|
|
7853
|
-
if (typeof opts.serviceExists === "function") {
|
|
7854
|
-
if (!opts.serviceExists(id)) {
|
|
7855
|
-
throw new Error(`service_not_found:${String(id)}`);
|
|
7856
|
-
}
|
|
7857
|
-
return;
|
|
7858
|
-
}
|
|
7859
|
-
if (opts.serviceMap) {
|
|
7860
|
-
if (!Object.prototype.hasOwnProperty.call(opts.serviceMap, id)) {
|
|
7861
|
-
throw new Error(`service_not_found:${String(id)}`);
|
|
7862
|
-
}
|
|
7863
|
-
return;
|
|
7864
|
-
}
|
|
7865
|
-
throw new Error("service_checker_missing");
|
|
7866
|
-
}
|
|
7867
|
-
|
|
7868
|
-
// src/react/canvas/editor/editor-nodes.ts
|
|
7869
8394
|
var RELATION_MAP_KEYS = [
|
|
7870
8395
|
"includes_for_buttons",
|
|
7871
8396
|
"excludes_for_buttons",
|
|
@@ -7925,6 +8450,43 @@ function cleanRelationMapsForDeleted(p, deleted) {
|
|
|
7925
8450
|
if (!Object.keys(map).length) delete p[key];
|
|
7926
8451
|
}
|
|
7927
8452
|
}
|
|
8453
|
+
function cleanOptionEffectsForDeleted(p, deleted) {
|
|
8454
|
+
var _a, _b;
|
|
8455
|
+
const map = p.option_effects_for_buttons;
|
|
8456
|
+
if (!map) return;
|
|
8457
|
+
for (const triggerId of Object.keys(map)) {
|
|
8458
|
+
if (deleted.has(String(triggerId))) {
|
|
8459
|
+
delete map[triggerId];
|
|
8460
|
+
continue;
|
|
8461
|
+
}
|
|
8462
|
+
const targets = map[triggerId];
|
|
8463
|
+
for (const targetFieldId of Object.keys(targets != null ? targets : {})) {
|
|
8464
|
+
if (deleted.has(String(targetFieldId))) {
|
|
8465
|
+
delete targets[targetFieldId];
|
|
8466
|
+
continue;
|
|
8467
|
+
}
|
|
8468
|
+
const effect = targets[targetFieldId];
|
|
8469
|
+
if (!effect) continue;
|
|
8470
|
+
if (effect.include) {
|
|
8471
|
+
effect.include = effect.include.filter(
|
|
8472
|
+
(optionId) => !deleted.has(String(optionId))
|
|
8473
|
+
);
|
|
8474
|
+
if (!effect.include.length) delete effect.include;
|
|
8475
|
+
}
|
|
8476
|
+
if (effect.exclude) {
|
|
8477
|
+
effect.exclude = effect.exclude.filter(
|
|
8478
|
+
(optionId) => !deleted.has(String(optionId))
|
|
8479
|
+
);
|
|
8480
|
+
if (!effect.exclude.length) delete effect.exclude;
|
|
8481
|
+
}
|
|
8482
|
+
if (effect.forceVisible !== true && !((_a = effect.include) == null ? void 0 : _a.length) && !((_b = effect.exclude) == null ? void 0 : _b.length)) {
|
|
8483
|
+
delete targets[targetFieldId];
|
|
8484
|
+
}
|
|
8485
|
+
}
|
|
8486
|
+
if (!Object.keys(targets != null ? targets : {}).length) delete map[triggerId];
|
|
8487
|
+
}
|
|
8488
|
+
if (!Object.keys(map).length) delete p.option_effects_for_buttons;
|
|
8489
|
+
}
|
|
7928
8490
|
function cleanOrderForTagsForDeleted(p, deleted) {
|
|
7929
8491
|
var _a, _b;
|
|
7930
8492
|
const map = p.order_for_tags;
|
|
@@ -7960,28 +8522,37 @@ function applyDeleteCleanup(p, deleted) {
|
|
|
7960
8522
|
cleanTagRelationsForDeleted(p, deleted);
|
|
7961
8523
|
cleanFieldBindsForDeleted(p, deleted);
|
|
7962
8524
|
cleanRelationMapsForDeleted(p, deleted);
|
|
8525
|
+
cleanOptionEffectsForDeleted(p, deleted);
|
|
7963
8526
|
cleanOrderForTagsForDeleted(p, deleted);
|
|
7964
8527
|
cleanNoticesForDeleted(p, deleted);
|
|
7965
8528
|
}
|
|
8529
|
+
function collectOptionSubtreeIds(option) {
|
|
8530
|
+
var _a;
|
|
8531
|
+
return [
|
|
8532
|
+
String(option.id),
|
|
8533
|
+
...((_a = option.children) != null ? _a : []).flatMap((child) => collectOptionSubtreeIds(child))
|
|
8534
|
+
];
|
|
8535
|
+
}
|
|
7966
8536
|
function removeOptionInPlace(p, optionId) {
|
|
7967
8537
|
var _a;
|
|
7968
|
-
const
|
|
7969
|
-
if (!
|
|
7970
|
-
const
|
|
7971
|
-
|
|
7972
|
-
|
|
7973
|
-
|
|
7974
|
-
|
|
8538
|
+
const found = findMutableOption(p, optionId);
|
|
8539
|
+
if (!found) return [];
|
|
8540
|
+
const deleted = collectOptionSubtreeIds(found.option);
|
|
8541
|
+
found.siblings.splice(found.index, 1);
|
|
8542
|
+
if (found.parent && ((_a = found.parent.children) == null ? void 0 : _a.length) === 0) {
|
|
8543
|
+
delete found.parent.children;
|
|
8544
|
+
}
|
|
8545
|
+
return deleted;
|
|
7975
8546
|
}
|
|
7976
8547
|
function removeFieldInPlace(p, fieldId) {
|
|
7977
|
-
var _a, _b, _c, _d
|
|
8548
|
+
var _a, _b, _c, _d;
|
|
7978
8549
|
const field = ((_a = p.fields) != null ? _a : []).find((f) => f.id === fieldId);
|
|
7979
8550
|
if (!field) return [];
|
|
7980
|
-
const deleted = [fieldId, ...(
|
|
7981
|
-
const before = ((
|
|
7982
|
-
p.fields = ((
|
|
8551
|
+
const deleted = [fieldId, ...collectFieldOptionIds(field)];
|
|
8552
|
+
const before = ((_b = p.fields) != null ? _b : []).length;
|
|
8553
|
+
p.fields = ((_c = p.fields) != null ? _c : []).filter((f) => f.id !== fieldId);
|
|
7983
8554
|
clearFieldButtonReceiverMaps(p, fieldId);
|
|
7984
|
-
return ((
|
|
8555
|
+
return ((_d = p.fields) != null ? _d : []).length !== before ? deleted : [];
|
|
7985
8556
|
}
|
|
7986
8557
|
function removeTagInPlace(p, tagId) {
|
|
7987
8558
|
var _a, _b, _c;
|
|
@@ -7994,7 +8565,7 @@ function reLabel(ctx, id, nextLabel) {
|
|
|
7994
8565
|
ctx.exec({
|
|
7995
8566
|
name: "reLabel",
|
|
7996
8567
|
do: () => ctx.patchProps((p) => {
|
|
7997
|
-
var _a, _b, _c, _d, _e, _f
|
|
8568
|
+
var _a, _b, _c, _d, _e, _f;
|
|
7998
8569
|
if (ctx.isTagId(id)) {
|
|
7999
8570
|
const t = ((_a = p.filters) != null ? _a : []).find((x) => x.id === id);
|
|
8000
8571
|
if (!t) return;
|
|
@@ -8004,19 +8575,16 @@ function reLabel(ctx, id, nextLabel) {
|
|
|
8004
8575
|
return;
|
|
8005
8576
|
}
|
|
8006
8577
|
if (ctx.isOptionId(id)) {
|
|
8007
|
-
const
|
|
8008
|
-
if (!own) return;
|
|
8009
|
-
const f = ((_c = p.fields) != null ? _c : []).find((x) => x.id === own.fieldId);
|
|
8010
|
-
const o = (_d = f == null ? void 0 : f.options) == null ? void 0 : _d.find((x) => x.id === id);
|
|
8578
|
+
const o = (_c = findMutableOption(p, id)) == null ? void 0 : _c.option;
|
|
8011
8579
|
if (!o) return;
|
|
8012
|
-
if (((
|
|
8580
|
+
if (((_d = o.label) != null ? _d : "") === label) return;
|
|
8013
8581
|
o.label = label;
|
|
8014
8582
|
ctx.api.refreshGraph();
|
|
8015
8583
|
return;
|
|
8016
8584
|
}
|
|
8017
|
-
const fld = ((
|
|
8585
|
+
const fld = ((_e = p.fields) != null ? _e : []).find((x) => x.id === id);
|
|
8018
8586
|
if (!fld) return;
|
|
8019
|
-
if (((
|
|
8587
|
+
if (((_f = fld.label) != null ? _f : "") === label) return;
|
|
8020
8588
|
fld.label = label;
|
|
8021
8589
|
ctx.api.refreshGraph();
|
|
8022
8590
|
}),
|
|
@@ -8106,11 +8674,7 @@ function updateOption(ctx, optionId, patch) {
|
|
|
8106
8674
|
name: "updateOption",
|
|
8107
8675
|
do: () => ctx.patchProps((p) => {
|
|
8108
8676
|
var _a;
|
|
8109
|
-
const
|
|
8110
|
-
if (!owner) return;
|
|
8111
|
-
const f = ((_a = p.fields) != null ? _a : []).find((x) => x.id === owner.fieldId);
|
|
8112
|
-
if (!(f == null ? void 0 : f.options)) return;
|
|
8113
|
-
const o = f.options.find((x) => x.id === optionId);
|
|
8677
|
+
const o = (_a = findMutableOption(p, optionId)) == null ? void 0 : _a.option;
|
|
8114
8678
|
if (o) Object.assign(o, patch);
|
|
8115
8679
|
}),
|
|
8116
8680
|
undo: () => ctx.undo()
|
|
@@ -8123,9 +8687,9 @@ function removeOption(ctx, optionId) {
|
|
|
8123
8687
|
ctx.exec({
|
|
8124
8688
|
name: "removeOption",
|
|
8125
8689
|
do: () => ctx.patchProps((p) => {
|
|
8126
|
-
const
|
|
8127
|
-
if (!
|
|
8128
|
-
applyDeleteCleanup(p,
|
|
8690
|
+
const removedIds = removeOptionInPlace(p, optionId);
|
|
8691
|
+
if (!removedIds.length) return;
|
|
8692
|
+
applyDeleteCleanup(p, new Set(removedIds));
|
|
8129
8693
|
}),
|
|
8130
8694
|
undo: () => ctx.undo()
|
|
8131
8695
|
});
|
|
@@ -8136,7 +8700,7 @@ function editLabel(ctx, id, label) {
|
|
|
8136
8700
|
ctx.exec({
|
|
8137
8701
|
name: "editLabel",
|
|
8138
8702
|
do: () => ctx.patchProps((p) => {
|
|
8139
|
-
var _a, _b, _c
|
|
8703
|
+
var _a, _b, _c;
|
|
8140
8704
|
if (ctx.isTagId(id)) {
|
|
8141
8705
|
const t = ((_a = p.filters) != null ? _a : []).find((x) => x.id === id);
|
|
8142
8706
|
if (t) t.label = next;
|
|
@@ -8148,10 +8712,7 @@ function editLabel(ctx, id, label) {
|
|
|
8148
8712
|
return;
|
|
8149
8713
|
}
|
|
8150
8714
|
if (ctx.isOptionId(id)) {
|
|
8151
|
-
const
|
|
8152
|
-
if (!own) return;
|
|
8153
|
-
const f = ((_c = p.fields) != null ? _c : []).find((x) => x.id === own.fieldId);
|
|
8154
|
-
const o = (_d = f == null ? void 0 : f.options) == null ? void 0 : _d.find((x) => x.id === id);
|
|
8715
|
+
const o = (_c = findMutableOption(p, id)) == null ? void 0 : _c.option;
|
|
8155
8716
|
if (o) o.label = next;
|
|
8156
8717
|
return;
|
|
8157
8718
|
}
|
|
@@ -8176,7 +8737,7 @@ function setService(ctx, id, input) {
|
|
|
8176
8737
|
ctx.exec({
|
|
8177
8738
|
name: "setService",
|
|
8178
8739
|
do: () => ctx.patchProps((p) => {
|
|
8179
|
-
var _a, _b, _c, _d, _e
|
|
8740
|
+
var _a, _b, _c, _d, _e;
|
|
8180
8741
|
const hasSidKey = Object.prototype.hasOwnProperty.call(
|
|
8181
8742
|
input,
|
|
8182
8743
|
"service_id"
|
|
@@ -8194,12 +8755,9 @@ function setService(ctx, id, input) {
|
|
|
8194
8755
|
return;
|
|
8195
8756
|
}
|
|
8196
8757
|
if (ctx.isOptionId(id)) {
|
|
8197
|
-
const
|
|
8198
|
-
if (!own) return;
|
|
8199
|
-
const f2 = ((_b = p.fields) != null ? _b : []).find((x) => x.id === own.fieldId);
|
|
8200
|
-
const o = (_c = f2 == null ? void 0 : f2.options) == null ? void 0 : _c.find((x) => x.id === id);
|
|
8758
|
+
const o = (_b = findMutableOption(p, id)) == null ? void 0 : _b.option;
|
|
8201
8759
|
if (!o) return;
|
|
8202
|
-
const currentRole = (
|
|
8760
|
+
const currentRole = (_c = o.pricing_role) != null ? _c : "base";
|
|
8203
8761
|
const role = nextRole != null ? nextRole : currentRole;
|
|
8204
8762
|
if (role === "utility") {
|
|
8205
8763
|
if (hasSidKey && sid !== void 0) {
|
|
@@ -8220,7 +8778,7 @@ function setService(ctx, id, input) {
|
|
|
8220
8778
|
}
|
|
8221
8779
|
return;
|
|
8222
8780
|
}
|
|
8223
|
-
const f = ((
|
|
8781
|
+
const f = ((_d = p.fields) != null ? _d : []).find((x) => x.id === id);
|
|
8224
8782
|
if (!f) {
|
|
8225
8783
|
throw new Error(
|
|
8226
8784
|
'setService only supports tag ("t:*"), option ("o:*"), or field ("f:*") ids'
|
|
@@ -8231,7 +8789,7 @@ function setService(ctx, id, input) {
|
|
|
8231
8789
|
if (nextRole) {
|
|
8232
8790
|
f.pricing_role = nextRole;
|
|
8233
8791
|
}
|
|
8234
|
-
const effectiveRole = (
|
|
8792
|
+
const effectiveRole = (_e = f.pricing_role) != null ? _e : "base";
|
|
8235
8793
|
if (isOptionBased) {
|
|
8236
8794
|
if (hasSidKey) {
|
|
8237
8795
|
ctx.api.emit("error", {
|
|
@@ -8343,13 +8901,15 @@ function updateField(ctx, id, patch) {
|
|
|
8343
8901
|
let prev;
|
|
8344
8902
|
let prevIncludesForButton;
|
|
8345
8903
|
let prevExcludesForButton;
|
|
8904
|
+
let prevOptionEffectsForButton;
|
|
8346
8905
|
ctx.exec({
|
|
8347
8906
|
name: "updateField",
|
|
8348
8907
|
do: () => ctx.patchProps((p) => {
|
|
8349
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
8908
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
8350
8909
|
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;
|
|
8351
8910
|
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;
|
|
8352
|
-
|
|
8911
|
+
prevOptionEffectsForButton = ((_g = p.option_effects_for_buttons) == null ? void 0 : _g[id]) ? cloneDeep3(p.option_effects_for_buttons[id]) : void 0;
|
|
8912
|
+
p.fields = ((_h = p.fields) != null ? _h : []).map((f) => {
|
|
8353
8913
|
if (f.id !== id) return f;
|
|
8354
8914
|
prev = cloneDeep3(f);
|
|
8355
8915
|
const nextField = { ...f, ...patch };
|
|
@@ -8360,7 +8920,7 @@ function updateField(ctx, id, patch) {
|
|
|
8360
8920
|
});
|
|
8361
8921
|
}),
|
|
8362
8922
|
undo: () => ctx.patchProps((p) => {
|
|
8363
|
-
var _a, _b, _c;
|
|
8923
|
+
var _a, _b, _c, _d;
|
|
8364
8924
|
p.fields = ((_a = p.fields) != null ? _a : []).map(
|
|
8365
8925
|
(f) => f.id === id && prev ? prev : f
|
|
8366
8926
|
);
|
|
@@ -8378,6 +8938,12 @@ function updateField(ctx, id, patch) {
|
|
|
8378
8938
|
[id]: [...prevExcludesForButton]
|
|
8379
8939
|
};
|
|
8380
8940
|
}
|
|
8941
|
+
if (prevOptionEffectsForButton) {
|
|
8942
|
+
p.option_effects_for_buttons = {
|
|
8943
|
+
...(_d = p.option_effects_for_buttons) != null ? _d : {},
|
|
8944
|
+
[id]: cloneDeep3(prevOptionEffectsForButton)
|
|
8945
|
+
};
|
|
8946
|
+
}
|
|
8381
8947
|
})
|
|
8382
8948
|
});
|
|
8383
8949
|
}
|
|
@@ -8424,9 +8990,9 @@ function remove(ctx, id) {
|
|
|
8424
8990
|
ctx.exec({
|
|
8425
8991
|
name: "removeOption",
|
|
8426
8992
|
do: () => ctx.patchProps((p) => {
|
|
8427
|
-
const
|
|
8428
|
-
if (!
|
|
8429
|
-
applyDeleteCleanup(p,
|
|
8993
|
+
const removedIds = removeOptionInPlace(p, key);
|
|
8994
|
+
if (!removedIds.length) return;
|
|
8995
|
+
applyDeleteCleanup(p, new Set(removedIds));
|
|
8430
8996
|
}),
|
|
8431
8997
|
undo: () => ctx.undo()
|
|
8432
8998
|
});
|
|
@@ -8443,10 +9009,7 @@ function removeMany(ctx, ids) {
|
|
|
8443
9009
|
const existingFieldIds = new Set(((_a = p.fields) != null ? _a : []).map((f) => String(f.id)));
|
|
8444
9010
|
const existingTagIds = new Set(((_b = p.filters) != null ? _b : []).map((t) => String(t.id)));
|
|
8445
9011
|
const existingOptionIds = new Set(
|
|
8446
|
-
((_c = p.fields) != null ? _c : []).flatMap((f) =>
|
|
8447
|
-
var _a2;
|
|
8448
|
-
return ((_a2 = f.options) != null ? _a2 : []).map((o) => String(o.id));
|
|
8449
|
-
})
|
|
9012
|
+
((_c = p.fields) != null ? _c : []).flatMap((f) => collectFieldOptionIds(f))
|
|
8450
9013
|
);
|
|
8451
9014
|
const fieldIds = ordered.filter((id) => ctx.isFieldId(id) && existingFieldIds.has(id));
|
|
8452
9015
|
const fieldIdSet = new Set(fieldIds);
|
|
@@ -8459,7 +9022,9 @@ function removeMany(ctx, ids) {
|
|
|
8459
9022
|
});
|
|
8460
9023
|
const deleted = /* @__PURE__ */ new Set();
|
|
8461
9024
|
for (const optionId of optionIds) {
|
|
8462
|
-
|
|
9025
|
+
for (const removedId of removeOptionInPlace(p, optionId)) {
|
|
9026
|
+
deleted.add(removedId);
|
|
9027
|
+
}
|
|
8463
9028
|
}
|
|
8464
9029
|
for (const fieldId of fieldIds) {
|
|
8465
9030
|
const removedIds = removeFieldInPlace(p, fieldId);
|
|
@@ -8474,7 +9039,7 @@ function removeMany(ctx, ids) {
|
|
|
8474
9039
|
});
|
|
8475
9040
|
}
|
|
8476
9041
|
function getNode(ctx, id) {
|
|
8477
|
-
var _a, _b, _c
|
|
9042
|
+
var _a, _b, _c;
|
|
8478
9043
|
const props = ctx.getProps();
|
|
8479
9044
|
if (ctx.isTagId(id)) {
|
|
8480
9045
|
const t = ((_a = props.filters) != null ? _a : []).find((x) => x.id === id);
|
|
@@ -8491,8 +9056,7 @@ function getNode(ctx, id) {
|
|
|
8491
9056
|
}
|
|
8492
9057
|
if (ctx.isOptionId(id)) {
|
|
8493
9058
|
const own = ownerOfOption(props, id);
|
|
8494
|
-
const
|
|
8495
|
-
const o = (_d = f == null ? void 0 : f.options) == null ? void 0 : _d.find((x) => x.id === id);
|
|
9059
|
+
const o = (_c = findMutableOption(props, id)) == null ? void 0 : _c.option;
|
|
8496
9060
|
return {
|
|
8497
9061
|
kind: "option",
|
|
8498
9062
|
data: o,
|
|
@@ -9029,7 +9593,7 @@ function connect(ctx, kind, fromId, toId2) {
|
|
|
9029
9593
|
ctx.exec({
|
|
9030
9594
|
name: `connect:${kind}`,
|
|
9031
9595
|
do: () => ctx.patchProps((p) => {
|
|
9032
|
-
var _a, _b, _c, _d, _e, _f, _g
|
|
9596
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
9033
9597
|
if (kind === "bind") {
|
|
9034
9598
|
if (ctx.isTagId(fromId) && ctx.isTagId(toId2)) {
|
|
9035
9599
|
if (wouldCreateTagCycle(ctx, p, fromId, toId2)) {
|
|
@@ -9109,12 +9673,10 @@ function connect(ctx, kind, fromId, toId2) {
|
|
|
9109
9673
|
return;
|
|
9110
9674
|
}
|
|
9111
9675
|
if (toId2.startsWith("o:")) {
|
|
9112
|
-
|
|
9113
|
-
|
|
9114
|
-
|
|
9115
|
-
|
|
9116
|
-
return;
|
|
9117
|
-
}
|
|
9676
|
+
const o = (_g = findMutableOption(p, toId2)) == null ? void 0 : _g.option;
|
|
9677
|
+
if (o) {
|
|
9678
|
+
o.service_id = fromId;
|
|
9679
|
+
return;
|
|
9118
9680
|
}
|
|
9119
9681
|
return;
|
|
9120
9682
|
}
|
|
@@ -9131,7 +9693,7 @@ function disconnect(ctx, kind, fromId, toId2) {
|
|
|
9131
9693
|
ctx.exec({
|
|
9132
9694
|
name: `disconnect:${kind}`,
|
|
9133
9695
|
do: () => ctx.patchProps((p) => {
|
|
9134
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i
|
|
9696
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
9135
9697
|
if (kind === "bind") {
|
|
9136
9698
|
if (ctx.isTagId(fromId) && ctx.isTagId(toId2)) {
|
|
9137
9699
|
const child = ((_a = p.filters) != null ? _a : []).find(
|
|
@@ -9207,12 +9769,10 @@ function disconnect(ctx, kind, fromId, toId2) {
|
|
|
9207
9769
|
return;
|
|
9208
9770
|
}
|
|
9209
9771
|
if (toId2.startsWith("o:")) {
|
|
9210
|
-
|
|
9211
|
-
|
|
9212
|
-
|
|
9213
|
-
|
|
9214
|
-
return;
|
|
9215
|
-
}
|
|
9772
|
+
const o = (_i = findMutableOption(p, toId2)) == null ? void 0 : _i.option;
|
|
9773
|
+
if (o) {
|
|
9774
|
+
delete o.service_id;
|
|
9775
|
+
return;
|
|
9216
9776
|
}
|
|
9217
9777
|
return;
|
|
9218
9778
|
}
|
|
@@ -9235,6 +9795,250 @@ function addMappedField(p, mapKey, fromId, toId2) {
|
|
|
9235
9795
|
p[mapKey] = maps;
|
|
9236
9796
|
}
|
|
9237
9797
|
|
|
9798
|
+
// src/react/canvas/editor/editor-option-effects.ts
|
|
9799
|
+
function assertCanonicalId(id, label) {
|
|
9800
|
+
if (!id || id.includes("::") || id.includes("/")) {
|
|
9801
|
+
throw new Error(
|
|
9802
|
+
`${label}: expected a raw field or option id, not a composite/path id`
|
|
9803
|
+
);
|
|
9804
|
+
}
|
|
9805
|
+
}
|
|
9806
|
+
function assertTrigger(ctx, triggerId) {
|
|
9807
|
+
assertCanonicalId(triggerId, "option effect trigger");
|
|
9808
|
+
const trigger = ctx.getNode(triggerId);
|
|
9809
|
+
if (trigger.kind === "option" && trigger.data) return;
|
|
9810
|
+
if (trigger.kind === "field" && trigger.data && isActualButtonField(trigger.data)) {
|
|
9811
|
+
return;
|
|
9812
|
+
}
|
|
9813
|
+
throw new Error(
|
|
9814
|
+
"option effect trigger must be an option id or button field id"
|
|
9815
|
+
);
|
|
9816
|
+
}
|
|
9817
|
+
function assertTargetField(props, targetFieldId) {
|
|
9818
|
+
var _a;
|
|
9819
|
+
assertCanonicalId(targetFieldId, "option effect target");
|
|
9820
|
+
const field = ((_a = props.fields) != null ? _a : []).find((item) => item.id === targetFieldId);
|
|
9821
|
+
if (!field) {
|
|
9822
|
+
throw new Error(`option effect target field not found: ${targetFieldId}`);
|
|
9823
|
+
}
|
|
9824
|
+
return field;
|
|
9825
|
+
}
|
|
9826
|
+
function dedupe2(values) {
|
|
9827
|
+
if (!values) return void 0;
|
|
9828
|
+
const out = [];
|
|
9829
|
+
for (const value of values) {
|
|
9830
|
+
const id = String(value);
|
|
9831
|
+
if (!id || out.includes(id)) continue;
|
|
9832
|
+
out.push(id);
|
|
9833
|
+
}
|
|
9834
|
+
return out.length ? out : void 0;
|
|
9835
|
+
}
|
|
9836
|
+
function assertTargetOptions(props, targetFieldId, ids, kind) {
|
|
9837
|
+
if (!(ids == null ? void 0 : ids.length)) return;
|
|
9838
|
+
const field = assertTargetField(props, targetFieldId);
|
|
9839
|
+
const valid = fieldOptionIdSet(field);
|
|
9840
|
+
for (const id of ids) {
|
|
9841
|
+
assertCanonicalId(String(id), `option effect ${kind} option`);
|
|
9842
|
+
if (!valid.has(String(id))) {
|
|
9843
|
+
throw new Error(
|
|
9844
|
+
`option effect ${kind} option not found under ${targetFieldId}: ${String(id)}`
|
|
9845
|
+
);
|
|
9846
|
+
}
|
|
9847
|
+
}
|
|
9848
|
+
}
|
|
9849
|
+
function normalizeEffect(effect) {
|
|
9850
|
+
var _a;
|
|
9851
|
+
if (!effect) return void 0;
|
|
9852
|
+
const exclude2 = dedupe2(effect.exclude);
|
|
9853
|
+
const excluded = new Set(exclude2 != null ? exclude2 : []);
|
|
9854
|
+
const include2 = (_a = dedupe2(effect.include)) == null ? void 0 : _a.filter((id) => !excluded.has(id));
|
|
9855
|
+
const out = {};
|
|
9856
|
+
if (effect.forceVisible === true) out.forceVisible = true;
|
|
9857
|
+
if (include2 == null ? void 0 : include2.length) out.include = include2;
|
|
9858
|
+
if (exclude2 == null ? void 0 : exclude2.length) out.exclude = exclude2;
|
|
9859
|
+
return Object.keys(out).length ? out : void 0;
|
|
9860
|
+
}
|
|
9861
|
+
function ensureTargetMap(props, triggerId) {
|
|
9862
|
+
var _a, _b, _c;
|
|
9863
|
+
(_a = props.option_effects_for_buttons) != null ? _a : props.option_effects_for_buttons = {};
|
|
9864
|
+
(_c = (_b = props.option_effects_for_buttons)[triggerId]) != null ? _c : _b[triggerId] = {};
|
|
9865
|
+
return props.option_effects_for_buttons[triggerId];
|
|
9866
|
+
}
|
|
9867
|
+
function pruneEffectMap(props, triggerId) {
|
|
9868
|
+
const map = props.option_effects_for_buttons;
|
|
9869
|
+
if (!map) return;
|
|
9870
|
+
const keys = triggerId ? [triggerId] : Object.keys(map);
|
|
9871
|
+
for (const key of keys) {
|
|
9872
|
+
const targets = map[key];
|
|
9873
|
+
if (!targets || Object.keys(targets).length === 0) delete map[key];
|
|
9874
|
+
}
|
|
9875
|
+
if (Object.keys(map).length === 0) delete props.option_effects_for_buttons;
|
|
9876
|
+
}
|
|
9877
|
+
function validateEffect(ctx, props, triggerId, targetFieldId, effect) {
|
|
9878
|
+
assertTrigger(ctx, triggerId);
|
|
9879
|
+
assertTargetField(props, targetFieldId);
|
|
9880
|
+
assertTargetOptions(props, targetFieldId, effect == null ? void 0 : effect.include, "include");
|
|
9881
|
+
assertTargetOptions(props, targetFieldId, effect == null ? void 0 : effect.exclude, "exclude");
|
|
9882
|
+
return normalizeEffect(effect);
|
|
9883
|
+
}
|
|
9884
|
+
function setOptionEffect(ctx, triggerId, targetFieldId, effect) {
|
|
9885
|
+
ctx.exec({
|
|
9886
|
+
name: "setOptionEffect",
|
|
9887
|
+
do: () => ctx.patchProps((props) => {
|
|
9888
|
+
var _a;
|
|
9889
|
+
const normalized = validateEffect(
|
|
9890
|
+
ctx,
|
|
9891
|
+
props,
|
|
9892
|
+
triggerId,
|
|
9893
|
+
targetFieldId,
|
|
9894
|
+
effect
|
|
9895
|
+
);
|
|
9896
|
+
if (!normalized) {
|
|
9897
|
+
const map = (_a = props.option_effects_for_buttons) == null ? void 0 : _a[triggerId];
|
|
9898
|
+
if (map) delete map[targetFieldId];
|
|
9899
|
+
pruneEffectMap(props, triggerId);
|
|
9900
|
+
return;
|
|
9901
|
+
}
|
|
9902
|
+
ensureTargetMap(props, triggerId)[targetFieldId] = normalized;
|
|
9903
|
+
}),
|
|
9904
|
+
undo: () => ctx.undo()
|
|
9905
|
+
});
|
|
9906
|
+
}
|
|
9907
|
+
function patchOptionEffect(ctx, triggerId, targetFieldId, patch) {
|
|
9908
|
+
ctx.exec({
|
|
9909
|
+
name: "patchOptionEffect",
|
|
9910
|
+
do: () => ctx.patchProps((props) => {
|
|
9911
|
+
var _a, _b, _c, _d;
|
|
9912
|
+
const current = (_c = (_b = (_a = props.option_effects_for_buttons) == null ? void 0 : _a[triggerId]) == null ? void 0 : _b[targetFieldId]) != null ? _c : {};
|
|
9913
|
+
const merged = {
|
|
9914
|
+
...current,
|
|
9915
|
+
...patch
|
|
9916
|
+
};
|
|
9917
|
+
const normalized = validateEffect(
|
|
9918
|
+
ctx,
|
|
9919
|
+
props,
|
|
9920
|
+
triggerId,
|
|
9921
|
+
targetFieldId,
|
|
9922
|
+
merged
|
|
9923
|
+
);
|
|
9924
|
+
if (!normalized) {
|
|
9925
|
+
const map = (_d = props.option_effects_for_buttons) == null ? void 0 : _d[triggerId];
|
|
9926
|
+
if (map) delete map[targetFieldId];
|
|
9927
|
+
pruneEffectMap(props, triggerId);
|
|
9928
|
+
return;
|
|
9929
|
+
}
|
|
9930
|
+
ensureTargetMap(props, triggerId)[targetFieldId] = normalized;
|
|
9931
|
+
}),
|
|
9932
|
+
undo: () => ctx.undo()
|
|
9933
|
+
});
|
|
9934
|
+
}
|
|
9935
|
+
function clearOptionEffect(ctx, triggerId, targetFieldId) {
|
|
9936
|
+
ctx.exec({
|
|
9937
|
+
name: "clearOptionEffect",
|
|
9938
|
+
do: () => ctx.patchProps((props) => {
|
|
9939
|
+
var _a;
|
|
9940
|
+
const map = (_a = props.option_effects_for_buttons) == null ? void 0 : _a[triggerId];
|
|
9941
|
+
if (!map) return;
|
|
9942
|
+
delete map[targetFieldId];
|
|
9943
|
+
pruneEffectMap(props, triggerId);
|
|
9944
|
+
}),
|
|
9945
|
+
undo: () => ctx.undo()
|
|
9946
|
+
});
|
|
9947
|
+
}
|
|
9948
|
+
function clearOptionEffectsForTrigger(ctx, triggerId) {
|
|
9949
|
+
ctx.exec({
|
|
9950
|
+
name: "clearOptionEffectsForTrigger",
|
|
9951
|
+
do: () => ctx.patchProps((props) => {
|
|
9952
|
+
if (!props.option_effects_for_buttons) return;
|
|
9953
|
+
delete props.option_effects_for_buttons[triggerId];
|
|
9954
|
+
pruneEffectMap(props);
|
|
9955
|
+
}),
|
|
9956
|
+
undo: () => ctx.undo()
|
|
9957
|
+
});
|
|
9958
|
+
}
|
|
9959
|
+
function clearOptionEffectsForTarget(ctx, targetFieldId) {
|
|
9960
|
+
ctx.exec({
|
|
9961
|
+
name: "clearOptionEffectsForTarget",
|
|
9962
|
+
do: () => ctx.patchProps((props) => {
|
|
9963
|
+
var _a;
|
|
9964
|
+
const map = props.option_effects_for_buttons;
|
|
9965
|
+
if (!map) return;
|
|
9966
|
+
for (const triggerId of Object.keys(map)) {
|
|
9967
|
+
(_a = map[triggerId]) == null ? true : delete _a[targetFieldId];
|
|
9968
|
+
}
|
|
9969
|
+
pruneEffectMap(props);
|
|
9970
|
+
}),
|
|
9971
|
+
undo: () => ctx.undo()
|
|
9972
|
+
});
|
|
9973
|
+
}
|
|
9974
|
+
function addOptionEffectOptions(ctx, triggerId, targetFieldId, kind, optionIds) {
|
|
9975
|
+
var _a;
|
|
9976
|
+
const additions = (_a = dedupe2(optionIds)) != null ? _a : [];
|
|
9977
|
+
if (!additions.length) return;
|
|
9978
|
+
ctx.exec({
|
|
9979
|
+
name: "addOptionEffectOptions",
|
|
9980
|
+
do: () => ctx.patchProps((props) => {
|
|
9981
|
+
var _a2, _b, _c, _d;
|
|
9982
|
+
const current = (_c = (_b = (_a2 = props.option_effects_for_buttons) == null ? void 0 : _a2[triggerId]) == null ? void 0 : _b[targetFieldId]) != null ? _c : {};
|
|
9983
|
+
const nextValues = dedupe2([
|
|
9984
|
+
...(_d = current[kind]) != null ? _d : [],
|
|
9985
|
+
...additions
|
|
9986
|
+
]);
|
|
9987
|
+
const normalized = validateEffect(
|
|
9988
|
+
ctx,
|
|
9989
|
+
props,
|
|
9990
|
+
triggerId,
|
|
9991
|
+
targetFieldId,
|
|
9992
|
+
{
|
|
9993
|
+
...current,
|
|
9994
|
+
[kind]: nextValues
|
|
9995
|
+
}
|
|
9996
|
+
);
|
|
9997
|
+
if (!normalized) return;
|
|
9998
|
+
ensureTargetMap(props, triggerId)[targetFieldId] = normalized;
|
|
9999
|
+
}),
|
|
10000
|
+
undo: () => ctx.undo()
|
|
10001
|
+
});
|
|
10002
|
+
}
|
|
10003
|
+
function removeOptionEffectOptions(ctx, triggerId, targetFieldId, kind, optionIds) {
|
|
10004
|
+
var _a;
|
|
10005
|
+
const removals = new Set((_a = dedupe2(optionIds)) != null ? _a : []);
|
|
10006
|
+
if (!removals.size) return;
|
|
10007
|
+
ctx.exec({
|
|
10008
|
+
name: "removeOptionEffectOptions",
|
|
10009
|
+
do: () => ctx.patchProps((props) => {
|
|
10010
|
+
var _a2, _b, _c, _d, _e;
|
|
10011
|
+
const current = (_b = (_a2 = props.option_effects_for_buttons) == null ? void 0 : _a2[triggerId]) == null ? void 0 : _b[targetFieldId];
|
|
10012
|
+
if (!current) return;
|
|
10013
|
+
const next = {
|
|
10014
|
+
...current,
|
|
10015
|
+
[kind]: ((_c = current[kind]) != null ? _c : []).filter(
|
|
10016
|
+
(optionId) => !removals.has(optionId)
|
|
10017
|
+
)
|
|
10018
|
+
};
|
|
10019
|
+
const normalized = validateEffect(
|
|
10020
|
+
ctx,
|
|
10021
|
+
props,
|
|
10022
|
+
triggerId,
|
|
10023
|
+
targetFieldId,
|
|
10024
|
+
next
|
|
10025
|
+
);
|
|
10026
|
+
if (!normalized) {
|
|
10027
|
+
(_e = (_d = props.option_effects_for_buttons) == null ? void 0 : _d[triggerId]) == null ? true : delete _e[targetFieldId];
|
|
10028
|
+
pruneEffectMap(props, triggerId);
|
|
10029
|
+
return;
|
|
10030
|
+
}
|
|
10031
|
+
ensureTargetMap(props, triggerId)[targetFieldId] = normalized;
|
|
10032
|
+
}),
|
|
10033
|
+
undo: () => ctx.undo()
|
|
10034
|
+
});
|
|
10035
|
+
}
|
|
10036
|
+
function setOptionEffectForceVisible(ctx, triggerId, targetFieldId, forceVisible) {
|
|
10037
|
+
patchOptionEffect(ctx, triggerId, targetFieldId, {
|
|
10038
|
+
forceVisible: forceVisible === true ? true : void 0
|
|
10039
|
+
});
|
|
10040
|
+
}
|
|
10041
|
+
|
|
9238
10042
|
// src/react/canvas/editor/editor-service-filter.ts
|
|
9239
10043
|
function filterServicesForVisibleGroup2(ctx, candidates, input) {
|
|
9240
10044
|
const coreInput = {
|
|
@@ -9821,7 +10625,7 @@ var Editor = class {
|
|
|
9821
10625
|
if (!ordered.length) return;
|
|
9822
10626
|
this.transact("clearServiceMany", () => {
|
|
9823
10627
|
this.patchProps((p) => {
|
|
9824
|
-
var _a, _b
|
|
10628
|
+
var _a, _b;
|
|
9825
10629
|
for (const id of ordered) {
|
|
9826
10630
|
if (this.isTagId(id)) {
|
|
9827
10631
|
const t = ((_a = p.filters) != null ? _a : []).find((x) => x.id === id);
|
|
@@ -9834,10 +10638,8 @@ var Editor = class {
|
|
|
9834
10638
|
continue;
|
|
9835
10639
|
}
|
|
9836
10640
|
if (this.isOptionId(id)) {
|
|
9837
|
-
const
|
|
9838
|
-
|
|
9839
|
-
const f = ((_c = p.fields) != null ? _c : []).find((x) => x.id === own.fieldId);
|
|
9840
|
-
const o = (_d = f == null ? void 0 : f.options) == null ? void 0 : _d.find((x) => x.id === id);
|
|
10641
|
+
const found = findMutableOption(p, id);
|
|
10642
|
+
const o = found == null ? void 0 : found.option;
|
|
9841
10643
|
if (o && "service_id" in o) delete o.service_id;
|
|
9842
10644
|
}
|
|
9843
10645
|
}
|
|
@@ -9886,7 +10688,7 @@ var Editor = class {
|
|
|
9886
10688
|
if (!selected.size) return;
|
|
9887
10689
|
this.transact("clearRelationsMany", () => {
|
|
9888
10690
|
this.patchProps((p) => {
|
|
9889
|
-
var _a, _b, _c;
|
|
10691
|
+
var _a, _b, _c, _d, _e;
|
|
9890
10692
|
const clearOwned = mode === "owned" || mode === "both";
|
|
9891
10693
|
const clearIncoming = mode === "incoming" || mode === "both";
|
|
9892
10694
|
for (const t of (_a = p.filters) != null ? _a : []) {
|
|
@@ -9926,6 +10728,44 @@ var Editor = class {
|
|
|
9926
10728
|
}
|
|
9927
10729
|
if (!Object.keys(map).length) delete p[k];
|
|
9928
10730
|
}
|
|
10731
|
+
const effectMap = p.option_effects_for_buttons;
|
|
10732
|
+
if (effectMap) {
|
|
10733
|
+
for (const triggerId of Object.keys(effectMap)) {
|
|
10734
|
+
if (clearOwned && selected.has(String(triggerId))) {
|
|
10735
|
+
delete effectMap[triggerId];
|
|
10736
|
+
continue;
|
|
10737
|
+
}
|
|
10738
|
+
const targets = effectMap[triggerId];
|
|
10739
|
+
if (!targets || !clearIncoming) continue;
|
|
10740
|
+
for (const targetFieldId of Object.keys(targets)) {
|
|
10741
|
+
if (selected.has(String(targetFieldId))) {
|
|
10742
|
+
delete targets[targetFieldId];
|
|
10743
|
+
continue;
|
|
10744
|
+
}
|
|
10745
|
+
const effect = targets[targetFieldId];
|
|
10746
|
+
if (!effect) continue;
|
|
10747
|
+
if (effect.include) {
|
|
10748
|
+
effect.include = effect.include.filter(
|
|
10749
|
+
(optionId) => !selected.has(String(optionId))
|
|
10750
|
+
);
|
|
10751
|
+
if (!effect.include.length) delete effect.include;
|
|
10752
|
+
}
|
|
10753
|
+
if (effect.exclude) {
|
|
10754
|
+
effect.exclude = effect.exclude.filter(
|
|
10755
|
+
(optionId) => !selected.has(String(optionId))
|
|
10756
|
+
);
|
|
10757
|
+
if (!effect.exclude.length) delete effect.exclude;
|
|
10758
|
+
}
|
|
10759
|
+
if (effect.forceVisible !== true && !((_d = effect.include) == null ? void 0 : _d.length) && !((_e = effect.exclude) == null ? void 0 : _e.length)) {
|
|
10760
|
+
delete targets[targetFieldId];
|
|
10761
|
+
}
|
|
10762
|
+
}
|
|
10763
|
+
if (!Object.keys(targets).length) delete effectMap[triggerId];
|
|
10764
|
+
}
|
|
10765
|
+
if (!Object.keys(effectMap).length) {
|
|
10766
|
+
delete p.option_effects_for_buttons;
|
|
10767
|
+
}
|
|
10768
|
+
}
|
|
9929
10769
|
});
|
|
9930
10770
|
});
|
|
9931
10771
|
}
|
|
@@ -9937,7 +10777,7 @@ var Editor = class {
|
|
|
9937
10777
|
const suffix = (_b = input.suffix) != null ? _b : "";
|
|
9938
10778
|
this.transact("renameLabelsMany", () => {
|
|
9939
10779
|
this.patchProps((p) => {
|
|
9940
|
-
var _a2, _b2, _c, _d, _e, _f
|
|
10780
|
+
var _a2, _b2, _c, _d, _e, _f;
|
|
9941
10781
|
for (const id of ordered) {
|
|
9942
10782
|
if (this.isTagId(id)) {
|
|
9943
10783
|
const t = ((_a2 = p.filters) != null ? _a2 : []).find((x) => x.id === id);
|
|
@@ -9950,11 +10790,8 @@ var Editor = class {
|
|
|
9950
10790
|
continue;
|
|
9951
10791
|
}
|
|
9952
10792
|
if (this.isOptionId(id)) {
|
|
9953
|
-
const
|
|
9954
|
-
if (
|
|
9955
|
-
const f = ((_e = p.fields) != null ? _e : []).find((x) => x.id === own.fieldId);
|
|
9956
|
-
const o = (_f = f == null ? void 0 : f.options) == null ? void 0 : _f.find((x) => x.id === id);
|
|
9957
|
-
if (o) o.label = `${prefix}${(_g = o.label) != null ? _g : ""}${suffix}`.trim();
|
|
10793
|
+
const o = (_e = findMutableOption(p, id)) == null ? void 0 : _e.option;
|
|
10794
|
+
if (o) o.label = `${prefix}${(_f = o.label) != null ? _f : ""}${suffix}`.trim();
|
|
9958
10795
|
}
|
|
9959
10796
|
}
|
|
9960
10797
|
});
|
|
@@ -10107,6 +10944,57 @@ var Editor = class {
|
|
|
10107
10944
|
exclude(receiverId, idOrIds) {
|
|
10108
10945
|
return exclude(this.moduleCtx(), receiverId, idOrIds);
|
|
10109
10946
|
}
|
|
10947
|
+
setOptionEffect(triggerId, targetFieldId, effect) {
|
|
10948
|
+
return setOptionEffect(
|
|
10949
|
+
this.moduleCtx(),
|
|
10950
|
+
triggerId,
|
|
10951
|
+
targetFieldId,
|
|
10952
|
+
effect
|
|
10953
|
+
);
|
|
10954
|
+
}
|
|
10955
|
+
patchOptionEffect(triggerId, targetFieldId, patch) {
|
|
10956
|
+
return patchOptionEffect(
|
|
10957
|
+
this.moduleCtx(),
|
|
10958
|
+
triggerId,
|
|
10959
|
+
targetFieldId,
|
|
10960
|
+
patch
|
|
10961
|
+
);
|
|
10962
|
+
}
|
|
10963
|
+
clearOptionEffect(triggerId, targetFieldId) {
|
|
10964
|
+
return clearOptionEffect(this.moduleCtx(), triggerId, targetFieldId);
|
|
10965
|
+
}
|
|
10966
|
+
clearOptionEffectsForTrigger(triggerId) {
|
|
10967
|
+
return clearOptionEffectsForTrigger(this.moduleCtx(), triggerId);
|
|
10968
|
+
}
|
|
10969
|
+
clearOptionEffectsForTarget(targetFieldId) {
|
|
10970
|
+
return clearOptionEffectsForTarget(this.moduleCtx(), targetFieldId);
|
|
10971
|
+
}
|
|
10972
|
+
addOptionEffectOptions(triggerId, targetFieldId, kind, optionIds) {
|
|
10973
|
+
return addOptionEffectOptions(
|
|
10974
|
+
this.moduleCtx(),
|
|
10975
|
+
triggerId,
|
|
10976
|
+
targetFieldId,
|
|
10977
|
+
kind,
|
|
10978
|
+
optionIds
|
|
10979
|
+
);
|
|
10980
|
+
}
|
|
10981
|
+
removeOptionEffectOptions(triggerId, targetFieldId, kind, optionIds) {
|
|
10982
|
+
return removeOptionEffectOptions(
|
|
10983
|
+
this.moduleCtx(),
|
|
10984
|
+
triggerId,
|
|
10985
|
+
targetFieldId,
|
|
10986
|
+
kind,
|
|
10987
|
+
optionIds
|
|
10988
|
+
);
|
|
10989
|
+
}
|
|
10990
|
+
setOptionEffectForceVisible(triggerId, targetFieldId, forceVisible) {
|
|
10991
|
+
return setOptionEffectForceVisible(
|
|
10992
|
+
this.moduleCtx(),
|
|
10993
|
+
triggerId,
|
|
10994
|
+
targetFieldId,
|
|
10995
|
+
forceVisible
|
|
10996
|
+
);
|
|
10997
|
+
}
|
|
10110
10998
|
connect(kind, fromId, toId2) {
|
|
10111
10999
|
return connect(this.moduleCtx(), kind, fromId, toId2);
|
|
10112
11000
|
}
|
|
@@ -10475,11 +11363,10 @@ var Selection = class {
|
|
|
10475
11363
|
* What counts as a "button selection" (trigger key):
|
|
10476
11364
|
* - field key where the field has button === true (e.g. "f:dripfeed")
|
|
10477
11365
|
* - option key (e.g. "o:fast")
|
|
10478
|
-
* - composite key "fieldId::optionId" (e.g. "f:speed::o:fast")
|
|
10479
11366
|
*
|
|
10480
11367
|
* Grouping:
|
|
10481
11368
|
* - button-field trigger groups under its own fieldId
|
|
10482
|
-
* - option
|
|
11369
|
+
* - option trigger groups under the option's owning fieldId (from nodeMap)
|
|
10483
11370
|
*
|
|
10484
11371
|
* Deterministic:
|
|
10485
11372
|
* - preserves selection insertion order
|
|
@@ -10496,15 +11383,6 @@ var Selection = class {
|
|
|
10496
11383
|
};
|
|
10497
11384
|
for (const key of this.set) {
|
|
10498
11385
|
if (!key) continue;
|
|
10499
|
-
const idx = key.indexOf("::");
|
|
10500
|
-
if (idx !== -1) {
|
|
10501
|
-
const optionId = key.slice(idx + 2);
|
|
10502
|
-
const optRef = nodeMap.get(optionId);
|
|
10503
|
-
if ((optRef == null ? void 0 : optRef.kind) === "option" && typeof optRef.fieldId === "string") {
|
|
10504
|
-
push(optRef.fieldId, key);
|
|
10505
|
-
}
|
|
10506
|
-
continue;
|
|
10507
|
-
}
|
|
10508
11386
|
const ref = nodeMap.get(key);
|
|
10509
11387
|
if (!ref) continue;
|
|
10510
11388
|
if (ref.kind === "option" && typeof ref.fieldId === "string") {
|
|
@@ -10525,7 +11403,6 @@ var Selection = class {
|
|
|
10525
11403
|
* Returns only selection keys that are valid "trigger buttons":
|
|
10526
11404
|
* - field keys where field.button === true
|
|
10527
11405
|
* - option keys
|
|
10528
|
-
* - composite keys "fieldId::optionId" (validated by optionId)
|
|
10529
11406
|
* Excludes tags and non-button fields.
|
|
10530
11407
|
*/
|
|
10531
11408
|
selectedButtons() {
|
|
@@ -10541,13 +11418,6 @@ var Selection = class {
|
|
|
10541
11418
|
};
|
|
10542
11419
|
for (const key of this.set) {
|
|
10543
11420
|
if (!key) continue;
|
|
10544
|
-
const idx = key.indexOf("::");
|
|
10545
|
-
if (idx !== -1) {
|
|
10546
|
-
const optionId = key.slice(idx + 2);
|
|
10547
|
-
const optRef = nodeMap.get(optionId);
|
|
10548
|
-
if ((optRef == null ? void 0 : optRef.kind) === "option") push(key);
|
|
10549
|
-
continue;
|
|
10550
|
-
}
|
|
10551
11421
|
const ref = nodeMap.get(key);
|
|
10552
11422
|
if (!ref) continue;
|
|
10553
11423
|
if (ref.kind === "option") {
|
|
@@ -10586,17 +11456,7 @@ var Selection = class {
|
|
|
10586
11456
|
const direct = fields.find((x) => x.id === id);
|
|
10587
11457
|
if (direct) return direct;
|
|
10588
11458
|
if (this.builder.isOptionId(id)) {
|
|
10589
|
-
return fields
|
|
10590
|
-
(x) => {
|
|
10591
|
-
var _a2;
|
|
10592
|
-
return ((_a2 = x.options) != null ? _a2 : []).some((o) => o.id === id);
|
|
10593
|
-
}
|
|
10594
|
-
);
|
|
10595
|
-
}
|
|
10596
|
-
if (id.includes("::")) {
|
|
10597
|
-
const [fieldId] = id.split("::");
|
|
10598
|
-
if (!fieldId) return void 0;
|
|
10599
|
-
return fields.find((x) => x.id === fieldId);
|
|
11459
|
+
return findOptionOwnerField(fields, id);
|
|
10600
11460
|
}
|
|
10601
11461
|
return void 0;
|
|
10602
11462
|
};
|
|
@@ -10627,18 +11487,7 @@ var Selection = class {
|
|
|
10627
11487
|
}
|
|
10628
11488
|
for (const id of this.set) {
|
|
10629
11489
|
if (this.builder.isOptionId(id)) {
|
|
10630
|
-
const host = fields
|
|
10631
|
-
(x) => {
|
|
10632
|
-
var _a2;
|
|
10633
|
-
return ((_a2 = x.options) != null ? _a2 : []).some((o) => o.id === id);
|
|
10634
|
-
}
|
|
10635
|
-
);
|
|
10636
|
-
if (host == null ? void 0 : host.bind_id)
|
|
10637
|
-
return Array.isArray(host.bind_id) ? host.bind_id[0] : host.bind_id;
|
|
10638
|
-
}
|
|
10639
|
-
if (id.includes("::")) {
|
|
10640
|
-
const [fid] = id.split("::");
|
|
10641
|
-
const host = fields.find((x) => x.id === fid);
|
|
11490
|
+
const host = findOptionOwnerField(fields, id);
|
|
10642
11491
|
if (host == null ? void 0 : host.bind_id)
|
|
10643
11492
|
return Array.isArray(host.bind_id) ? host.bind_id[0] : host.bind_id;
|
|
10644
11493
|
}
|
|
@@ -10652,7 +11501,11 @@ var Selection = class {
|
|
|
10652
11501
|
const tagById = new Map(tags.map((t) => [t.id, t]));
|
|
10653
11502
|
const tag = tagById.get(tagId);
|
|
10654
11503
|
const selectedTriggerIds = this.selectedButtons();
|
|
10655
|
-
const
|
|
11504
|
+
const visibility = this.builder.resolveVisibility(
|
|
11505
|
+
tagId,
|
|
11506
|
+
selectedTriggerIds
|
|
11507
|
+
);
|
|
11508
|
+
const fieldIds = visibility.fieldIds;
|
|
10656
11509
|
const fieldById = new Map(fields.map((f) => [f.id, f]));
|
|
10657
11510
|
const visible = fieldIds.map((id) => fieldById.get(id)).filter(Boolean);
|
|
10658
11511
|
const parentTags = [];
|
|
@@ -10678,6 +11531,14 @@ var Selection = class {
|
|
|
10678
11531
|
let baseOverridden = false;
|
|
10679
11532
|
for (const selId of this.set) {
|
|
10680
11533
|
const opt = this.findOptionById(fields, selId);
|
|
11534
|
+
if (opt && !this.isSelectedOptionVisible(
|
|
11535
|
+
fields,
|
|
11536
|
+
selId,
|
|
11537
|
+
fieldIds,
|
|
11538
|
+
visibility.optionsByFieldId
|
|
11539
|
+
)) {
|
|
11540
|
+
continue;
|
|
11541
|
+
}
|
|
10681
11542
|
if ((opt == null ? void 0 : opt.service_id) != null) {
|
|
10682
11543
|
const role = (_d = opt.pricing_role) != null ? _d : "base";
|
|
10683
11544
|
const cap = (_e = resolve == null ? void 0 : resolve(opt.service_id)) != null ? _e : { id: opt.service_id };
|
|
@@ -10708,6 +11569,8 @@ var Selection = class {
|
|
|
10708
11569
|
tag,
|
|
10709
11570
|
fields: visible,
|
|
10710
11571
|
fieldIds,
|
|
11572
|
+
optionsByFieldId: visibility.optionsByFieldId,
|
|
11573
|
+
forcedFieldIds: visibility.forcedFieldIds,
|
|
10711
11574
|
parentTags,
|
|
10712
11575
|
childrenTags,
|
|
10713
11576
|
services
|
|
@@ -10731,21 +11594,19 @@ var Selection = class {
|
|
|
10731
11594
|
return baseOverridden;
|
|
10732
11595
|
}
|
|
10733
11596
|
findOptionById(fields, selId) {
|
|
10734
|
-
var _a, _b;
|
|
10735
11597
|
if (this.builder.isOptionId(selId)) {
|
|
10736
|
-
|
|
10737
|
-
|
|
10738
|
-
if (o) return o;
|
|
10739
|
-
}
|
|
10740
|
-
}
|
|
10741
|
-
if (selId.includes("::")) {
|
|
10742
|
-
const [fid, oid] = selId.split("::");
|
|
10743
|
-
const f = fields.find((x) => x.id === fid);
|
|
10744
|
-
const o = (_b = f == null ? void 0 : f.options) == null ? void 0 : _b.find((x) => x.id === oid || x.id === selId);
|
|
10745
|
-
if (o) return o;
|
|
11598
|
+
const field = findOptionOwnerField(fields, selId);
|
|
11599
|
+
return findFieldOption(field, selId);
|
|
10746
11600
|
}
|
|
10747
11601
|
return void 0;
|
|
10748
11602
|
}
|
|
11603
|
+
isSelectedOptionVisible(fields, selId, visibleFieldIds, optionsByFieldId) {
|
|
11604
|
+
const visibleFields = new Set(visibleFieldIds);
|
|
11605
|
+
const field = findOptionOwnerField(fields, selId);
|
|
11606
|
+
if (!field || !visibleFields.has(field.id)) return false;
|
|
11607
|
+
const allowed = optionsByFieldId[field.id];
|
|
11608
|
+
return !allowed || allowed.includes(selId);
|
|
11609
|
+
}
|
|
10749
11610
|
};
|
|
10750
11611
|
|
|
10751
11612
|
// src/react/canvas/api.ts
|