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