@timeax/digital-service-engine 0.0.1 → 0.0.3
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 +1097 -193
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +191 -51
- package/dist/core/index.d.ts +191 -51
- package/dist/core/index.js +1095 -193
- package/dist/core/index.js.map +1 -1
- package/dist/react/index.cjs +8563 -2703
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +424 -141
- package/dist/react/index.d.ts +424 -141
- package/dist/react/index.js +8557 -2706
- package/dist/react/index.js.map +1 -1
- package/dist/schema/index.d.cts +123 -54
- package/dist/schema/index.d.ts +123 -54
- package/dist/workspace/index.cjs +541 -255
- package/dist/workspace/index.cjs.map +1 -1
- package/dist/workspace/index.d.cts +79 -51
- package/dist/workspace/index.d.ts +79 -51
- package/dist/workspace/index.js +541 -255
- package/dist/workspace/index.js.map +1 -1
- package/package.json +106 -97
- package/schema/editor-snapshot.schema.json +121 -209
- package/schema/service-props.schema.json +121 -209
package/dist/workspace/index.cjs
CHANGED
|
@@ -3260,11 +3260,6 @@ function hasAnyServiceOption(f) {
|
|
|
3260
3260
|
var _a;
|
|
3261
3261
|
return ((_a = f.options) != null ? _a : []).some((o) => isFiniteNumber(o.service_id));
|
|
3262
3262
|
}
|
|
3263
|
-
function isBoundTo(f, tagId) {
|
|
3264
|
-
const b = f.bind_id;
|
|
3265
|
-
if (!b) return false;
|
|
3266
|
-
return Array.isArray(b) ? b.includes(tagId) : b === tagId;
|
|
3267
|
-
}
|
|
3268
3263
|
function getByPath(obj, path) {
|
|
3269
3264
|
if (!path) return void 0;
|
|
3270
3265
|
const parts = path.split(".");
|
|
@@ -3350,33 +3345,214 @@ function withAffected(details, ids) {
|
|
|
3350
3345
|
return { ...details != null ? details : {}, affectedIds: ids };
|
|
3351
3346
|
}
|
|
3352
3347
|
|
|
3348
|
+
// src/core/node-map.ts
|
|
3349
|
+
function buildNodeMap(props) {
|
|
3350
|
+
var _a, _b, _c;
|
|
3351
|
+
const map = /* @__PURE__ */ new Map();
|
|
3352
|
+
for (const t of (_a = props.filters) != null ? _a : []) {
|
|
3353
|
+
if (!map.has(t.id)) map.set(t.id, { kind: "tag", id: t.id, node: t });
|
|
3354
|
+
}
|
|
3355
|
+
for (const f of (_b = props.fields) != null ? _b : []) {
|
|
3356
|
+
if (!map.has(f.id)) map.set(f.id, { kind: "field", id: f.id, node: f });
|
|
3357
|
+
for (const o of (_c = f.options) != null ? _c : []) {
|
|
3358
|
+
if (!map.has(o.id))
|
|
3359
|
+
map.set(o.id, {
|
|
3360
|
+
kind: "option",
|
|
3361
|
+
id: o.id,
|
|
3362
|
+
node: o,
|
|
3363
|
+
fieldId: f.id
|
|
3364
|
+
});
|
|
3365
|
+
}
|
|
3366
|
+
}
|
|
3367
|
+
return map;
|
|
3368
|
+
}
|
|
3369
|
+
function resolveTrigger(trigger, nodeMap) {
|
|
3370
|
+
const idx = trigger.indexOf("::");
|
|
3371
|
+
if (idx !== -1) {
|
|
3372
|
+
const fieldId = trigger.slice(0, idx);
|
|
3373
|
+
const optionId = trigger.slice(idx + 2);
|
|
3374
|
+
return { kind: "composite", triggerKey: trigger, fieldId, optionId };
|
|
3375
|
+
}
|
|
3376
|
+
const direct = nodeMap.get(trigger);
|
|
3377
|
+
if (!direct) return void 0;
|
|
3378
|
+
if (direct.kind === "option") {
|
|
3379
|
+
return {
|
|
3380
|
+
kind: "option",
|
|
3381
|
+
triggerKey: trigger,
|
|
3382
|
+
id: direct.id,
|
|
3383
|
+
fieldId: direct.fieldId
|
|
3384
|
+
};
|
|
3385
|
+
}
|
|
3386
|
+
return { kind: direct.kind, triggerKey: trigger, id: direct.id };
|
|
3387
|
+
}
|
|
3388
|
+
|
|
3389
|
+
// src/core/visibility.ts
|
|
3390
|
+
function visibleFieldIdsUnder(props, tagId, opts = {}) {
|
|
3391
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
3392
|
+
const tags = (_a = props.filters) != null ? _a : [];
|
|
3393
|
+
const fields = (_b = props.fields) != null ? _b : [];
|
|
3394
|
+
const tagById = new Map(tags.map((t) => [t.id, t]));
|
|
3395
|
+
const tag = tagById.get(tagId);
|
|
3396
|
+
if (!tag) return [];
|
|
3397
|
+
const nodeMap = buildNodeMap(props);
|
|
3398
|
+
const lineageDepth = /* @__PURE__ */ new Map();
|
|
3399
|
+
{
|
|
3400
|
+
const guard = /* @__PURE__ */ new Set();
|
|
3401
|
+
let cur = tag;
|
|
3402
|
+
let d = 0;
|
|
3403
|
+
while (cur && !guard.has(cur.id)) {
|
|
3404
|
+
lineageDepth.set(cur.id, d++);
|
|
3405
|
+
guard.add(cur.id);
|
|
3406
|
+
const parentId = cur.bind_id;
|
|
3407
|
+
cur = parentId ? tagById.get(parentId) : void 0;
|
|
3408
|
+
}
|
|
3409
|
+
}
|
|
3410
|
+
const isTagInLineage = (id) => lineageDepth.has(id);
|
|
3411
|
+
const fieldById = new Map(fields.map((f) => [f.id, f]));
|
|
3412
|
+
const ownerDepthForField = (f) => {
|
|
3413
|
+
const b = f.bind_id;
|
|
3414
|
+
if (!b) return void 0;
|
|
3415
|
+
if (typeof b === "string") return lineageDepth.get(b);
|
|
3416
|
+
let best = void 0;
|
|
3417
|
+
for (const id of b) {
|
|
3418
|
+
const d = lineageDepth.get(id);
|
|
3419
|
+
if (d == null) continue;
|
|
3420
|
+
if (best == null || d < best) best = d;
|
|
3421
|
+
}
|
|
3422
|
+
return best;
|
|
3423
|
+
};
|
|
3424
|
+
const ownerDepthForTriggerKey = (triggerKey) => {
|
|
3425
|
+
const t = resolveTrigger(triggerKey, nodeMap);
|
|
3426
|
+
if (!t) return void 0;
|
|
3427
|
+
if (t.kind === "composite") {
|
|
3428
|
+
const f = fieldById.get(t.fieldId);
|
|
3429
|
+
if (!f) return void 0;
|
|
3430
|
+
return ownerDepthForField(f);
|
|
3431
|
+
}
|
|
3432
|
+
if (t.kind === "field") {
|
|
3433
|
+
const f = fieldById.get(t.id);
|
|
3434
|
+
if (!f || f.button !== true) return void 0;
|
|
3435
|
+
return ownerDepthForField(f);
|
|
3436
|
+
}
|
|
3437
|
+
if (t.kind === "option") {
|
|
3438
|
+
const f = t.fieldId ? fieldById.get(t.fieldId) : void 0;
|
|
3439
|
+
if (!f) return void 0;
|
|
3440
|
+
return ownerDepthForField(f);
|
|
3441
|
+
}
|
|
3442
|
+
return void 0;
|
|
3443
|
+
};
|
|
3444
|
+
const tagInclude = new Set((_c = tag.includes) != null ? _c : []);
|
|
3445
|
+
const tagExclude = new Set((_d = tag.excludes) != null ? _d : []);
|
|
3446
|
+
const selected = (_e = opts.selectedKeys) != null ? _e : /* @__PURE__ */ new Set();
|
|
3447
|
+
const incMap = (_f = props.includes_for_buttons) != null ? _f : {};
|
|
3448
|
+
const excMap = (_g = props.excludes_for_buttons) != null ? _g : {};
|
|
3449
|
+
const relevantTriggersInOrder = [];
|
|
3450
|
+
for (const key of selected) {
|
|
3451
|
+
const d = ownerDepthForTriggerKey(key);
|
|
3452
|
+
if (d == null) continue;
|
|
3453
|
+
relevantTriggersInOrder.push(key);
|
|
3454
|
+
}
|
|
3455
|
+
const visible = /* @__PURE__ */ new Set();
|
|
3456
|
+
const isBoundToLineage = (f) => {
|
|
3457
|
+
const b = f.bind_id;
|
|
3458
|
+
if (!b) return false;
|
|
3459
|
+
if (typeof b === "string") return isTagInLineage(b);
|
|
3460
|
+
for (const id of b) if (isTagInLineage(id)) return true;
|
|
3461
|
+
return false;
|
|
3462
|
+
};
|
|
3463
|
+
for (const f of fields) {
|
|
3464
|
+
if (isBoundToLineage(f)) visible.add(f.id);
|
|
3465
|
+
if (tagInclude.has(f.id)) visible.add(f.id);
|
|
3466
|
+
}
|
|
3467
|
+
for (const id of tagExclude) visible.delete(id);
|
|
3468
|
+
const decide = /* @__PURE__ */ new Map();
|
|
3469
|
+
const applyDecision = (fieldId, next) => {
|
|
3470
|
+
const prev = decide.get(fieldId);
|
|
3471
|
+
if (!prev) return void decide.set(fieldId, next);
|
|
3472
|
+
if (next.depth < prev.depth) return void decide.set(fieldId, next);
|
|
3473
|
+
if (next.depth > prev.depth) return;
|
|
3474
|
+
if (prev.kind === "include" && next.kind === "exclude") {
|
|
3475
|
+
decide.set(fieldId, next);
|
|
3476
|
+
}
|
|
3477
|
+
};
|
|
3478
|
+
const revealedOrder = [];
|
|
3479
|
+
const revealedSeen = /* @__PURE__ */ new Set();
|
|
3480
|
+
for (const triggerKey of relevantTriggersInOrder) {
|
|
3481
|
+
const depth = ownerDepthForTriggerKey(triggerKey);
|
|
3482
|
+
if (depth == null) continue;
|
|
3483
|
+
for (const id of (_h = incMap[triggerKey]) != null ? _h : []) {
|
|
3484
|
+
applyDecision(id, { depth, kind: "include" });
|
|
3485
|
+
if (!revealedSeen.has(id)) {
|
|
3486
|
+
revealedSeen.add(id);
|
|
3487
|
+
revealedOrder.push(id);
|
|
3488
|
+
}
|
|
3489
|
+
}
|
|
3490
|
+
for (const id of (_i = excMap[triggerKey]) != null ? _i : []) {
|
|
3491
|
+
applyDecision(id, { depth, kind: "exclude" });
|
|
3492
|
+
}
|
|
3493
|
+
}
|
|
3494
|
+
for (const [fid, d] of decide) {
|
|
3495
|
+
if (d.kind === "include") visible.add(fid);
|
|
3496
|
+
else visible.delete(fid);
|
|
3497
|
+
}
|
|
3498
|
+
const base = fields.filter((f) => visible.has(f.id)).map((f) => f.id);
|
|
3499
|
+
const order = (_j = props.order_for_tags) == null ? void 0 : _j[tagId];
|
|
3500
|
+
if (order && order.length) {
|
|
3501
|
+
const ordered = order.filter((fid) => visible.has(fid));
|
|
3502
|
+
const orderedSet = new Set(ordered);
|
|
3503
|
+
const rest = base.filter((fid) => !orderedSet.has(fid));
|
|
3504
|
+
return [...ordered, ...rest];
|
|
3505
|
+
}
|
|
3506
|
+
return base;
|
|
3507
|
+
}
|
|
3508
|
+
function visibleFieldsUnder(props, tagId, opts = {}) {
|
|
3509
|
+
var _a;
|
|
3510
|
+
const ids = visibleFieldIdsUnder(props, tagId, opts);
|
|
3511
|
+
const fieldById = new Map(((_a = props.fields) != null ? _a : []).map((f) => [f.id, f]));
|
|
3512
|
+
return ids.map((id) => fieldById.get(id)).filter(Boolean);
|
|
3513
|
+
}
|
|
3514
|
+
|
|
3353
3515
|
// src/core/validate/steps/visibility.ts
|
|
3354
3516
|
function createFieldsVisibleUnder(v) {
|
|
3355
3517
|
return (tagId) => {
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
|
|
3359
|
-
const excludesTag = new Set((_b = tag == null ? void 0 : tag.excludes) != null ? _b : []);
|
|
3360
|
-
const incForOpt = (_c = v.props.includes_for_buttons) != null ? _c : {};
|
|
3361
|
-
const excForOpt = (_d = v.props.excludes_for_buttons) != null ? _d : {};
|
|
3362
|
-
const includesOpt = /* @__PURE__ */ new Set();
|
|
3363
|
-
const excludesOpt = /* @__PURE__ */ new Set();
|
|
3364
|
-
for (const key of v.selectedKeys) {
|
|
3365
|
-
for (const id of (_e = incForOpt[key]) != null ? _e : []) includesOpt.add(id);
|
|
3366
|
-
for (const id of (_f = excForOpt[key]) != null ? _f : []) excludesOpt.add(id);
|
|
3367
|
-
}
|
|
3368
|
-
const merged = /* @__PURE__ */ new Map();
|
|
3369
|
-
for (const f of v.fields) {
|
|
3370
|
-
if (isBoundTo(f, tagId)) merged.set(f.id, f);
|
|
3371
|
-
if (includesTag.has(f.id)) merged.set(f.id, f);
|
|
3372
|
-
if (includesOpt.has(f.id)) merged.set(f.id, f);
|
|
3373
|
-
}
|
|
3374
|
-
for (const id of excludesTag) merged.delete(id);
|
|
3375
|
-
for (const id of excludesOpt) merged.delete(id);
|
|
3376
|
-
return Array.from(merged.values());
|
|
3518
|
+
return visibleFieldsUnder(v.props, tagId, {
|
|
3519
|
+
selectedKeys: v.selectedKeys
|
|
3520
|
+
});
|
|
3377
3521
|
};
|
|
3378
3522
|
}
|
|
3379
|
-
function
|
|
3523
|
+
function stableKeyOfSelection(keys) {
|
|
3524
|
+
return Array.from(keys).sort().join("|");
|
|
3525
|
+
}
|
|
3526
|
+
function resolveRootTags(tags) {
|
|
3527
|
+
const roots = tags.filter((t) => !t.bind_id);
|
|
3528
|
+
return roots.length ? roots : tags.slice(0, 1);
|
|
3529
|
+
}
|
|
3530
|
+
function isEffectfulTrigger(v, trigger) {
|
|
3531
|
+
var _a, _b, _c, _d, _e, _f;
|
|
3532
|
+
const inc = (_a = v.props.includes_for_buttons) != null ? _a : {};
|
|
3533
|
+
const exc = (_b = v.props.excludes_for_buttons) != null ? _b : {};
|
|
3534
|
+
return ((_d = (_c = inc[trigger]) == null ? void 0 : _c.length) != null ? _d : 0) > 0 || ((_f = (_e = exc[trigger]) == null ? void 0 : _e.length) != null ? _f : 0) > 0;
|
|
3535
|
+
}
|
|
3536
|
+
function collectSelectableTriggersInContext(v, tagId, selectedKeys, onlyEffectful) {
|
|
3537
|
+
var _a;
|
|
3538
|
+
const visible = visibleFieldsUnder(v.props, tagId, {
|
|
3539
|
+
selectedKeys
|
|
3540
|
+
});
|
|
3541
|
+
const triggers = [];
|
|
3542
|
+
for (const f of visible) {
|
|
3543
|
+
if (f.button === true) {
|
|
3544
|
+
const t = f.id;
|
|
3545
|
+
if (!onlyEffectful || isEffectfulTrigger(v, t)) triggers.push(t);
|
|
3546
|
+
}
|
|
3547
|
+
for (const o of (_a = f.options) != null ? _a : []) {
|
|
3548
|
+
const t = `${f.id}::${o.id}`;
|
|
3549
|
+
if (!onlyEffectful || isEffectfulTrigger(v, t)) triggers.push(t);
|
|
3550
|
+
}
|
|
3551
|
+
}
|
|
3552
|
+
triggers.sort();
|
|
3553
|
+
return triggers;
|
|
3554
|
+
}
|
|
3555
|
+
function runVisibilityRulesOnce(v) {
|
|
3380
3556
|
var _a, _b, _c, _d, _e;
|
|
3381
3557
|
for (const t of v.tags) {
|
|
3382
3558
|
const visible = v.fieldsVisibleUnder(t.id);
|
|
@@ -3451,12 +3627,85 @@ function validateVisibility(v) {
|
|
|
3451
3627
|
}
|
|
3452
3628
|
}
|
|
3453
3629
|
}
|
|
3630
|
+
function dedupeErrorsInPlace(v, startIndex) {
|
|
3631
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3632
|
+
const keyOfErr = (e) => {
|
|
3633
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
3634
|
+
const tagId = (_e = (_d = (_a = e == null ? void 0 : e.details) == null ? void 0 : _a.tagId) != null ? _d : (_c = (_b = e == null ? void 0 : e.details) == null ? void 0 : _b.affected) == null ? void 0 : _c.tagId) != null ? _e : "";
|
|
3635
|
+
const other = (_g = (_f = e == null ? void 0 : e.details) == null ? void 0 : _f.other) != null ? _g : "";
|
|
3636
|
+
return `${(_h = e == null ? void 0 : e.code) != null ? _h : ""}::${(_i = e == null ? void 0 : e.nodeId) != null ? _i : ""}::${tagId}::${other}::${(_j = e == null ? void 0 : e.message) != null ? _j : ""}`;
|
|
3637
|
+
};
|
|
3638
|
+
const kept = [];
|
|
3639
|
+
for (let i = startIndex; i < v.errors.length; i++) {
|
|
3640
|
+
const e = v.errors[i];
|
|
3641
|
+
const k = keyOfErr(e);
|
|
3642
|
+
if (seen.has(k)) continue;
|
|
3643
|
+
seen.add(k);
|
|
3644
|
+
kept.push(e);
|
|
3645
|
+
}
|
|
3646
|
+
v.errors.splice(startIndex, v.errors.length - startIndex, ...kept);
|
|
3647
|
+
}
|
|
3648
|
+
function validateVisibility(v, options = {}) {
|
|
3649
|
+
var _a, _b, _c;
|
|
3650
|
+
const simulate = options.simulate === true;
|
|
3651
|
+
if (!simulate) {
|
|
3652
|
+
runVisibilityRulesOnce(v);
|
|
3653
|
+
return;
|
|
3654
|
+
}
|
|
3655
|
+
const maxStates = Math.max(1, (_a = options.maxStates) != null ? _a : 500);
|
|
3656
|
+
const maxDepth = Math.max(0, (_b = options.maxDepth) != null ? _b : 6);
|
|
3657
|
+
const onlyEffectful = options.onlyEffectfulTriggers !== false;
|
|
3658
|
+
const roots = resolveRootTags(v.tags);
|
|
3659
|
+
const rootTags = options.simulateAllRoots ? roots : roots.slice(0, 1);
|
|
3660
|
+
const originalSelected = new Set((_c = v.selectedKeys) != null ? _c : []);
|
|
3661
|
+
const errorsStart = v.errors.length;
|
|
3662
|
+
const visited = /* @__PURE__ */ new Set();
|
|
3663
|
+
const stack = [];
|
|
3664
|
+
for (const rt of rootTags) {
|
|
3665
|
+
stack.push({
|
|
3666
|
+
rootTagId: rt.id,
|
|
3667
|
+
selected: new Set(originalSelected),
|
|
3668
|
+
depth: 0
|
|
3669
|
+
});
|
|
3670
|
+
}
|
|
3671
|
+
let validatedStates = 0;
|
|
3672
|
+
while (stack.length) {
|
|
3673
|
+
if (validatedStates >= maxStates) break;
|
|
3674
|
+
const state = stack.pop();
|
|
3675
|
+
const sig = stableKeyOfSelection(state.selected);
|
|
3676
|
+
if (visited.has(sig)) continue;
|
|
3677
|
+
visited.add(sig);
|
|
3678
|
+
v.selectedKeys = state.selected;
|
|
3679
|
+
validatedStates++;
|
|
3680
|
+
runVisibilityRulesOnce(v);
|
|
3681
|
+
if (state.depth >= maxDepth) continue;
|
|
3682
|
+
const triggers = collectSelectableTriggersInContext(
|
|
3683
|
+
v,
|
|
3684
|
+
state.rootTagId,
|
|
3685
|
+
state.selected,
|
|
3686
|
+
onlyEffectful
|
|
3687
|
+
);
|
|
3688
|
+
for (let i = triggers.length - 1; i >= 0; i--) {
|
|
3689
|
+
const trig = triggers[i];
|
|
3690
|
+
if (state.selected.has(trig)) continue;
|
|
3691
|
+
const next = new Set(state.selected);
|
|
3692
|
+
next.add(trig);
|
|
3693
|
+
stack.push({
|
|
3694
|
+
rootTagId: state.rootTagId,
|
|
3695
|
+
selected: next,
|
|
3696
|
+
depth: state.depth + 1
|
|
3697
|
+
});
|
|
3698
|
+
}
|
|
3699
|
+
}
|
|
3700
|
+
v.selectedKeys = originalSelected;
|
|
3701
|
+
dedupeErrorsInPlace(v, errorsStart);
|
|
3702
|
+
}
|
|
3454
3703
|
|
|
3455
3704
|
// src/core/validate/steps/structure.ts
|
|
3456
3705
|
function validateStructure(v) {
|
|
3457
3706
|
const tags = v.tags;
|
|
3458
3707
|
const fields = v.fields;
|
|
3459
|
-
if (!tags.some((t) => t.id === "root")) {
|
|
3708
|
+
if (!tags.some((t) => t.id === "t:root")) {
|
|
3460
3709
|
v.errors.push({
|
|
3461
3710
|
code: "root_missing",
|
|
3462
3711
|
severity: "error",
|
|
@@ -3646,58 +3895,91 @@ function validateIdentity(v) {
|
|
|
3646
3895
|
}
|
|
3647
3896
|
|
|
3648
3897
|
// src/core/validate/steps/option-maps.ts
|
|
3898
|
+
function parseFieldOptionKey(key) {
|
|
3899
|
+
const idx = key.indexOf("::");
|
|
3900
|
+
if (idx === -1) return null;
|
|
3901
|
+
const fieldId = key.slice(0, idx).trim();
|
|
3902
|
+
const optionId = key.slice(idx + 2).trim();
|
|
3903
|
+
if (!fieldId || !optionId) return null;
|
|
3904
|
+
return { fieldId, optionId };
|
|
3905
|
+
}
|
|
3906
|
+
function hasOption(v, fid, oid) {
|
|
3907
|
+
var _a;
|
|
3908
|
+
const f = v.fieldById.get(fid);
|
|
3909
|
+
if (!f) return false;
|
|
3910
|
+
return !!((_a = f.options) != null ? _a : []).find((o) => o.id === oid);
|
|
3911
|
+
}
|
|
3649
3912
|
function validateOptionMaps(v) {
|
|
3650
3913
|
var _a, _b;
|
|
3651
3914
|
const incMap = (_a = v.props.includes_for_buttons) != null ? _a : {};
|
|
3652
3915
|
const excMap = (_b = v.props.excludes_for_buttons) != null ? _b : {};
|
|
3653
|
-
const
|
|
3654
|
-
|
|
3655
|
-
const
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
3659
|
-
|
|
3660
|
-
|
|
3661
|
-
|
|
3662
|
-
|
|
3663
|
-
|
|
3664
|
-
|
|
3916
|
+
const badKeyMessage = (key) => `Invalid trigger-map key "${key}". Expected a known node id (option or button-field), or "fieldId::optionId" pointing to an existing option.`;
|
|
3917
|
+
const validateTriggerKey = (key) => {
|
|
3918
|
+
const ref = v.nodeMap.get(key);
|
|
3919
|
+
if (ref) {
|
|
3920
|
+
if (ref.kind === "option") {
|
|
3921
|
+
return {
|
|
3922
|
+
ok: true,
|
|
3923
|
+
nodeId: ref.fieldId,
|
|
3924
|
+
affected: [ref.fieldId, ref.id]
|
|
3925
|
+
};
|
|
3926
|
+
}
|
|
3927
|
+
if (ref.kind === "field") {
|
|
3928
|
+
const isButton = ref.node.button === true;
|
|
3929
|
+
if (!isButton)
|
|
3930
|
+
return { ok: false, nodeId: ref.id, affected: [ref.id] };
|
|
3931
|
+
return { ok: true, nodeId: ref.id, affected: [ref.id] };
|
|
3932
|
+
}
|
|
3933
|
+
return { ok: false, nodeId: ref.id, affected: [ref.id] };
|
|
3934
|
+
}
|
|
3935
|
+
const p = parseFieldOptionKey(key);
|
|
3936
|
+
if (!p) return { ok: false };
|
|
3937
|
+
if (!hasOption(v, p.fieldId, p.optionId))
|
|
3938
|
+
return {
|
|
3939
|
+
ok: false,
|
|
3940
|
+
nodeId: p.fieldId,
|
|
3941
|
+
affected: [p.fieldId, p.optionId]
|
|
3942
|
+
};
|
|
3943
|
+
return {
|
|
3944
|
+
ok: true,
|
|
3945
|
+
nodeId: p.fieldId,
|
|
3946
|
+
affected: [p.fieldId, p.optionId]
|
|
3947
|
+
};
|
|
3665
3948
|
};
|
|
3666
|
-
const badKeyMessage = (key) => `Invalid option-map key "${key}". Expected "fieldId::optionId" pointing to an existing option.`;
|
|
3667
3949
|
for (const k of Object.keys(incMap)) {
|
|
3668
|
-
const
|
|
3669
|
-
if (!
|
|
3950
|
+
const r = validateTriggerKey(k);
|
|
3951
|
+
if (!r.ok) {
|
|
3670
3952
|
v.errors.push({
|
|
3671
3953
|
code: "bad_option_key",
|
|
3672
3954
|
severity: "error",
|
|
3673
3955
|
message: badKeyMessage(k),
|
|
3674
|
-
|
|
3956
|
+
nodeId: r.nodeId,
|
|
3957
|
+
details: withAffected({ key: k }, r.affected)
|
|
3675
3958
|
});
|
|
3676
3959
|
}
|
|
3677
3960
|
}
|
|
3678
3961
|
for (const k of Object.keys(excMap)) {
|
|
3679
|
-
const
|
|
3680
|
-
if (!
|
|
3962
|
+
const r = validateTriggerKey(k);
|
|
3963
|
+
if (!r.ok) {
|
|
3681
3964
|
v.errors.push({
|
|
3682
3965
|
code: "bad_option_key",
|
|
3683
3966
|
severity: "error",
|
|
3684
3967
|
message: badKeyMessage(k),
|
|
3685
|
-
|
|
3968
|
+
nodeId: r.nodeId,
|
|
3969
|
+
details: withAffected({ key: k }, r.affected)
|
|
3686
3970
|
});
|
|
3687
3971
|
}
|
|
3688
3972
|
}
|
|
3689
3973
|
for (const k of Object.keys(incMap)) {
|
|
3690
|
-
if (k in excMap)
|
|
3691
|
-
|
|
3692
|
-
|
|
3693
|
-
|
|
3694
|
-
|
|
3695
|
-
|
|
3696
|
-
|
|
3697
|
-
|
|
3698
|
-
|
|
3699
|
-
});
|
|
3700
|
-
}
|
|
3974
|
+
if (!(k in excMap)) continue;
|
|
3975
|
+
const r = validateTriggerKey(k);
|
|
3976
|
+
v.errors.push({
|
|
3977
|
+
code: "option_include_exclude_conflict",
|
|
3978
|
+
severity: "error",
|
|
3979
|
+
message: `Trigger-map key "${k}" appears in both includes_for_buttons and excludes_for_buttons.`,
|
|
3980
|
+
nodeId: r.nodeId,
|
|
3981
|
+
details: withAffected({ key: k }, r.affected)
|
|
3982
|
+
});
|
|
3701
3983
|
}
|
|
3702
3984
|
}
|
|
3703
3985
|
|
|
@@ -4602,8 +4884,23 @@ function applyPolicies(errors, props, serviceMap, policies, fieldsVisibleUnder,
|
|
|
4602
4884
|
}
|
|
4603
4885
|
|
|
4604
4886
|
// src/core/validate/index.ts
|
|
4887
|
+
function readVisibilitySimOpts(ctx) {
|
|
4888
|
+
const c = ctx;
|
|
4889
|
+
const simulate = c.simulateVisibility === true || c.visibilitySimulate === true || c.simulate === true;
|
|
4890
|
+
const maxStates = typeof c.maxVisibilityStates === "number" ? c.maxVisibilityStates : typeof c.visibilityMaxStates === "number" ? c.visibilityMaxStates : typeof c.maxStates === "number" ? c.maxStates : void 0;
|
|
4891
|
+
const maxDepth = typeof c.maxVisibilityDepth === "number" ? c.maxVisibilityDepth : typeof c.visibilityMaxDepth === "number" ? c.visibilityMaxDepth : typeof c.maxDepth === "number" ? c.maxDepth : void 0;
|
|
4892
|
+
const simulateAllRoots = c.simulateAllRoots === true || c.visibilitySimulateAllRoots === true;
|
|
4893
|
+
const onlyEffectfulTriggers = c.onlyEffectfulTriggers === false ? false : c.visibilityOnlyEffectfulTriggers !== false;
|
|
4894
|
+
return {
|
|
4895
|
+
simulate,
|
|
4896
|
+
maxStates,
|
|
4897
|
+
maxDepth,
|
|
4898
|
+
simulateAllRoots,
|
|
4899
|
+
onlyEffectfulTriggers
|
|
4900
|
+
};
|
|
4901
|
+
}
|
|
4605
4902
|
function validate(props, ctx = {}) {
|
|
4606
|
-
var _a, _b;
|
|
4903
|
+
var _a, _b, _c;
|
|
4607
4904
|
const errors = [];
|
|
4608
4905
|
const serviceMap = (_a = ctx.serviceMap) != null ? _a : {};
|
|
4609
4906
|
const selectedKeys = new Set(
|
|
@@ -4617,6 +4914,7 @@ function validate(props, ctx = {}) {
|
|
|
4617
4914
|
for (const f of fields) fieldById.set(f.id, f);
|
|
4618
4915
|
const v = {
|
|
4619
4916
|
props,
|
|
4917
|
+
nodeMap: (_c = ctx.nodeMap) != null ? _c : buildNodeMap(props),
|
|
4620
4918
|
options: ctx,
|
|
4621
4919
|
errors,
|
|
4622
4920
|
serviceMap,
|
|
@@ -4631,7 +4929,8 @@ function validate(props, ctx = {}) {
|
|
|
4631
4929
|
validateIdentity(v);
|
|
4632
4930
|
validateOptionMaps(v);
|
|
4633
4931
|
v.fieldsVisibleUnder = createFieldsVisibleUnder(v);
|
|
4634
|
-
|
|
4932
|
+
const visSim = readVisibilitySimOpts(ctx);
|
|
4933
|
+
validateVisibility(v, visSim);
|
|
4635
4934
|
applyPolicies(
|
|
4636
4935
|
v.errors,
|
|
4637
4936
|
v.props,
|
|
@@ -4667,11 +4966,21 @@ var BuilderImpl = class {
|
|
|
4667
4966
|
this.optionOwnerById = /* @__PURE__ */ new Map();
|
|
4668
4967
|
this.history = [];
|
|
4669
4968
|
this.future = [];
|
|
4969
|
+
this._nodemap = null;
|
|
4670
4970
|
var _a;
|
|
4671
4971
|
this.options = { ...opts };
|
|
4672
4972
|
this.historyLimit = (_a = opts.historyLimit) != null ? _a : 50;
|
|
4673
4973
|
}
|
|
4674
4974
|
/* ───── lifecycle ─────────────────────────────────────────────────────── */
|
|
4975
|
+
isTagId(id) {
|
|
4976
|
+
return this.tagById.has(id);
|
|
4977
|
+
}
|
|
4978
|
+
isFieldId(id) {
|
|
4979
|
+
return this.fieldById.has(id);
|
|
4980
|
+
}
|
|
4981
|
+
isOptionId(id) {
|
|
4982
|
+
return this.optionOwnerById.has(id);
|
|
4983
|
+
}
|
|
4675
4984
|
load(raw) {
|
|
4676
4985
|
const next = normalise(raw, {
|
|
4677
4986
|
defaultPricingRole: "base",
|
|
@@ -4891,129 +5200,16 @@ var BuilderImpl = class {
|
|
|
4891
5200
|
return validate(this.props, this.options);
|
|
4892
5201
|
}
|
|
4893
5202
|
visibleFields(tagId, selectedKeys) {
|
|
4894
|
-
var _a
|
|
4895
|
-
|
|
4896
|
-
|
|
4897
|
-
|
|
4898
|
-
|
|
4899
|
-
|
|
4900
|
-
|
|
4901
|
-
|
|
4902
|
-
|
|
4903
|
-
|
|
4904
|
-
let cur = tag;
|
|
4905
|
-
let d = 0;
|
|
4906
|
-
while (cur && !guard.has(cur.id)) {
|
|
4907
|
-
lineageDepth.set(cur.id, d++);
|
|
4908
|
-
guard.add(cur.id);
|
|
4909
|
-
const parentId = cur.bind_id;
|
|
4910
|
-
cur = parentId ? tagById.get(parentId) : void 0;
|
|
4911
|
-
}
|
|
4912
|
-
}
|
|
4913
|
-
const isTagInLineage = (id) => lineageDepth.has(id);
|
|
4914
|
-
const fieldById = new Map(fields.map((f) => [f.id, f]));
|
|
4915
|
-
const optionOwnerFieldId = /* @__PURE__ */ new Map();
|
|
4916
|
-
for (const f of fields) {
|
|
4917
|
-
for (const o of (_c = f.options) != null ? _c : []) optionOwnerFieldId.set(o.id, f.id);
|
|
4918
|
-
}
|
|
4919
|
-
const ownerDepthForField = (f) => {
|
|
4920
|
-
const b = f.bind_id;
|
|
4921
|
-
if (!b) return void 0;
|
|
4922
|
-
if (typeof b === "string") return lineageDepth.get(b);
|
|
4923
|
-
let best = void 0;
|
|
4924
|
-
for (const id of b) {
|
|
4925
|
-
const d = lineageDepth.get(id);
|
|
4926
|
-
if (d == null) continue;
|
|
4927
|
-
if (best == null || d < best) best = d;
|
|
4928
|
-
}
|
|
4929
|
-
return best;
|
|
4930
|
-
};
|
|
4931
|
-
const ownerDepthForTrigger = (triggerId) => {
|
|
4932
|
-
if (triggerId.startsWith("o:")) {
|
|
4933
|
-
const fid = optionOwnerFieldId.get(triggerId);
|
|
4934
|
-
if (!fid) return void 0;
|
|
4935
|
-
const f2 = fieldById.get(fid);
|
|
4936
|
-
if (!f2) return void 0;
|
|
4937
|
-
return ownerDepthForField(f2);
|
|
4938
|
-
}
|
|
4939
|
-
const f = fieldById.get(triggerId);
|
|
4940
|
-
if (!f || f.button !== true) return void 0;
|
|
4941
|
-
return ownerDepthForField(f);
|
|
4942
|
-
};
|
|
4943
|
-
const tagInclude = new Set((_d = tag.includes) != null ? _d : []);
|
|
4944
|
-
const tagExclude = new Set((_e = tag.excludes) != null ? _e : []);
|
|
4945
|
-
const selected = new Set(
|
|
4946
|
-
(_f = selectedKeys != null ? selectedKeys : this.options.selectedOptionKeys) != null ? _f : []
|
|
4947
|
-
);
|
|
4948
|
-
const incMap = (_g = props.includes_for_buttons) != null ? _g : {};
|
|
4949
|
-
const excMap = (_h = props.excludes_for_buttons) != null ? _h : {};
|
|
4950
|
-
const relevantTriggersInOrder = [];
|
|
4951
|
-
for (const key of selected) {
|
|
4952
|
-
const d = ownerDepthForTrigger(key);
|
|
4953
|
-
if (d == null) continue;
|
|
4954
|
-
relevantTriggersInOrder.push(key);
|
|
4955
|
-
}
|
|
4956
|
-
const visible = /* @__PURE__ */ new Set();
|
|
4957
|
-
const isBoundToLineage = (f) => {
|
|
4958
|
-
const b = f.bind_id;
|
|
4959
|
-
if (!b) return false;
|
|
4960
|
-
if (typeof b === "string") return isTagInLineage(b);
|
|
4961
|
-
for (const id of b) if (isTagInLineage(id)) return true;
|
|
4962
|
-
return false;
|
|
4963
|
-
};
|
|
4964
|
-
for (const f of fields) {
|
|
4965
|
-
if (isBoundToLineage(f)) visible.add(f.id);
|
|
4966
|
-
if (tagInclude.has(f.id)) visible.add(f.id);
|
|
4967
|
-
}
|
|
4968
|
-
for (const id of tagExclude) visible.delete(id);
|
|
4969
|
-
const decide = /* @__PURE__ */ new Map();
|
|
4970
|
-
const applyDecision = (fieldId, next) => {
|
|
4971
|
-
const prev = decide.get(fieldId);
|
|
4972
|
-
if (!prev) {
|
|
4973
|
-
decide.set(fieldId, next);
|
|
4974
|
-
return;
|
|
4975
|
-
}
|
|
4976
|
-
if (next.depth < prev.depth) {
|
|
4977
|
-
decide.set(fieldId, next);
|
|
4978
|
-
return;
|
|
4979
|
-
}
|
|
4980
|
-
if (next.depth > prev.depth) return;
|
|
4981
|
-
if (prev.kind === "include" && next.kind === "exclude") {
|
|
4982
|
-
decide.set(fieldId, next);
|
|
4983
|
-
}
|
|
4984
|
-
};
|
|
4985
|
-
const revealedOrder = [];
|
|
4986
|
-
const revealedSeen = /* @__PURE__ */ new Set();
|
|
4987
|
-
for (const triggerId of relevantTriggersInOrder) {
|
|
4988
|
-
const depth = ownerDepthForTrigger(triggerId);
|
|
4989
|
-
if (depth == null) continue;
|
|
4990
|
-
for (const id of (_i = incMap[triggerId]) != null ? _i : []) {
|
|
4991
|
-
applyDecision(id, { depth, kind: "include" });
|
|
4992
|
-
if (!revealedSeen.has(id)) {
|
|
4993
|
-
revealedSeen.add(id);
|
|
4994
|
-
revealedOrder.push(id);
|
|
4995
|
-
}
|
|
4996
|
-
}
|
|
4997
|
-
for (const id of (_j = excMap[triggerId]) != null ? _j : []) {
|
|
4998
|
-
applyDecision(id, { depth, kind: "exclude" });
|
|
4999
|
-
}
|
|
5000
|
-
}
|
|
5001
|
-
for (const [fid, d] of decide) {
|
|
5002
|
-
if (d.kind === "include") visible.add(fid);
|
|
5003
|
-
else visible.delete(fid);
|
|
5004
|
-
}
|
|
5005
|
-
const base = fields.filter((f) => visible.has(f.id)).map((f) => f.id);
|
|
5006
|
-
const order = (_k = props.order_for_tags) == null ? void 0 : _k[tagId];
|
|
5007
|
-
if (order && order.length) {
|
|
5008
|
-
const ordered = order.filter((fid) => visible.has(fid));
|
|
5009
|
-
const orderedSet = new Set(ordered);
|
|
5010
|
-
const rest2 = base.filter((fid) => !orderedSet.has(fid));
|
|
5011
|
-
return [...ordered, ...rest2];
|
|
5012
|
-
}
|
|
5013
|
-
const promoted = revealedOrder.filter((fid) => visible.has(fid));
|
|
5014
|
-
const promotedSet = new Set(promoted);
|
|
5015
|
-
const rest = base.filter((fid) => !promotedSet.has(fid));
|
|
5016
|
-
return [...promoted, ...rest];
|
|
5203
|
+
var _a;
|
|
5204
|
+
return visibleFieldIdsUnder(this.props, tagId, {
|
|
5205
|
+
selectedKeys: new Set(
|
|
5206
|
+
(_a = selectedKeys != null ? selectedKeys : this.options.selectedOptionKeys) != null ? _a : []
|
|
5207
|
+
)
|
|
5208
|
+
});
|
|
5209
|
+
}
|
|
5210
|
+
getNodeMap() {
|
|
5211
|
+
if (!this._nodemap) this._nodemap = buildNodeMap(this.getProps());
|
|
5212
|
+
return this._nodemap;
|
|
5017
5213
|
}
|
|
5018
5214
|
/* ───── history ─────────────────────────────────────────────────────── */
|
|
5019
5215
|
undo() {
|
|
@@ -5037,6 +5233,7 @@ var BuilderImpl = class {
|
|
|
5037
5233
|
this.tagById.clear();
|
|
5038
5234
|
this.fieldById.clear();
|
|
5039
5235
|
this.optionOwnerById.clear();
|
|
5236
|
+
this._nodemap = null;
|
|
5040
5237
|
for (const t of this.props.filters) this.tagById.set(t.id, t);
|
|
5041
5238
|
for (const f of this.props.fields) {
|
|
5042
5239
|
this.fieldById.set(f.id, f);
|
|
@@ -5264,6 +5461,7 @@ var toBindList = (b) => {
|
|
|
5264
5461
|
function createNodeIndex(builder) {
|
|
5265
5462
|
var _a, _b, _c, _d;
|
|
5266
5463
|
const props = builder.getProps();
|
|
5464
|
+
const nodeMap = builder.getNodeMap();
|
|
5267
5465
|
const tags = (_a = props.filters) != null ? _a : [];
|
|
5268
5466
|
const fields = (_b = props.fields) != null ? _b : [];
|
|
5269
5467
|
const tagById = new Map(tags.map((t) => [t.id, t]));
|
|
@@ -5467,7 +5665,9 @@ function createNodeIndex(builder) {
|
|
|
5467
5665
|
return parentById.get(id) === tid;
|
|
5468
5666
|
},
|
|
5469
5667
|
getDescendant(descendantId) {
|
|
5470
|
-
return this.getDescendants().find(
|
|
5668
|
+
return this.getDescendants().find(
|
|
5669
|
+
(item) => item.id == descendantId
|
|
5670
|
+
);
|
|
5471
5671
|
},
|
|
5472
5672
|
getDescendants() {
|
|
5473
5673
|
const results = [];
|
|
@@ -5476,7 +5676,9 @@ function createNodeIndex(builder) {
|
|
|
5476
5676
|
const node2 = getField(fieldId);
|
|
5477
5677
|
if (!node2) continue;
|
|
5478
5678
|
const explicit = includes.has(fieldId) || isFieldBoundDirectToTag(fieldId, id);
|
|
5479
|
-
results.push(
|
|
5679
|
+
results.push(
|
|
5680
|
+
explicit ? node2 : { ...node2, isInherited: true }
|
|
5681
|
+
);
|
|
5480
5682
|
}
|
|
5481
5683
|
return Object.freeze(results);
|
|
5482
5684
|
}
|
|
@@ -5525,7 +5727,9 @@ function createNodeIndex(builder) {
|
|
|
5525
5727
|
return false;
|
|
5526
5728
|
},
|
|
5527
5729
|
getDescendant(descendantId, context) {
|
|
5528
|
-
return this.getDescendants(context).find(
|
|
5730
|
+
return this.getDescendants(context).find(
|
|
5731
|
+
(item) => item.id == descendantId
|
|
5732
|
+
);
|
|
5529
5733
|
},
|
|
5530
5734
|
getDescendants(tagId) {
|
|
5531
5735
|
return resolveDescendants(id, includes, tagId, !isButton);
|
|
@@ -5567,7 +5771,9 @@ function createNodeIndex(builder) {
|
|
|
5567
5771
|
return owner.isBoundTo(tagId);
|
|
5568
5772
|
},
|
|
5569
5773
|
getDescendant(descendantId, context) {
|
|
5570
|
-
return this.getDescendants(context).find(
|
|
5774
|
+
return this.getDescendants(context).find(
|
|
5775
|
+
(item) => item.id == descendantId
|
|
5776
|
+
);
|
|
5571
5777
|
},
|
|
5572
5778
|
getDescendants(tagId) {
|
|
5573
5779
|
return resolveDescendants(id, includes, tagId);
|
|
@@ -5578,7 +5784,7 @@ function createNodeIndex(builder) {
|
|
|
5578
5784
|
return node;
|
|
5579
5785
|
};
|
|
5580
5786
|
const getNode = (input) => {
|
|
5581
|
-
var _a2, _b2, _c2, _d2, _e
|
|
5787
|
+
var _a2, _b2, _c2, _d2, _e;
|
|
5582
5788
|
if (typeof input !== "string") {
|
|
5583
5789
|
if ("bind_id" in input && !("type" in input))
|
|
5584
5790
|
return (_a2 = getTag(input.id)) != null ? _a2 : mkUnknown(input.id);
|
|
@@ -5588,11 +5794,7 @@ function createNodeIndex(builder) {
|
|
|
5588
5794
|
}
|
|
5589
5795
|
const cached = nodeCache.get(input);
|
|
5590
5796
|
if (cached) return cached;
|
|
5591
|
-
|
|
5592
|
-
if (id.startsWith("t:")) return (_d2 = getTag(id)) != null ? _d2 : mkUnknown(id);
|
|
5593
|
-
if (id.startsWith("f:")) return (_e = getField(id)) != null ? _e : mkUnknown(id);
|
|
5594
|
-
if (id.startsWith("o:")) return (_f = getOption(id)) != null ? _f : mkUnknown(id);
|
|
5595
|
-
return (_i = (_h = (_g = getTag(id)) != null ? _g : getField(id)) != null ? _h : getOption(id)) != null ? _i : mkUnknown(id);
|
|
5797
|
+
return (_e = (_d2 = nodeMap.get(input)) == null ? void 0 : _d2.node) != null ? _e : mkUnknown(input);
|
|
5596
5798
|
};
|
|
5597
5799
|
const mkUnknown = (id) => {
|
|
5598
5800
|
const u = {
|
|
@@ -5652,9 +5854,6 @@ function rateOk(svcMap, candidate, primary, policy) {
|
|
|
5652
5854
|
|
|
5653
5855
|
// src/react/canvas/editor.ts
|
|
5654
5856
|
var MAX_LIMIT = 100;
|
|
5655
|
-
var isTagId = (id) => id.startsWith("t:");
|
|
5656
|
-
var isFieldId = (id) => id.startsWith("f:");
|
|
5657
|
-
var isOptionId = (id) => id.startsWith("o:");
|
|
5658
5857
|
function ownerOfOption(props, optionId) {
|
|
5659
5858
|
var _a, _b;
|
|
5660
5859
|
for (const f of (_a = props.fields) != null ? _a : []) {
|
|
@@ -5696,6 +5895,15 @@ var Editor = class {
|
|
|
5696
5895
|
this.pushHistory(this.makeSnapshot("init"));
|
|
5697
5896
|
}
|
|
5698
5897
|
/* ───────────────────────── Public API ───────────────────────── */
|
|
5898
|
+
isTagId(id) {
|
|
5899
|
+
return this.builder.isTagId(id);
|
|
5900
|
+
}
|
|
5901
|
+
isFieldId(id) {
|
|
5902
|
+
return this.builder.isFieldId(id);
|
|
5903
|
+
}
|
|
5904
|
+
isOptionId(id) {
|
|
5905
|
+
return this.builder.isOptionId(id);
|
|
5906
|
+
}
|
|
5699
5907
|
getProps() {
|
|
5700
5908
|
return this.builder.getProps();
|
|
5701
5909
|
}
|
|
@@ -5791,7 +5999,7 @@ var Editor = class {
|
|
|
5791
5999
|
name: "reLabel",
|
|
5792
6000
|
do: () => this.patchProps((p) => {
|
|
5793
6001
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
5794
|
-
if (isTagId(id)) {
|
|
6002
|
+
if (this.isTagId(id)) {
|
|
5795
6003
|
const t = ((_a = p.filters) != null ? _a : []).find((x) => x.id === id);
|
|
5796
6004
|
if (!t) return;
|
|
5797
6005
|
if (((_b = t.label) != null ? _b : "") === label) return;
|
|
@@ -5799,7 +6007,7 @@ var Editor = class {
|
|
|
5799
6007
|
this.api.refreshGraph();
|
|
5800
6008
|
return;
|
|
5801
6009
|
}
|
|
5802
|
-
if (isOptionId(id)) {
|
|
6010
|
+
if (this.isOptionId(id)) {
|
|
5803
6011
|
const own = ownerOfOption(p, id);
|
|
5804
6012
|
if (!own) return;
|
|
5805
6013
|
const f = ((_c = p.fields) != null ? _c : []).find(
|
|
@@ -6100,7 +6308,7 @@ var Editor = class {
|
|
|
6100
6308
|
* - Option: use placeOption() instead
|
|
6101
6309
|
*/
|
|
6102
6310
|
placeNode(id, opts) {
|
|
6103
|
-
if (isTagId(id)) {
|
|
6311
|
+
if (this.isTagId(id)) {
|
|
6104
6312
|
this.exec({
|
|
6105
6313
|
name: "placeTag",
|
|
6106
6314
|
do: () => this.patchProps((p) => {
|
|
@@ -6147,7 +6355,7 @@ var Editor = class {
|
|
|
6147
6355
|
}),
|
|
6148
6356
|
undo: () => this.api.undo()
|
|
6149
6357
|
});
|
|
6150
|
-
} else if (isFieldId(id)) {
|
|
6358
|
+
} else if (this.isFieldId(id)) {
|
|
6151
6359
|
if (!opts.scopeTagId)
|
|
6152
6360
|
throw new Error("placeNode(field): scopeTagId is required");
|
|
6153
6361
|
const fieldId = id;
|
|
@@ -6174,14 +6382,14 @@ var Editor = class {
|
|
|
6174
6382
|
}),
|
|
6175
6383
|
undo: () => this.api.undo()
|
|
6176
6384
|
});
|
|
6177
|
-
} else if (isOptionId(id)) {
|
|
6385
|
+
} else if (this.isOptionId(id)) {
|
|
6178
6386
|
this.placeOption(id, opts);
|
|
6179
6387
|
} else {
|
|
6180
6388
|
throw new Error("placeNode: unknown id prefix");
|
|
6181
6389
|
}
|
|
6182
6390
|
}
|
|
6183
6391
|
placeOption(optionId, opts) {
|
|
6184
|
-
if (!isOptionId(optionId))
|
|
6392
|
+
if (!this.isOptionId(optionId))
|
|
6185
6393
|
throw new Error('placeOption: optionId must start with "o:"');
|
|
6186
6394
|
this.exec({
|
|
6187
6395
|
name: "placeOption",
|
|
@@ -6238,7 +6446,7 @@ var Editor = class {
|
|
|
6238
6446
|
return id;
|
|
6239
6447
|
}
|
|
6240
6448
|
updateOption(optionId, patch) {
|
|
6241
|
-
if (!isOptionId(optionId))
|
|
6449
|
+
if (!this.isOptionId(optionId))
|
|
6242
6450
|
throw new Error('updateOption: optionId must start with "o:"');
|
|
6243
6451
|
this.exec({
|
|
6244
6452
|
name: "updateOption",
|
|
@@ -6257,7 +6465,7 @@ var Editor = class {
|
|
|
6257
6465
|
});
|
|
6258
6466
|
}
|
|
6259
6467
|
removeOption(optionId) {
|
|
6260
|
-
if (!isOptionId(optionId))
|
|
6468
|
+
if (!this.isOptionId(optionId))
|
|
6261
6469
|
throw new Error('removeOption: optionId must start with "o:"');
|
|
6262
6470
|
this.exec({
|
|
6263
6471
|
name: "removeOption",
|
|
@@ -6288,17 +6496,17 @@ var Editor = class {
|
|
|
6288
6496
|
name: "editLabel",
|
|
6289
6497
|
do: () => this.patchProps((p) => {
|
|
6290
6498
|
var _a, _b, _c, _d;
|
|
6291
|
-
if (isTagId(id)) {
|
|
6499
|
+
if (this.isTagId(id)) {
|
|
6292
6500
|
const t = ((_a = p.filters) != null ? _a : []).find((x) => x.id === id);
|
|
6293
6501
|
if (t) t.label = next;
|
|
6294
6502
|
return;
|
|
6295
6503
|
}
|
|
6296
|
-
if (isFieldId(id)) {
|
|
6504
|
+
if (this.isFieldId(id)) {
|
|
6297
6505
|
const f = ((_b = p.fields) != null ? _b : []).find((x) => x.id === id);
|
|
6298
6506
|
if (f) f.label = next;
|
|
6299
6507
|
return;
|
|
6300
6508
|
}
|
|
6301
|
-
if (isOptionId(id)) {
|
|
6509
|
+
if (this.isOptionId(id)) {
|
|
6302
6510
|
const own = ownerOfOption(p, id);
|
|
6303
6511
|
if (!own) return;
|
|
6304
6512
|
const f = ((_c = p.fields) != null ? _c : []).find(
|
|
@@ -6337,7 +6545,7 @@ var Editor = class {
|
|
|
6337
6545
|
const validId = hasSidKey && typeof input.service_id === "number" && Number.isFinite(input.service_id);
|
|
6338
6546
|
const sid = validId ? Number(input.service_id) : void 0;
|
|
6339
6547
|
const nextRole = input.pricing_role;
|
|
6340
|
-
if (isTagId(id)) {
|
|
6548
|
+
if (this.isTagId(id)) {
|
|
6341
6549
|
const t = ((_a = p.filters) != null ? _a : []).find((x) => x.id === id);
|
|
6342
6550
|
if (!t) return;
|
|
6343
6551
|
if (hasSidKey) {
|
|
@@ -6346,7 +6554,7 @@ var Editor = class {
|
|
|
6346
6554
|
}
|
|
6347
6555
|
return;
|
|
6348
6556
|
}
|
|
6349
|
-
if (isOptionId(id)) {
|
|
6557
|
+
if (this.isOptionId(id)) {
|
|
6350
6558
|
const own = ownerOfOption(p, id);
|
|
6351
6559
|
if (!own) return;
|
|
6352
6560
|
const f2 = ((_b = p.fields) != null ? _b : []).find(
|
|
@@ -6553,7 +6761,7 @@ var Editor = class {
|
|
|
6553
6761
|
});
|
|
6554
6762
|
}
|
|
6555
6763
|
remove(id) {
|
|
6556
|
-
if (isTagId(id)) {
|
|
6764
|
+
if (this.isTagId(id)) {
|
|
6557
6765
|
this.exec({
|
|
6558
6766
|
name: "removeTag",
|
|
6559
6767
|
do: () => this.patchProps((p) => {
|
|
@@ -6593,7 +6801,7 @@ var Editor = class {
|
|
|
6593
6801
|
});
|
|
6594
6802
|
return;
|
|
6595
6803
|
}
|
|
6596
|
-
if (isFieldId(id)) {
|
|
6804
|
+
if (this.isFieldId(id)) {
|
|
6597
6805
|
this.exec({
|
|
6598
6806
|
name: "removeField",
|
|
6599
6807
|
do: () => this.patchProps((p) => {
|
|
@@ -6629,7 +6837,7 @@ var Editor = class {
|
|
|
6629
6837
|
});
|
|
6630
6838
|
return;
|
|
6631
6839
|
}
|
|
6632
|
-
if (isOptionId(id)) {
|
|
6840
|
+
if (this.isOptionId(id)) {
|
|
6633
6841
|
this.removeOption(id);
|
|
6634
6842
|
return;
|
|
6635
6843
|
}
|
|
@@ -6638,7 +6846,7 @@ var Editor = class {
|
|
|
6638
6846
|
getNode(id) {
|
|
6639
6847
|
var _a, _b, _c, _d;
|
|
6640
6848
|
const props = this.builder.getProps();
|
|
6641
|
-
if (isTagId(id)) {
|
|
6849
|
+
if (this.isTagId(id)) {
|
|
6642
6850
|
const t = ((_a = props.filters) != null ? _a : []).find((x) => x.id === id);
|
|
6643
6851
|
return {
|
|
6644
6852
|
kind: "tag",
|
|
@@ -6646,12 +6854,12 @@ var Editor = class {
|
|
|
6646
6854
|
owners: { parentTagId: t == null ? void 0 : t.bind_id }
|
|
6647
6855
|
};
|
|
6648
6856
|
}
|
|
6649
|
-
if (isFieldId(id)) {
|
|
6857
|
+
if (this.isFieldId(id)) {
|
|
6650
6858
|
const f = ((_b = props.fields) != null ? _b : []).find((x) => x.id === id);
|
|
6651
6859
|
const bind = Array.isArray(f == null ? void 0 : f.bind_id) ? f.bind_id : (f == null ? void 0 : f.bind_id) ? [f.bind_id] : [];
|
|
6652
6860
|
return { kind: "field", data: f, owners: { bindTagIds: bind } };
|
|
6653
6861
|
}
|
|
6654
|
-
if (isOptionId(id)) {
|
|
6862
|
+
if (this.isOptionId(id)) {
|
|
6655
6863
|
const own = ownerOfOption(props, id);
|
|
6656
6864
|
const f = own ? ((_c = props.fields) != null ? _c : []).find((x) => x.id === own.fieldId) : void 0;
|
|
6657
6865
|
const o = (_d = f == null ? void 0 : f.options) == null ? void 0 : _d.find((x) => x.id === id);
|
|
@@ -6729,7 +6937,7 @@ var Editor = class {
|
|
|
6729
6937
|
if (receiverId === targetId) return true;
|
|
6730
6938
|
const getDirectRelations = (id) => {
|
|
6731
6939
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
6732
|
-
if (isTagId(id)) {
|
|
6940
|
+
if (this.isTagId(id)) {
|
|
6733
6941
|
const t = ((_a = p.filters) != null ? _a : []).find((x) => x.id === id);
|
|
6734
6942
|
return [...(_b = t == null ? void 0 : t.includes) != null ? _b : [], ...(_c = t == null ? void 0 : t.excludes) != null ? _c : []];
|
|
6735
6943
|
}
|
|
@@ -6949,7 +7157,7 @@ var Editor = class {
|
|
|
6949
7157
|
do: () => this.patchProps((p) => {
|
|
6950
7158
|
var _a, _b, _c, _d, _e;
|
|
6951
7159
|
if (kind === "bind") {
|
|
6952
|
-
if (isTagId(fromId) && isTagId(toId2)) {
|
|
7160
|
+
if (this.isTagId(fromId) && this.isTagId(toId2)) {
|
|
6953
7161
|
if (this.wouldCreateTagCycle(p, fromId, toId2)) {
|
|
6954
7162
|
throw new Error(
|
|
6955
7163
|
`bind would create a cycle: ${fromId} \u2192 ${toId2}`
|
|
@@ -6961,9 +7169,9 @@ var Editor = class {
|
|
|
6961
7169
|
if (child) child.bind_id = fromId;
|
|
6962
7170
|
return;
|
|
6963
7171
|
}
|
|
6964
|
-
if (isTagId(fromId) && isFieldId(toId2) || isFieldId(fromId) && isTagId(toId2)) {
|
|
6965
|
-
const fieldId = isFieldId(toId2) ? toId2 : fromId;
|
|
6966
|
-
const tagId = isTagId(fromId) ? fromId : toId2;
|
|
7172
|
+
if (this.isTagId(fromId) && this.isFieldId(toId2) || this.isFieldId(fromId) && this.isTagId(toId2)) {
|
|
7173
|
+
const fieldId = this.isFieldId(toId2) ? toId2 : fromId;
|
|
7174
|
+
const tagId = this.isTagId(fromId) ? fromId : toId2;
|
|
6967
7175
|
const f = ((_b = p.fields) != null ? _b : []).find(
|
|
6968
7176
|
(x) => x.id === fieldId
|
|
6969
7177
|
);
|
|
@@ -6987,7 +7195,7 @@ var Editor = class {
|
|
|
6987
7195
|
}
|
|
6988
7196
|
if (kind === "include" || kind === "exclude") {
|
|
6989
7197
|
const key = kind === "include" ? "includes" : "excludes";
|
|
6990
|
-
if (isTagId(fromId) && isFieldId(toId2)) {
|
|
7198
|
+
if (this.isTagId(fromId) && this.isFieldId(toId2)) {
|
|
6991
7199
|
const t = ((_c = p.filters) != null ? _c : []).find(
|
|
6992
7200
|
(x) => x.id === fromId
|
|
6993
7201
|
);
|
|
@@ -6996,7 +7204,7 @@ var Editor = class {
|
|
|
6996
7204
|
if (!arr.includes(toId2)) arr.push(toId2);
|
|
6997
7205
|
return;
|
|
6998
7206
|
}
|
|
6999
|
-
if (isOptionId(fromId) && isFieldId(toId2)) {
|
|
7207
|
+
if (this.isOptionId(fromId) && this.isFieldId(toId2)) {
|
|
7000
7208
|
const mapKey = kind === "include" ? "includes_for_options" : "excludes_for_options";
|
|
7001
7209
|
const maps = p[mapKey];
|
|
7002
7210
|
const next = { ...maps != null ? maps : {} };
|
|
@@ -7064,16 +7272,16 @@ var Editor = class {
|
|
|
7064
7272
|
do: () => this.patchProps((p) => {
|
|
7065
7273
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
7066
7274
|
if (kind === "bind") {
|
|
7067
|
-
if (isTagId(fromId) && isTagId(toId2)) {
|
|
7275
|
+
if (this.isTagId(fromId) && this.isTagId(toId2)) {
|
|
7068
7276
|
const child = ((_a = p.filters) != null ? _a : []).find(
|
|
7069
7277
|
(t) => t.id === toId2
|
|
7070
7278
|
);
|
|
7071
7279
|
if ((child == null ? void 0 : child.bind_id) === fromId) delete child.bind_id;
|
|
7072
7280
|
return;
|
|
7073
7281
|
}
|
|
7074
|
-
if (isTagId(fromId) && isFieldId(toId2) || isFieldId(fromId) && isTagId(toId2)) {
|
|
7075
|
-
const fieldId = isFieldId(toId2) ? toId2 : fromId;
|
|
7076
|
-
const tagId = isTagId(fromId) ? fromId : toId2;
|
|
7282
|
+
if (this.isTagId(fromId) && this.isFieldId(toId2) || this.isFieldId(fromId) && this.isTagId(toId2)) {
|
|
7283
|
+
const fieldId = this.isFieldId(toId2) ? toId2 : fromId;
|
|
7284
|
+
const tagId = this.isTagId(fromId) ? fromId : toId2;
|
|
7077
7285
|
const f = ((_b = p.fields) != null ? _b : []).find(
|
|
7078
7286
|
(x) => x.id === fieldId
|
|
7079
7287
|
);
|
|
@@ -7094,7 +7302,7 @@ var Editor = class {
|
|
|
7094
7302
|
}
|
|
7095
7303
|
if (kind === "include" || kind === "exclude") {
|
|
7096
7304
|
const key = kind === "include" ? "includes" : "excludes";
|
|
7097
|
-
if (isTagId(fromId) && isFieldId(toId2)) {
|
|
7305
|
+
if (this.isTagId(fromId) && this.isFieldId(toId2)) {
|
|
7098
7306
|
const t = ((_d = p.filters) != null ? _d : []).find(
|
|
7099
7307
|
(x) => x.id === fromId
|
|
7100
7308
|
);
|
|
@@ -7103,7 +7311,7 @@ var Editor = class {
|
|
|
7103
7311
|
if (!((_f = t[key]) == null ? void 0 : _f.length)) delete t[key];
|
|
7104
7312
|
return;
|
|
7105
7313
|
}
|
|
7106
|
-
if (isOptionId(fromId) && isFieldId(toId2)) {
|
|
7314
|
+
if (this.isOptionId(fromId) && this.isFieldId(toId2)) {
|
|
7107
7315
|
const mapKey = kind === "include" ? "includes_for_options" : "excludes_for_options";
|
|
7108
7316
|
const maps = p[mapKey];
|
|
7109
7317
|
if (!maps) return;
|
|
@@ -7570,8 +7778,6 @@ function toStrSet(v) {
|
|
|
7570
7778
|
}
|
|
7571
7779
|
|
|
7572
7780
|
// src/react/canvas/selection.ts
|
|
7573
|
-
var isTagId2 = (id) => typeof id === "string" && id.startsWith("t:");
|
|
7574
|
-
var isOptionId2 = (id) => typeof id === "string" && id.startsWith("o:");
|
|
7575
7781
|
var Selection = class {
|
|
7576
7782
|
constructor(builder, opts) {
|
|
7577
7783
|
this.builder = builder;
|
|
@@ -7589,6 +7795,7 @@ var Selection = class {
|
|
|
7589
7795
|
this.emit();
|
|
7590
7796
|
}
|
|
7591
7797
|
add(id) {
|
|
7798
|
+
if (this.set.has(id)) this.set.delete(id);
|
|
7592
7799
|
this.set.add(id);
|
|
7593
7800
|
this.primaryId = id;
|
|
7594
7801
|
this.updateCurrentTagFrom(id);
|
|
@@ -7643,7 +7850,9 @@ var Selection = class {
|
|
|
7643
7850
|
var _a;
|
|
7644
7851
|
const props = this.builder.getProps();
|
|
7645
7852
|
if (((_a = this.opts.env) != null ? _a : "client") === "workspace") {
|
|
7646
|
-
const tagIds = Array.from(this.set).filter(
|
|
7853
|
+
const tagIds = Array.from(this.set).filter(
|
|
7854
|
+
this.builder.isTagId.bind(this.builder)
|
|
7855
|
+
);
|
|
7647
7856
|
if (tagIds.length > 1) {
|
|
7648
7857
|
return { kind: "multi", groups: Array.from(this.set) };
|
|
7649
7858
|
}
|
|
@@ -7654,6 +7863,98 @@ var Selection = class {
|
|
|
7654
7863
|
const group = this.computeGroupForTag(props, tagId);
|
|
7655
7864
|
return { kind: "single", group };
|
|
7656
7865
|
}
|
|
7866
|
+
/**
|
|
7867
|
+
* Build a fieldId -> triggerKeys[] map from the current selection set.
|
|
7868
|
+
*
|
|
7869
|
+
* What counts as a "button selection" (trigger key):
|
|
7870
|
+
* - field key where the field has button === true (e.g. "f:dripfeed")
|
|
7871
|
+
* - option key (e.g. "o:fast")
|
|
7872
|
+
* - composite key "fieldId::optionId" (e.g. "f:speed::o:fast")
|
|
7873
|
+
*
|
|
7874
|
+
* Grouping:
|
|
7875
|
+
* - button-field trigger groups under its own fieldId
|
|
7876
|
+
* - option/composite groups under the option's owning fieldId (from nodeMap)
|
|
7877
|
+
*
|
|
7878
|
+
* Deterministic:
|
|
7879
|
+
* - preserves selection insertion order
|
|
7880
|
+
* - de-dupes per field
|
|
7881
|
+
*/
|
|
7882
|
+
buttonSelectionsByFieldId() {
|
|
7883
|
+
var _a, _b, _c, _d, _e;
|
|
7884
|
+
const nodeMap = this.builder.getNodeMap();
|
|
7885
|
+
const out = {};
|
|
7886
|
+
const push = (fieldId, triggerKey) => {
|
|
7887
|
+
var _a2;
|
|
7888
|
+
const arr = (_a2 = out[fieldId]) != null ? _a2 : out[fieldId] = [];
|
|
7889
|
+
if (!arr.includes(triggerKey)) arr.push(triggerKey);
|
|
7890
|
+
};
|
|
7891
|
+
for (const key of this.set) {
|
|
7892
|
+
if (!key) continue;
|
|
7893
|
+
const idx = key.indexOf("::");
|
|
7894
|
+
if (idx !== -1) {
|
|
7895
|
+
const optionId = key.slice(idx + 2);
|
|
7896
|
+
const optRef = nodeMap.get(optionId);
|
|
7897
|
+
if ((optRef == null ? void 0 : optRef.kind) === "option" && typeof optRef.fieldId === "string") {
|
|
7898
|
+
push(optRef.fieldId, key);
|
|
7899
|
+
}
|
|
7900
|
+
continue;
|
|
7901
|
+
}
|
|
7902
|
+
const ref = nodeMap.get(key);
|
|
7903
|
+
if (!ref) continue;
|
|
7904
|
+
if (ref.kind === "option" && typeof ref.fieldId === "string") {
|
|
7905
|
+
push(ref.fieldId, (_a = ref.id) != null ? _a : key);
|
|
7906
|
+
continue;
|
|
7907
|
+
}
|
|
7908
|
+
if (ref.kind === "field") {
|
|
7909
|
+
const field = (_c = (_b = ref.node) != null ? _b : ref.field) != null ? _c : ref;
|
|
7910
|
+
const fieldId = (_e = (_d = ref.id) != null ? _d : field == null ? void 0 : field.id) != null ? _e : key;
|
|
7911
|
+
if ((field == null ? void 0 : field.button) === true && typeof fieldId === "string") {
|
|
7912
|
+
push(fieldId, fieldId);
|
|
7913
|
+
}
|
|
7914
|
+
}
|
|
7915
|
+
}
|
|
7916
|
+
return out;
|
|
7917
|
+
}
|
|
7918
|
+
/**
|
|
7919
|
+
* Returns only selection keys that are valid "trigger buttons":
|
|
7920
|
+
* - field keys where field.button === true
|
|
7921
|
+
* - option keys
|
|
7922
|
+
* - composite keys "fieldId::optionId" (validated by optionId)
|
|
7923
|
+
* Excludes tags and non-button fields.
|
|
7924
|
+
*/
|
|
7925
|
+
selectedButtons() {
|
|
7926
|
+
var _a, _b;
|
|
7927
|
+
const nodeMap = this.builder.getNodeMap();
|
|
7928
|
+
const out = [];
|
|
7929
|
+
const seen = /* @__PURE__ */ new Set();
|
|
7930
|
+
const push = (k) => {
|
|
7931
|
+
if (!seen.has(k)) {
|
|
7932
|
+
seen.add(k);
|
|
7933
|
+
out.push(k);
|
|
7934
|
+
}
|
|
7935
|
+
};
|
|
7936
|
+
for (const key of this.set) {
|
|
7937
|
+
if (!key) continue;
|
|
7938
|
+
const idx = key.indexOf("::");
|
|
7939
|
+
if (idx !== -1) {
|
|
7940
|
+
const optionId = key.slice(idx + 2);
|
|
7941
|
+
const optRef = nodeMap.get(optionId);
|
|
7942
|
+
if ((optRef == null ? void 0 : optRef.kind) === "option") push(key);
|
|
7943
|
+
continue;
|
|
7944
|
+
}
|
|
7945
|
+
const ref = nodeMap.get(key);
|
|
7946
|
+
if (!ref) continue;
|
|
7947
|
+
if (ref.kind === "option") {
|
|
7948
|
+
push(key);
|
|
7949
|
+
continue;
|
|
7950
|
+
}
|
|
7951
|
+
if (ref.kind === "field") {
|
|
7952
|
+
const field = (_b = (_a = ref.node) != null ? _a : ref.field) != null ? _b : ref;
|
|
7953
|
+
if ((field == null ? void 0 : field.button) === true) push(key);
|
|
7954
|
+
}
|
|
7955
|
+
}
|
|
7956
|
+
return out;
|
|
7957
|
+
}
|
|
7657
7958
|
// ── Internals ────────────────────────────────────────────────────────────
|
|
7658
7959
|
emit() {
|
|
7659
7960
|
const payload = {
|
|
@@ -7676,7 +7977,7 @@ var Selection = class {
|
|
|
7676
7977
|
this.currentTagId = Array.isArray(f.bind_id) ? f.bind_id[0] : f.bind_id;
|
|
7677
7978
|
return;
|
|
7678
7979
|
}
|
|
7679
|
-
if (
|
|
7980
|
+
if (this.builder.isOptionId(id)) {
|
|
7680
7981
|
const host = fields.find(
|
|
7681
7982
|
(x) => {
|
|
7682
7983
|
var _a2;
|
|
@@ -7700,7 +8001,7 @@ var Selection = class {
|
|
|
7700
8001
|
resolveTagContextId(props) {
|
|
7701
8002
|
var _a;
|
|
7702
8003
|
if (this.currentTagId) return this.currentTagId;
|
|
7703
|
-
for (const id of this.set) if (
|
|
8004
|
+
for (const id of this.set) if (this.builder.isTagId(id)) return id;
|
|
7704
8005
|
const fields = (_a = props.fields) != null ? _a : [];
|
|
7705
8006
|
for (const id of this.set) {
|
|
7706
8007
|
const f = fields.find((x) => x.id === id);
|
|
@@ -7708,7 +8009,7 @@ var Selection = class {
|
|
|
7708
8009
|
return Array.isArray(f.bind_id) ? f.bind_id[0] : f.bind_id;
|
|
7709
8010
|
}
|
|
7710
8011
|
for (const id of this.set) {
|
|
7711
|
-
if (
|
|
8012
|
+
if (this.builder.isOptionId(id)) {
|
|
7712
8013
|
const host = fields.find(
|
|
7713
8014
|
(x) => {
|
|
7714
8015
|
var _a2;
|
|
@@ -7727,28 +8028,13 @@ var Selection = class {
|
|
|
7727
8028
|
}
|
|
7728
8029
|
return this.opts.rootTagId;
|
|
7729
8030
|
}
|
|
7730
|
-
selectedButtonTriggerIds(props) {
|
|
7731
|
-
var _a;
|
|
7732
|
-
const fields = (_a = props.fields) != null ? _a : [];
|
|
7733
|
-
const fieldById = new Map(fields.map((f) => [f.id, f]));
|
|
7734
|
-
const out = [];
|
|
7735
|
-
for (const selId of this.set) {
|
|
7736
|
-
if (selId.startsWith("o:")) {
|
|
7737
|
-
out.push(selId);
|
|
7738
|
-
continue;
|
|
7739
|
-
}
|
|
7740
|
-
const f = fieldById.get(selId);
|
|
7741
|
-
if ((f == null ? void 0 : f.button) === true) out.push(selId);
|
|
7742
|
-
}
|
|
7743
|
-
return out;
|
|
7744
|
-
}
|
|
7745
8031
|
computeGroupForTag(props, tagId) {
|
|
7746
8032
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
7747
8033
|
const tags = (_a = props.filters) != null ? _a : [];
|
|
7748
8034
|
const fields = (_b = props.fields) != null ? _b : [];
|
|
7749
8035
|
const tagById = new Map(tags.map((t) => [t.id, t]));
|
|
7750
8036
|
const tag = tagById.get(tagId);
|
|
7751
|
-
const selectedTriggerIds = this.
|
|
8037
|
+
const selectedTriggerIds = this.selectedButtons();
|
|
7752
8038
|
const fieldIds = this.builder.visibleFields(tagId, selectedTriggerIds);
|
|
7753
8039
|
const fieldById = new Map(fields.map((f) => [f.id, f]));
|
|
7754
8040
|
const visible = fieldIds.map((id) => fieldById.get(id)).filter(Boolean);
|
|
@@ -7829,7 +8115,7 @@ var Selection = class {
|
|
|
7829
8115
|
}
|
|
7830
8116
|
findOptionById(fields, selId) {
|
|
7831
8117
|
var _a, _b;
|
|
7832
|
-
if (
|
|
8118
|
+
if (this.builder.isOptionId(selId)) {
|
|
7833
8119
|
for (const f of fields) {
|
|
7834
8120
|
const o = (_a = f.options) == null ? void 0 : _a.find((x) => x.id === selId);
|
|
7835
8121
|
if (o) return o;
|
|
@@ -8251,8 +8537,8 @@ function useCanvasOwned(initialProps, canvasOpts, builderOpts) {
|
|
|
8251
8537
|
// src/react/workspace/context/hooks/use-canvas.ts
|
|
8252
8538
|
var React16 = __toESM(require("react"), 1);
|
|
8253
8539
|
var import_react4 = require("react");
|
|
8254
|
-
var
|
|
8255
|
-
var
|
|
8540
|
+
var isTagId = (id) => id.startsWith("t:");
|
|
8541
|
+
var isOptionId = (id) => id.startsWith("o:");
|
|
8256
8542
|
function deriveSelectionInfo(props, ids) {
|
|
8257
8543
|
var _a, _b, _c, _d;
|
|
8258
8544
|
const tags = [];
|
|
@@ -8261,11 +8547,11 @@ function deriveSelectionInfo(props, ids) {
|
|
|
8261
8547
|
const fieldById = /* @__PURE__ */ new Map();
|
|
8262
8548
|
for (const f of (_a = props.fields) != null ? _a : []) fieldById.set(f.id, f);
|
|
8263
8549
|
for (const id of ids) {
|
|
8264
|
-
if (
|
|
8550
|
+
if (isTagId(id)) {
|
|
8265
8551
|
tags.push(id);
|
|
8266
8552
|
continue;
|
|
8267
8553
|
}
|
|
8268
|
-
if (
|
|
8554
|
+
if (isOptionId(id)) {
|
|
8269
8555
|
options.push(id);
|
|
8270
8556
|
continue;
|
|
8271
8557
|
}
|