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