@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.js
CHANGED
|
@@ -3217,11 +3217,6 @@ function hasAnyServiceOption(f) {
|
|
|
3217
3217
|
var _a;
|
|
3218
3218
|
return ((_a = f.options) != null ? _a : []).some((o) => isFiniteNumber(o.service_id));
|
|
3219
3219
|
}
|
|
3220
|
-
function isBoundTo(f, tagId) {
|
|
3221
|
-
const b = f.bind_id;
|
|
3222
|
-
if (!b) return false;
|
|
3223
|
-
return Array.isArray(b) ? b.includes(tagId) : b === tagId;
|
|
3224
|
-
}
|
|
3225
3220
|
function getByPath(obj, path) {
|
|
3226
3221
|
if (!path) return void 0;
|
|
3227
3222
|
const parts = path.split(".");
|
|
@@ -3307,33 +3302,214 @@ function withAffected(details, ids) {
|
|
|
3307
3302
|
return { ...details != null ? details : {}, affectedIds: ids };
|
|
3308
3303
|
}
|
|
3309
3304
|
|
|
3305
|
+
// src/core/node-map.ts
|
|
3306
|
+
function buildNodeMap(props) {
|
|
3307
|
+
var _a, _b, _c;
|
|
3308
|
+
const map = /* @__PURE__ */ new Map();
|
|
3309
|
+
for (const t of (_a = props.filters) != null ? _a : []) {
|
|
3310
|
+
if (!map.has(t.id)) map.set(t.id, { kind: "tag", id: t.id, node: t });
|
|
3311
|
+
}
|
|
3312
|
+
for (const f of (_b = props.fields) != null ? _b : []) {
|
|
3313
|
+
if (!map.has(f.id)) map.set(f.id, { kind: "field", id: f.id, node: f });
|
|
3314
|
+
for (const o of (_c = f.options) != null ? _c : []) {
|
|
3315
|
+
if (!map.has(o.id))
|
|
3316
|
+
map.set(o.id, {
|
|
3317
|
+
kind: "option",
|
|
3318
|
+
id: o.id,
|
|
3319
|
+
node: o,
|
|
3320
|
+
fieldId: f.id
|
|
3321
|
+
});
|
|
3322
|
+
}
|
|
3323
|
+
}
|
|
3324
|
+
return map;
|
|
3325
|
+
}
|
|
3326
|
+
function resolveTrigger(trigger, nodeMap) {
|
|
3327
|
+
const idx = trigger.indexOf("::");
|
|
3328
|
+
if (idx !== -1) {
|
|
3329
|
+
const fieldId = trigger.slice(0, idx);
|
|
3330
|
+
const optionId = trigger.slice(idx + 2);
|
|
3331
|
+
return { kind: "composite", triggerKey: trigger, fieldId, optionId };
|
|
3332
|
+
}
|
|
3333
|
+
const direct = nodeMap.get(trigger);
|
|
3334
|
+
if (!direct) return void 0;
|
|
3335
|
+
if (direct.kind === "option") {
|
|
3336
|
+
return {
|
|
3337
|
+
kind: "option",
|
|
3338
|
+
triggerKey: trigger,
|
|
3339
|
+
id: direct.id,
|
|
3340
|
+
fieldId: direct.fieldId
|
|
3341
|
+
};
|
|
3342
|
+
}
|
|
3343
|
+
return { kind: direct.kind, triggerKey: trigger, id: direct.id };
|
|
3344
|
+
}
|
|
3345
|
+
|
|
3346
|
+
// src/core/visibility.ts
|
|
3347
|
+
function visibleFieldIdsUnder(props, tagId, opts = {}) {
|
|
3348
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
3349
|
+
const tags = (_a = props.filters) != null ? _a : [];
|
|
3350
|
+
const fields = (_b = props.fields) != null ? _b : [];
|
|
3351
|
+
const tagById = new Map(tags.map((t) => [t.id, t]));
|
|
3352
|
+
const tag = tagById.get(tagId);
|
|
3353
|
+
if (!tag) return [];
|
|
3354
|
+
const nodeMap = buildNodeMap(props);
|
|
3355
|
+
const lineageDepth = /* @__PURE__ */ new Map();
|
|
3356
|
+
{
|
|
3357
|
+
const guard = /* @__PURE__ */ new Set();
|
|
3358
|
+
let cur = tag;
|
|
3359
|
+
let d = 0;
|
|
3360
|
+
while (cur && !guard.has(cur.id)) {
|
|
3361
|
+
lineageDepth.set(cur.id, d++);
|
|
3362
|
+
guard.add(cur.id);
|
|
3363
|
+
const parentId = cur.bind_id;
|
|
3364
|
+
cur = parentId ? tagById.get(parentId) : void 0;
|
|
3365
|
+
}
|
|
3366
|
+
}
|
|
3367
|
+
const isTagInLineage = (id) => lineageDepth.has(id);
|
|
3368
|
+
const fieldById = new Map(fields.map((f) => [f.id, f]));
|
|
3369
|
+
const ownerDepthForField = (f) => {
|
|
3370
|
+
const b = f.bind_id;
|
|
3371
|
+
if (!b) return void 0;
|
|
3372
|
+
if (typeof b === "string") return lineageDepth.get(b);
|
|
3373
|
+
let best = void 0;
|
|
3374
|
+
for (const id of b) {
|
|
3375
|
+
const d = lineageDepth.get(id);
|
|
3376
|
+
if (d == null) continue;
|
|
3377
|
+
if (best == null || d < best) best = d;
|
|
3378
|
+
}
|
|
3379
|
+
return best;
|
|
3380
|
+
};
|
|
3381
|
+
const ownerDepthForTriggerKey = (triggerKey) => {
|
|
3382
|
+
const t = resolveTrigger(triggerKey, nodeMap);
|
|
3383
|
+
if (!t) return void 0;
|
|
3384
|
+
if (t.kind === "composite") {
|
|
3385
|
+
const f = fieldById.get(t.fieldId);
|
|
3386
|
+
if (!f) return void 0;
|
|
3387
|
+
return ownerDepthForField(f);
|
|
3388
|
+
}
|
|
3389
|
+
if (t.kind === "field") {
|
|
3390
|
+
const f = fieldById.get(t.id);
|
|
3391
|
+
if (!f || f.button !== true) return void 0;
|
|
3392
|
+
return ownerDepthForField(f);
|
|
3393
|
+
}
|
|
3394
|
+
if (t.kind === "option") {
|
|
3395
|
+
const f = t.fieldId ? fieldById.get(t.fieldId) : void 0;
|
|
3396
|
+
if (!f) return void 0;
|
|
3397
|
+
return ownerDepthForField(f);
|
|
3398
|
+
}
|
|
3399
|
+
return void 0;
|
|
3400
|
+
};
|
|
3401
|
+
const tagInclude = new Set((_c = tag.includes) != null ? _c : []);
|
|
3402
|
+
const tagExclude = new Set((_d = tag.excludes) != null ? _d : []);
|
|
3403
|
+
const selected = (_e = opts.selectedKeys) != null ? _e : /* @__PURE__ */ new Set();
|
|
3404
|
+
const incMap = (_f = props.includes_for_buttons) != null ? _f : {};
|
|
3405
|
+
const excMap = (_g = props.excludes_for_buttons) != null ? _g : {};
|
|
3406
|
+
const relevantTriggersInOrder = [];
|
|
3407
|
+
for (const key of selected) {
|
|
3408
|
+
const d = ownerDepthForTriggerKey(key);
|
|
3409
|
+
if (d == null) continue;
|
|
3410
|
+
relevantTriggersInOrder.push(key);
|
|
3411
|
+
}
|
|
3412
|
+
const visible = /* @__PURE__ */ new Set();
|
|
3413
|
+
const isBoundToLineage = (f) => {
|
|
3414
|
+
const b = f.bind_id;
|
|
3415
|
+
if (!b) return false;
|
|
3416
|
+
if (typeof b === "string") return isTagInLineage(b);
|
|
3417
|
+
for (const id of b) if (isTagInLineage(id)) return true;
|
|
3418
|
+
return false;
|
|
3419
|
+
};
|
|
3420
|
+
for (const f of fields) {
|
|
3421
|
+
if (isBoundToLineage(f)) visible.add(f.id);
|
|
3422
|
+
if (tagInclude.has(f.id)) visible.add(f.id);
|
|
3423
|
+
}
|
|
3424
|
+
for (const id of tagExclude) visible.delete(id);
|
|
3425
|
+
const decide = /* @__PURE__ */ new Map();
|
|
3426
|
+
const applyDecision = (fieldId, next) => {
|
|
3427
|
+
const prev = decide.get(fieldId);
|
|
3428
|
+
if (!prev) return void decide.set(fieldId, next);
|
|
3429
|
+
if (next.depth < prev.depth) return void decide.set(fieldId, next);
|
|
3430
|
+
if (next.depth > prev.depth) return;
|
|
3431
|
+
if (prev.kind === "include" && next.kind === "exclude") {
|
|
3432
|
+
decide.set(fieldId, next);
|
|
3433
|
+
}
|
|
3434
|
+
};
|
|
3435
|
+
const revealedOrder = [];
|
|
3436
|
+
const revealedSeen = /* @__PURE__ */ new Set();
|
|
3437
|
+
for (const triggerKey of relevantTriggersInOrder) {
|
|
3438
|
+
const depth = ownerDepthForTriggerKey(triggerKey);
|
|
3439
|
+
if (depth == null) continue;
|
|
3440
|
+
for (const id of (_h = incMap[triggerKey]) != null ? _h : []) {
|
|
3441
|
+
applyDecision(id, { depth, kind: "include" });
|
|
3442
|
+
if (!revealedSeen.has(id)) {
|
|
3443
|
+
revealedSeen.add(id);
|
|
3444
|
+
revealedOrder.push(id);
|
|
3445
|
+
}
|
|
3446
|
+
}
|
|
3447
|
+
for (const id of (_i = excMap[triggerKey]) != null ? _i : []) {
|
|
3448
|
+
applyDecision(id, { depth, kind: "exclude" });
|
|
3449
|
+
}
|
|
3450
|
+
}
|
|
3451
|
+
for (const [fid, d] of decide) {
|
|
3452
|
+
if (d.kind === "include") visible.add(fid);
|
|
3453
|
+
else visible.delete(fid);
|
|
3454
|
+
}
|
|
3455
|
+
const base = fields.filter((f) => visible.has(f.id)).map((f) => f.id);
|
|
3456
|
+
const order = (_j = props.order_for_tags) == null ? void 0 : _j[tagId];
|
|
3457
|
+
if (order && order.length) {
|
|
3458
|
+
const ordered = order.filter((fid) => visible.has(fid));
|
|
3459
|
+
const orderedSet = new Set(ordered);
|
|
3460
|
+
const rest = base.filter((fid) => !orderedSet.has(fid));
|
|
3461
|
+
return [...ordered, ...rest];
|
|
3462
|
+
}
|
|
3463
|
+
return base;
|
|
3464
|
+
}
|
|
3465
|
+
function visibleFieldsUnder(props, tagId, opts = {}) {
|
|
3466
|
+
var _a;
|
|
3467
|
+
const ids = visibleFieldIdsUnder(props, tagId, opts);
|
|
3468
|
+
const fieldById = new Map(((_a = props.fields) != null ? _a : []).map((f) => [f.id, f]));
|
|
3469
|
+
return ids.map((id) => fieldById.get(id)).filter(Boolean);
|
|
3470
|
+
}
|
|
3471
|
+
|
|
3310
3472
|
// src/core/validate/steps/visibility.ts
|
|
3311
3473
|
function createFieldsVisibleUnder(v) {
|
|
3312
3474
|
return (tagId) => {
|
|
3313
|
-
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
const excludesTag = new Set((_b = tag == null ? void 0 : tag.excludes) != null ? _b : []);
|
|
3317
|
-
const incForOpt = (_c = v.props.includes_for_buttons) != null ? _c : {};
|
|
3318
|
-
const excForOpt = (_d = v.props.excludes_for_buttons) != null ? _d : {};
|
|
3319
|
-
const includesOpt = /* @__PURE__ */ new Set();
|
|
3320
|
-
const excludesOpt = /* @__PURE__ */ new Set();
|
|
3321
|
-
for (const key of v.selectedKeys) {
|
|
3322
|
-
for (const id of (_e = incForOpt[key]) != null ? _e : []) includesOpt.add(id);
|
|
3323
|
-
for (const id of (_f = excForOpt[key]) != null ? _f : []) excludesOpt.add(id);
|
|
3324
|
-
}
|
|
3325
|
-
const merged = /* @__PURE__ */ new Map();
|
|
3326
|
-
for (const f of v.fields) {
|
|
3327
|
-
if (isBoundTo(f, tagId)) merged.set(f.id, f);
|
|
3328
|
-
if (includesTag.has(f.id)) merged.set(f.id, f);
|
|
3329
|
-
if (includesOpt.has(f.id)) merged.set(f.id, f);
|
|
3330
|
-
}
|
|
3331
|
-
for (const id of excludesTag) merged.delete(id);
|
|
3332
|
-
for (const id of excludesOpt) merged.delete(id);
|
|
3333
|
-
return Array.from(merged.values());
|
|
3475
|
+
return visibleFieldsUnder(v.props, tagId, {
|
|
3476
|
+
selectedKeys: v.selectedKeys
|
|
3477
|
+
});
|
|
3334
3478
|
};
|
|
3335
3479
|
}
|
|
3336
|
-
function
|
|
3480
|
+
function stableKeyOfSelection(keys) {
|
|
3481
|
+
return Array.from(keys).sort().join("|");
|
|
3482
|
+
}
|
|
3483
|
+
function resolveRootTags(tags) {
|
|
3484
|
+
const roots = tags.filter((t) => !t.bind_id);
|
|
3485
|
+
return roots.length ? roots : tags.slice(0, 1);
|
|
3486
|
+
}
|
|
3487
|
+
function isEffectfulTrigger(v, trigger) {
|
|
3488
|
+
var _a, _b, _c, _d, _e, _f;
|
|
3489
|
+
const inc = (_a = v.props.includes_for_buttons) != null ? _a : {};
|
|
3490
|
+
const exc = (_b = v.props.excludes_for_buttons) != null ? _b : {};
|
|
3491
|
+
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;
|
|
3492
|
+
}
|
|
3493
|
+
function collectSelectableTriggersInContext(v, tagId, selectedKeys, onlyEffectful) {
|
|
3494
|
+
var _a;
|
|
3495
|
+
const visible = visibleFieldsUnder(v.props, tagId, {
|
|
3496
|
+
selectedKeys
|
|
3497
|
+
});
|
|
3498
|
+
const triggers = [];
|
|
3499
|
+
for (const f of visible) {
|
|
3500
|
+
if (f.button === true) {
|
|
3501
|
+
const t = f.id;
|
|
3502
|
+
if (!onlyEffectful || isEffectfulTrigger(v, t)) triggers.push(t);
|
|
3503
|
+
}
|
|
3504
|
+
for (const o of (_a = f.options) != null ? _a : []) {
|
|
3505
|
+
const t = `${f.id}::${o.id}`;
|
|
3506
|
+
if (!onlyEffectful || isEffectfulTrigger(v, t)) triggers.push(t);
|
|
3507
|
+
}
|
|
3508
|
+
}
|
|
3509
|
+
triggers.sort();
|
|
3510
|
+
return triggers;
|
|
3511
|
+
}
|
|
3512
|
+
function runVisibilityRulesOnce(v) {
|
|
3337
3513
|
var _a, _b, _c, _d, _e;
|
|
3338
3514
|
for (const t of v.tags) {
|
|
3339
3515
|
const visible = v.fieldsVisibleUnder(t.id);
|
|
@@ -3408,12 +3584,85 @@ function validateVisibility(v) {
|
|
|
3408
3584
|
}
|
|
3409
3585
|
}
|
|
3410
3586
|
}
|
|
3587
|
+
function dedupeErrorsInPlace(v, startIndex) {
|
|
3588
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3589
|
+
const keyOfErr = (e) => {
|
|
3590
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
3591
|
+
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 : "";
|
|
3592
|
+
const other = (_g = (_f = e == null ? void 0 : e.details) == null ? void 0 : _f.other) != null ? _g : "";
|
|
3593
|
+
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 : ""}`;
|
|
3594
|
+
};
|
|
3595
|
+
const kept = [];
|
|
3596
|
+
for (let i = startIndex; i < v.errors.length; i++) {
|
|
3597
|
+
const e = v.errors[i];
|
|
3598
|
+
const k = keyOfErr(e);
|
|
3599
|
+
if (seen.has(k)) continue;
|
|
3600
|
+
seen.add(k);
|
|
3601
|
+
kept.push(e);
|
|
3602
|
+
}
|
|
3603
|
+
v.errors.splice(startIndex, v.errors.length - startIndex, ...kept);
|
|
3604
|
+
}
|
|
3605
|
+
function validateVisibility(v, options = {}) {
|
|
3606
|
+
var _a, _b, _c;
|
|
3607
|
+
const simulate = options.simulate === true;
|
|
3608
|
+
if (!simulate) {
|
|
3609
|
+
runVisibilityRulesOnce(v);
|
|
3610
|
+
return;
|
|
3611
|
+
}
|
|
3612
|
+
const maxStates = Math.max(1, (_a = options.maxStates) != null ? _a : 500);
|
|
3613
|
+
const maxDepth = Math.max(0, (_b = options.maxDepth) != null ? _b : 6);
|
|
3614
|
+
const onlyEffectful = options.onlyEffectfulTriggers !== false;
|
|
3615
|
+
const roots = resolveRootTags(v.tags);
|
|
3616
|
+
const rootTags = options.simulateAllRoots ? roots : roots.slice(0, 1);
|
|
3617
|
+
const originalSelected = new Set((_c = v.selectedKeys) != null ? _c : []);
|
|
3618
|
+
const errorsStart = v.errors.length;
|
|
3619
|
+
const visited = /* @__PURE__ */ new Set();
|
|
3620
|
+
const stack = [];
|
|
3621
|
+
for (const rt of rootTags) {
|
|
3622
|
+
stack.push({
|
|
3623
|
+
rootTagId: rt.id,
|
|
3624
|
+
selected: new Set(originalSelected),
|
|
3625
|
+
depth: 0
|
|
3626
|
+
});
|
|
3627
|
+
}
|
|
3628
|
+
let validatedStates = 0;
|
|
3629
|
+
while (stack.length) {
|
|
3630
|
+
if (validatedStates >= maxStates) break;
|
|
3631
|
+
const state = stack.pop();
|
|
3632
|
+
const sig = stableKeyOfSelection(state.selected);
|
|
3633
|
+
if (visited.has(sig)) continue;
|
|
3634
|
+
visited.add(sig);
|
|
3635
|
+
v.selectedKeys = state.selected;
|
|
3636
|
+
validatedStates++;
|
|
3637
|
+
runVisibilityRulesOnce(v);
|
|
3638
|
+
if (state.depth >= maxDepth) continue;
|
|
3639
|
+
const triggers = collectSelectableTriggersInContext(
|
|
3640
|
+
v,
|
|
3641
|
+
state.rootTagId,
|
|
3642
|
+
state.selected,
|
|
3643
|
+
onlyEffectful
|
|
3644
|
+
);
|
|
3645
|
+
for (let i = triggers.length - 1; i >= 0; i--) {
|
|
3646
|
+
const trig = triggers[i];
|
|
3647
|
+
if (state.selected.has(trig)) continue;
|
|
3648
|
+
const next = new Set(state.selected);
|
|
3649
|
+
next.add(trig);
|
|
3650
|
+
stack.push({
|
|
3651
|
+
rootTagId: state.rootTagId,
|
|
3652
|
+
selected: next,
|
|
3653
|
+
depth: state.depth + 1
|
|
3654
|
+
});
|
|
3655
|
+
}
|
|
3656
|
+
}
|
|
3657
|
+
v.selectedKeys = originalSelected;
|
|
3658
|
+
dedupeErrorsInPlace(v, errorsStart);
|
|
3659
|
+
}
|
|
3411
3660
|
|
|
3412
3661
|
// src/core/validate/steps/structure.ts
|
|
3413
3662
|
function validateStructure(v) {
|
|
3414
3663
|
const tags = v.tags;
|
|
3415
3664
|
const fields = v.fields;
|
|
3416
|
-
if (!tags.some((t) => t.id === "root")) {
|
|
3665
|
+
if (!tags.some((t) => t.id === "t:root")) {
|
|
3417
3666
|
v.errors.push({
|
|
3418
3667
|
code: "root_missing",
|
|
3419
3668
|
severity: "error",
|
|
@@ -3603,58 +3852,91 @@ function validateIdentity(v) {
|
|
|
3603
3852
|
}
|
|
3604
3853
|
|
|
3605
3854
|
// src/core/validate/steps/option-maps.ts
|
|
3855
|
+
function parseFieldOptionKey(key) {
|
|
3856
|
+
const idx = key.indexOf("::");
|
|
3857
|
+
if (idx === -1) return null;
|
|
3858
|
+
const fieldId = key.slice(0, idx).trim();
|
|
3859
|
+
const optionId = key.slice(idx + 2).trim();
|
|
3860
|
+
if (!fieldId || !optionId) return null;
|
|
3861
|
+
return { fieldId, optionId };
|
|
3862
|
+
}
|
|
3863
|
+
function hasOption(v, fid, oid) {
|
|
3864
|
+
var _a;
|
|
3865
|
+
const f = v.fieldById.get(fid);
|
|
3866
|
+
if (!f) return false;
|
|
3867
|
+
return !!((_a = f.options) != null ? _a : []).find((o) => o.id === oid);
|
|
3868
|
+
}
|
|
3606
3869
|
function validateOptionMaps(v) {
|
|
3607
3870
|
var _a, _b;
|
|
3608
3871
|
const incMap = (_a = v.props.includes_for_buttons) != null ? _a : {};
|
|
3609
3872
|
const excMap = (_b = v.props.excludes_for_buttons) != null ? _b : {};
|
|
3610
|
-
const
|
|
3611
|
-
|
|
3612
|
-
const
|
|
3613
|
-
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
|
|
3617
|
-
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
|
|
3621
|
-
|
|
3873
|
+
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.`;
|
|
3874
|
+
const validateTriggerKey = (key) => {
|
|
3875
|
+
const ref = v.nodeMap.get(key);
|
|
3876
|
+
if (ref) {
|
|
3877
|
+
if (ref.kind === "option") {
|
|
3878
|
+
return {
|
|
3879
|
+
ok: true,
|
|
3880
|
+
nodeId: ref.fieldId,
|
|
3881
|
+
affected: [ref.fieldId, ref.id]
|
|
3882
|
+
};
|
|
3883
|
+
}
|
|
3884
|
+
if (ref.kind === "field") {
|
|
3885
|
+
const isButton = ref.node.button === true;
|
|
3886
|
+
if (!isButton)
|
|
3887
|
+
return { ok: false, nodeId: ref.id, affected: [ref.id] };
|
|
3888
|
+
return { ok: true, nodeId: ref.id, affected: [ref.id] };
|
|
3889
|
+
}
|
|
3890
|
+
return { ok: false, nodeId: ref.id, affected: [ref.id] };
|
|
3891
|
+
}
|
|
3892
|
+
const p = parseFieldOptionKey(key);
|
|
3893
|
+
if (!p) return { ok: false };
|
|
3894
|
+
if (!hasOption(v, p.fieldId, p.optionId))
|
|
3895
|
+
return {
|
|
3896
|
+
ok: false,
|
|
3897
|
+
nodeId: p.fieldId,
|
|
3898
|
+
affected: [p.fieldId, p.optionId]
|
|
3899
|
+
};
|
|
3900
|
+
return {
|
|
3901
|
+
ok: true,
|
|
3902
|
+
nodeId: p.fieldId,
|
|
3903
|
+
affected: [p.fieldId, p.optionId]
|
|
3904
|
+
};
|
|
3622
3905
|
};
|
|
3623
|
-
const badKeyMessage = (key) => `Invalid option-map key "${key}". Expected "fieldId::optionId" pointing to an existing option.`;
|
|
3624
3906
|
for (const k of Object.keys(incMap)) {
|
|
3625
|
-
const
|
|
3626
|
-
if (!
|
|
3907
|
+
const r = validateTriggerKey(k);
|
|
3908
|
+
if (!r.ok) {
|
|
3627
3909
|
v.errors.push({
|
|
3628
3910
|
code: "bad_option_key",
|
|
3629
3911
|
severity: "error",
|
|
3630
3912
|
message: badKeyMessage(k),
|
|
3631
|
-
|
|
3913
|
+
nodeId: r.nodeId,
|
|
3914
|
+
details: withAffected({ key: k }, r.affected)
|
|
3632
3915
|
});
|
|
3633
3916
|
}
|
|
3634
3917
|
}
|
|
3635
3918
|
for (const k of Object.keys(excMap)) {
|
|
3636
|
-
const
|
|
3637
|
-
if (!
|
|
3919
|
+
const r = validateTriggerKey(k);
|
|
3920
|
+
if (!r.ok) {
|
|
3638
3921
|
v.errors.push({
|
|
3639
3922
|
code: "bad_option_key",
|
|
3640
3923
|
severity: "error",
|
|
3641
3924
|
message: badKeyMessage(k),
|
|
3642
|
-
|
|
3925
|
+
nodeId: r.nodeId,
|
|
3926
|
+
details: withAffected({ key: k }, r.affected)
|
|
3643
3927
|
});
|
|
3644
3928
|
}
|
|
3645
3929
|
}
|
|
3646
3930
|
for (const k of Object.keys(incMap)) {
|
|
3647
|
-
if (k in excMap)
|
|
3648
|
-
|
|
3649
|
-
|
|
3650
|
-
|
|
3651
|
-
|
|
3652
|
-
|
|
3653
|
-
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
|
-
});
|
|
3657
|
-
}
|
|
3931
|
+
if (!(k in excMap)) continue;
|
|
3932
|
+
const r = validateTriggerKey(k);
|
|
3933
|
+
v.errors.push({
|
|
3934
|
+
code: "option_include_exclude_conflict",
|
|
3935
|
+
severity: "error",
|
|
3936
|
+
message: `Trigger-map key "${k}" appears in both includes_for_buttons and excludes_for_buttons.`,
|
|
3937
|
+
nodeId: r.nodeId,
|
|
3938
|
+
details: withAffected({ key: k }, r.affected)
|
|
3939
|
+
});
|
|
3658
3940
|
}
|
|
3659
3941
|
}
|
|
3660
3942
|
|
|
@@ -4559,8 +4841,23 @@ function applyPolicies(errors, props, serviceMap, policies, fieldsVisibleUnder,
|
|
|
4559
4841
|
}
|
|
4560
4842
|
|
|
4561
4843
|
// src/core/validate/index.ts
|
|
4844
|
+
function readVisibilitySimOpts(ctx) {
|
|
4845
|
+
const c = ctx;
|
|
4846
|
+
const simulate = c.simulateVisibility === true || c.visibilitySimulate === true || c.simulate === true;
|
|
4847
|
+
const maxStates = typeof c.maxVisibilityStates === "number" ? c.maxVisibilityStates : typeof c.visibilityMaxStates === "number" ? c.visibilityMaxStates : typeof c.maxStates === "number" ? c.maxStates : void 0;
|
|
4848
|
+
const maxDepth = typeof c.maxVisibilityDepth === "number" ? c.maxVisibilityDepth : typeof c.visibilityMaxDepth === "number" ? c.visibilityMaxDepth : typeof c.maxDepth === "number" ? c.maxDepth : void 0;
|
|
4849
|
+
const simulateAllRoots = c.simulateAllRoots === true || c.visibilitySimulateAllRoots === true;
|
|
4850
|
+
const onlyEffectfulTriggers = c.onlyEffectfulTriggers === false ? false : c.visibilityOnlyEffectfulTriggers !== false;
|
|
4851
|
+
return {
|
|
4852
|
+
simulate,
|
|
4853
|
+
maxStates,
|
|
4854
|
+
maxDepth,
|
|
4855
|
+
simulateAllRoots,
|
|
4856
|
+
onlyEffectfulTriggers
|
|
4857
|
+
};
|
|
4858
|
+
}
|
|
4562
4859
|
function validate(props, ctx = {}) {
|
|
4563
|
-
var _a, _b;
|
|
4860
|
+
var _a, _b, _c;
|
|
4564
4861
|
const errors = [];
|
|
4565
4862
|
const serviceMap = (_a = ctx.serviceMap) != null ? _a : {};
|
|
4566
4863
|
const selectedKeys = new Set(
|
|
@@ -4574,6 +4871,7 @@ function validate(props, ctx = {}) {
|
|
|
4574
4871
|
for (const f of fields) fieldById.set(f.id, f);
|
|
4575
4872
|
const v = {
|
|
4576
4873
|
props,
|
|
4874
|
+
nodeMap: (_c = ctx.nodeMap) != null ? _c : buildNodeMap(props),
|
|
4577
4875
|
options: ctx,
|
|
4578
4876
|
errors,
|
|
4579
4877
|
serviceMap,
|
|
@@ -4588,7 +4886,8 @@ function validate(props, ctx = {}) {
|
|
|
4588
4886
|
validateIdentity(v);
|
|
4589
4887
|
validateOptionMaps(v);
|
|
4590
4888
|
v.fieldsVisibleUnder = createFieldsVisibleUnder(v);
|
|
4591
|
-
|
|
4889
|
+
const visSim = readVisibilitySimOpts(ctx);
|
|
4890
|
+
validateVisibility(v, visSim);
|
|
4592
4891
|
applyPolicies(
|
|
4593
4892
|
v.errors,
|
|
4594
4893
|
v.props,
|
|
@@ -4624,11 +4923,21 @@ var BuilderImpl = class {
|
|
|
4624
4923
|
this.optionOwnerById = /* @__PURE__ */ new Map();
|
|
4625
4924
|
this.history = [];
|
|
4626
4925
|
this.future = [];
|
|
4926
|
+
this._nodemap = null;
|
|
4627
4927
|
var _a;
|
|
4628
4928
|
this.options = { ...opts };
|
|
4629
4929
|
this.historyLimit = (_a = opts.historyLimit) != null ? _a : 50;
|
|
4630
4930
|
}
|
|
4631
4931
|
/* ───── lifecycle ─────────────────────────────────────────────────────── */
|
|
4932
|
+
isTagId(id) {
|
|
4933
|
+
return this.tagById.has(id);
|
|
4934
|
+
}
|
|
4935
|
+
isFieldId(id) {
|
|
4936
|
+
return this.fieldById.has(id);
|
|
4937
|
+
}
|
|
4938
|
+
isOptionId(id) {
|
|
4939
|
+
return this.optionOwnerById.has(id);
|
|
4940
|
+
}
|
|
4632
4941
|
load(raw) {
|
|
4633
4942
|
const next = normalise(raw, {
|
|
4634
4943
|
defaultPricingRole: "base",
|
|
@@ -4848,129 +5157,16 @@ var BuilderImpl = class {
|
|
|
4848
5157
|
return validate(this.props, this.options);
|
|
4849
5158
|
}
|
|
4850
5159
|
visibleFields(tagId, selectedKeys) {
|
|
4851
|
-
var _a
|
|
4852
|
-
|
|
4853
|
-
|
|
4854
|
-
|
|
4855
|
-
|
|
4856
|
-
|
|
4857
|
-
|
|
4858
|
-
|
|
4859
|
-
|
|
4860
|
-
|
|
4861
|
-
let cur = tag;
|
|
4862
|
-
let d = 0;
|
|
4863
|
-
while (cur && !guard.has(cur.id)) {
|
|
4864
|
-
lineageDepth.set(cur.id, d++);
|
|
4865
|
-
guard.add(cur.id);
|
|
4866
|
-
const parentId = cur.bind_id;
|
|
4867
|
-
cur = parentId ? tagById.get(parentId) : void 0;
|
|
4868
|
-
}
|
|
4869
|
-
}
|
|
4870
|
-
const isTagInLineage = (id) => lineageDepth.has(id);
|
|
4871
|
-
const fieldById = new Map(fields.map((f) => [f.id, f]));
|
|
4872
|
-
const optionOwnerFieldId = /* @__PURE__ */ new Map();
|
|
4873
|
-
for (const f of fields) {
|
|
4874
|
-
for (const o of (_c = f.options) != null ? _c : []) optionOwnerFieldId.set(o.id, f.id);
|
|
4875
|
-
}
|
|
4876
|
-
const ownerDepthForField = (f) => {
|
|
4877
|
-
const b = f.bind_id;
|
|
4878
|
-
if (!b) return void 0;
|
|
4879
|
-
if (typeof b === "string") return lineageDepth.get(b);
|
|
4880
|
-
let best = void 0;
|
|
4881
|
-
for (const id of b) {
|
|
4882
|
-
const d = lineageDepth.get(id);
|
|
4883
|
-
if (d == null) continue;
|
|
4884
|
-
if (best == null || d < best) best = d;
|
|
4885
|
-
}
|
|
4886
|
-
return best;
|
|
4887
|
-
};
|
|
4888
|
-
const ownerDepthForTrigger = (triggerId) => {
|
|
4889
|
-
if (triggerId.startsWith("o:")) {
|
|
4890
|
-
const fid = optionOwnerFieldId.get(triggerId);
|
|
4891
|
-
if (!fid) return void 0;
|
|
4892
|
-
const f2 = fieldById.get(fid);
|
|
4893
|
-
if (!f2) return void 0;
|
|
4894
|
-
return ownerDepthForField(f2);
|
|
4895
|
-
}
|
|
4896
|
-
const f = fieldById.get(triggerId);
|
|
4897
|
-
if (!f || f.button !== true) return void 0;
|
|
4898
|
-
return ownerDepthForField(f);
|
|
4899
|
-
};
|
|
4900
|
-
const tagInclude = new Set((_d = tag.includes) != null ? _d : []);
|
|
4901
|
-
const tagExclude = new Set((_e = tag.excludes) != null ? _e : []);
|
|
4902
|
-
const selected = new Set(
|
|
4903
|
-
(_f = selectedKeys != null ? selectedKeys : this.options.selectedOptionKeys) != null ? _f : []
|
|
4904
|
-
);
|
|
4905
|
-
const incMap = (_g = props.includes_for_buttons) != null ? _g : {};
|
|
4906
|
-
const excMap = (_h = props.excludes_for_buttons) != null ? _h : {};
|
|
4907
|
-
const relevantTriggersInOrder = [];
|
|
4908
|
-
for (const key of selected) {
|
|
4909
|
-
const d = ownerDepthForTrigger(key);
|
|
4910
|
-
if (d == null) continue;
|
|
4911
|
-
relevantTriggersInOrder.push(key);
|
|
4912
|
-
}
|
|
4913
|
-
const visible = /* @__PURE__ */ new Set();
|
|
4914
|
-
const isBoundToLineage = (f) => {
|
|
4915
|
-
const b = f.bind_id;
|
|
4916
|
-
if (!b) return false;
|
|
4917
|
-
if (typeof b === "string") return isTagInLineage(b);
|
|
4918
|
-
for (const id of b) if (isTagInLineage(id)) return true;
|
|
4919
|
-
return false;
|
|
4920
|
-
};
|
|
4921
|
-
for (const f of fields) {
|
|
4922
|
-
if (isBoundToLineage(f)) visible.add(f.id);
|
|
4923
|
-
if (tagInclude.has(f.id)) visible.add(f.id);
|
|
4924
|
-
}
|
|
4925
|
-
for (const id of tagExclude) visible.delete(id);
|
|
4926
|
-
const decide = /* @__PURE__ */ new Map();
|
|
4927
|
-
const applyDecision = (fieldId, next) => {
|
|
4928
|
-
const prev = decide.get(fieldId);
|
|
4929
|
-
if (!prev) {
|
|
4930
|
-
decide.set(fieldId, next);
|
|
4931
|
-
return;
|
|
4932
|
-
}
|
|
4933
|
-
if (next.depth < prev.depth) {
|
|
4934
|
-
decide.set(fieldId, next);
|
|
4935
|
-
return;
|
|
4936
|
-
}
|
|
4937
|
-
if (next.depth > prev.depth) return;
|
|
4938
|
-
if (prev.kind === "include" && next.kind === "exclude") {
|
|
4939
|
-
decide.set(fieldId, next);
|
|
4940
|
-
}
|
|
4941
|
-
};
|
|
4942
|
-
const revealedOrder = [];
|
|
4943
|
-
const revealedSeen = /* @__PURE__ */ new Set();
|
|
4944
|
-
for (const triggerId of relevantTriggersInOrder) {
|
|
4945
|
-
const depth = ownerDepthForTrigger(triggerId);
|
|
4946
|
-
if (depth == null) continue;
|
|
4947
|
-
for (const id of (_i = incMap[triggerId]) != null ? _i : []) {
|
|
4948
|
-
applyDecision(id, { depth, kind: "include" });
|
|
4949
|
-
if (!revealedSeen.has(id)) {
|
|
4950
|
-
revealedSeen.add(id);
|
|
4951
|
-
revealedOrder.push(id);
|
|
4952
|
-
}
|
|
4953
|
-
}
|
|
4954
|
-
for (const id of (_j = excMap[triggerId]) != null ? _j : []) {
|
|
4955
|
-
applyDecision(id, { depth, kind: "exclude" });
|
|
4956
|
-
}
|
|
4957
|
-
}
|
|
4958
|
-
for (const [fid, d] of decide) {
|
|
4959
|
-
if (d.kind === "include") visible.add(fid);
|
|
4960
|
-
else visible.delete(fid);
|
|
4961
|
-
}
|
|
4962
|
-
const base = fields.filter((f) => visible.has(f.id)).map((f) => f.id);
|
|
4963
|
-
const order = (_k = props.order_for_tags) == null ? void 0 : _k[tagId];
|
|
4964
|
-
if (order && order.length) {
|
|
4965
|
-
const ordered = order.filter((fid) => visible.has(fid));
|
|
4966
|
-
const orderedSet = new Set(ordered);
|
|
4967
|
-
const rest2 = base.filter((fid) => !orderedSet.has(fid));
|
|
4968
|
-
return [...ordered, ...rest2];
|
|
4969
|
-
}
|
|
4970
|
-
const promoted = revealedOrder.filter((fid) => visible.has(fid));
|
|
4971
|
-
const promotedSet = new Set(promoted);
|
|
4972
|
-
const rest = base.filter((fid) => !promotedSet.has(fid));
|
|
4973
|
-
return [...promoted, ...rest];
|
|
5160
|
+
var _a;
|
|
5161
|
+
return visibleFieldIdsUnder(this.props, tagId, {
|
|
5162
|
+
selectedKeys: new Set(
|
|
5163
|
+
(_a = selectedKeys != null ? selectedKeys : this.options.selectedOptionKeys) != null ? _a : []
|
|
5164
|
+
)
|
|
5165
|
+
});
|
|
5166
|
+
}
|
|
5167
|
+
getNodeMap() {
|
|
5168
|
+
if (!this._nodemap) this._nodemap = buildNodeMap(this.getProps());
|
|
5169
|
+
return this._nodemap;
|
|
4974
5170
|
}
|
|
4975
5171
|
/* ───── history ─────────────────────────────────────────────────────── */
|
|
4976
5172
|
undo() {
|
|
@@ -4994,6 +5190,7 @@ var BuilderImpl = class {
|
|
|
4994
5190
|
this.tagById.clear();
|
|
4995
5191
|
this.fieldById.clear();
|
|
4996
5192
|
this.optionOwnerById.clear();
|
|
5193
|
+
this._nodemap = null;
|
|
4997
5194
|
for (const t of this.props.filters) this.tagById.set(t.id, t);
|
|
4998
5195
|
for (const f of this.props.fields) {
|
|
4999
5196
|
this.fieldById.set(f.id, f);
|
|
@@ -5221,6 +5418,7 @@ var toBindList = (b) => {
|
|
|
5221
5418
|
function createNodeIndex(builder) {
|
|
5222
5419
|
var _a, _b, _c, _d;
|
|
5223
5420
|
const props = builder.getProps();
|
|
5421
|
+
const nodeMap = builder.getNodeMap();
|
|
5224
5422
|
const tags = (_a = props.filters) != null ? _a : [];
|
|
5225
5423
|
const fields = (_b = props.fields) != null ? _b : [];
|
|
5226
5424
|
const tagById = new Map(tags.map((t) => [t.id, t]));
|
|
@@ -5424,7 +5622,9 @@ function createNodeIndex(builder) {
|
|
|
5424
5622
|
return parentById.get(id) === tid;
|
|
5425
5623
|
},
|
|
5426
5624
|
getDescendant(descendantId) {
|
|
5427
|
-
return this.getDescendants().find(
|
|
5625
|
+
return this.getDescendants().find(
|
|
5626
|
+
(item) => item.id == descendantId
|
|
5627
|
+
);
|
|
5428
5628
|
},
|
|
5429
5629
|
getDescendants() {
|
|
5430
5630
|
const results = [];
|
|
@@ -5433,7 +5633,9 @@ function createNodeIndex(builder) {
|
|
|
5433
5633
|
const node2 = getField(fieldId);
|
|
5434
5634
|
if (!node2) continue;
|
|
5435
5635
|
const explicit = includes.has(fieldId) || isFieldBoundDirectToTag(fieldId, id);
|
|
5436
|
-
results.push(
|
|
5636
|
+
results.push(
|
|
5637
|
+
explicit ? node2 : { ...node2, isInherited: true }
|
|
5638
|
+
);
|
|
5437
5639
|
}
|
|
5438
5640
|
return Object.freeze(results);
|
|
5439
5641
|
}
|
|
@@ -5482,7 +5684,9 @@ function createNodeIndex(builder) {
|
|
|
5482
5684
|
return false;
|
|
5483
5685
|
},
|
|
5484
5686
|
getDescendant(descendantId, context) {
|
|
5485
|
-
return this.getDescendants(context).find(
|
|
5687
|
+
return this.getDescendants(context).find(
|
|
5688
|
+
(item) => item.id == descendantId
|
|
5689
|
+
);
|
|
5486
5690
|
},
|
|
5487
5691
|
getDescendants(tagId) {
|
|
5488
5692
|
return resolveDescendants(id, includes, tagId, !isButton);
|
|
@@ -5524,7 +5728,9 @@ function createNodeIndex(builder) {
|
|
|
5524
5728
|
return owner.isBoundTo(tagId);
|
|
5525
5729
|
},
|
|
5526
5730
|
getDescendant(descendantId, context) {
|
|
5527
|
-
return this.getDescendants(context).find(
|
|
5731
|
+
return this.getDescendants(context).find(
|
|
5732
|
+
(item) => item.id == descendantId
|
|
5733
|
+
);
|
|
5528
5734
|
},
|
|
5529
5735
|
getDescendants(tagId) {
|
|
5530
5736
|
return resolveDescendants(id, includes, tagId);
|
|
@@ -5535,7 +5741,7 @@ function createNodeIndex(builder) {
|
|
|
5535
5741
|
return node;
|
|
5536
5742
|
};
|
|
5537
5743
|
const getNode = (input) => {
|
|
5538
|
-
var _a2, _b2, _c2, _d2, _e
|
|
5744
|
+
var _a2, _b2, _c2, _d2, _e;
|
|
5539
5745
|
if (typeof input !== "string") {
|
|
5540
5746
|
if ("bind_id" in input && !("type" in input))
|
|
5541
5747
|
return (_a2 = getTag(input.id)) != null ? _a2 : mkUnknown(input.id);
|
|
@@ -5545,11 +5751,7 @@ function createNodeIndex(builder) {
|
|
|
5545
5751
|
}
|
|
5546
5752
|
const cached = nodeCache.get(input);
|
|
5547
5753
|
if (cached) return cached;
|
|
5548
|
-
|
|
5549
|
-
if (id.startsWith("t:")) return (_d2 = getTag(id)) != null ? _d2 : mkUnknown(id);
|
|
5550
|
-
if (id.startsWith("f:")) return (_e = getField(id)) != null ? _e : mkUnknown(id);
|
|
5551
|
-
if (id.startsWith("o:")) return (_f = getOption(id)) != null ? _f : mkUnknown(id);
|
|
5552
|
-
return (_i = (_h = (_g = getTag(id)) != null ? _g : getField(id)) != null ? _h : getOption(id)) != null ? _i : mkUnknown(id);
|
|
5754
|
+
return (_e = (_d2 = nodeMap.get(input)) == null ? void 0 : _d2.node) != null ? _e : mkUnknown(input);
|
|
5553
5755
|
};
|
|
5554
5756
|
const mkUnknown = (id) => {
|
|
5555
5757
|
const u = {
|
|
@@ -5609,9 +5811,6 @@ function rateOk(svcMap, candidate, primary, policy) {
|
|
|
5609
5811
|
|
|
5610
5812
|
// src/react/canvas/editor.ts
|
|
5611
5813
|
var MAX_LIMIT = 100;
|
|
5612
|
-
var isTagId = (id) => id.startsWith("t:");
|
|
5613
|
-
var isFieldId = (id) => id.startsWith("f:");
|
|
5614
|
-
var isOptionId = (id) => id.startsWith("o:");
|
|
5615
5814
|
function ownerOfOption(props, optionId) {
|
|
5616
5815
|
var _a, _b;
|
|
5617
5816
|
for (const f of (_a = props.fields) != null ? _a : []) {
|
|
@@ -5653,6 +5852,15 @@ var Editor = class {
|
|
|
5653
5852
|
this.pushHistory(this.makeSnapshot("init"));
|
|
5654
5853
|
}
|
|
5655
5854
|
/* ───────────────────────── Public API ───────────────────────── */
|
|
5855
|
+
isTagId(id) {
|
|
5856
|
+
return this.builder.isTagId(id);
|
|
5857
|
+
}
|
|
5858
|
+
isFieldId(id) {
|
|
5859
|
+
return this.builder.isFieldId(id);
|
|
5860
|
+
}
|
|
5861
|
+
isOptionId(id) {
|
|
5862
|
+
return this.builder.isOptionId(id);
|
|
5863
|
+
}
|
|
5656
5864
|
getProps() {
|
|
5657
5865
|
return this.builder.getProps();
|
|
5658
5866
|
}
|
|
@@ -5748,7 +5956,7 @@ var Editor = class {
|
|
|
5748
5956
|
name: "reLabel",
|
|
5749
5957
|
do: () => this.patchProps((p) => {
|
|
5750
5958
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
5751
|
-
if (isTagId(id)) {
|
|
5959
|
+
if (this.isTagId(id)) {
|
|
5752
5960
|
const t = ((_a = p.filters) != null ? _a : []).find((x) => x.id === id);
|
|
5753
5961
|
if (!t) return;
|
|
5754
5962
|
if (((_b = t.label) != null ? _b : "") === label) return;
|
|
@@ -5756,7 +5964,7 @@ var Editor = class {
|
|
|
5756
5964
|
this.api.refreshGraph();
|
|
5757
5965
|
return;
|
|
5758
5966
|
}
|
|
5759
|
-
if (isOptionId(id)) {
|
|
5967
|
+
if (this.isOptionId(id)) {
|
|
5760
5968
|
const own = ownerOfOption(p, id);
|
|
5761
5969
|
if (!own) return;
|
|
5762
5970
|
const f = ((_c = p.fields) != null ? _c : []).find(
|
|
@@ -6057,7 +6265,7 @@ var Editor = class {
|
|
|
6057
6265
|
* - Option: use placeOption() instead
|
|
6058
6266
|
*/
|
|
6059
6267
|
placeNode(id, opts) {
|
|
6060
|
-
if (isTagId(id)) {
|
|
6268
|
+
if (this.isTagId(id)) {
|
|
6061
6269
|
this.exec({
|
|
6062
6270
|
name: "placeTag",
|
|
6063
6271
|
do: () => this.patchProps((p) => {
|
|
@@ -6104,7 +6312,7 @@ var Editor = class {
|
|
|
6104
6312
|
}),
|
|
6105
6313
|
undo: () => this.api.undo()
|
|
6106
6314
|
});
|
|
6107
|
-
} else if (isFieldId(id)) {
|
|
6315
|
+
} else if (this.isFieldId(id)) {
|
|
6108
6316
|
if (!opts.scopeTagId)
|
|
6109
6317
|
throw new Error("placeNode(field): scopeTagId is required");
|
|
6110
6318
|
const fieldId = id;
|
|
@@ -6131,14 +6339,14 @@ var Editor = class {
|
|
|
6131
6339
|
}),
|
|
6132
6340
|
undo: () => this.api.undo()
|
|
6133
6341
|
});
|
|
6134
|
-
} else if (isOptionId(id)) {
|
|
6342
|
+
} else if (this.isOptionId(id)) {
|
|
6135
6343
|
this.placeOption(id, opts);
|
|
6136
6344
|
} else {
|
|
6137
6345
|
throw new Error("placeNode: unknown id prefix");
|
|
6138
6346
|
}
|
|
6139
6347
|
}
|
|
6140
6348
|
placeOption(optionId, opts) {
|
|
6141
|
-
if (!isOptionId(optionId))
|
|
6349
|
+
if (!this.isOptionId(optionId))
|
|
6142
6350
|
throw new Error('placeOption: optionId must start with "o:"');
|
|
6143
6351
|
this.exec({
|
|
6144
6352
|
name: "placeOption",
|
|
@@ -6195,7 +6403,7 @@ var Editor = class {
|
|
|
6195
6403
|
return id;
|
|
6196
6404
|
}
|
|
6197
6405
|
updateOption(optionId, patch) {
|
|
6198
|
-
if (!isOptionId(optionId))
|
|
6406
|
+
if (!this.isOptionId(optionId))
|
|
6199
6407
|
throw new Error('updateOption: optionId must start with "o:"');
|
|
6200
6408
|
this.exec({
|
|
6201
6409
|
name: "updateOption",
|
|
@@ -6214,7 +6422,7 @@ var Editor = class {
|
|
|
6214
6422
|
});
|
|
6215
6423
|
}
|
|
6216
6424
|
removeOption(optionId) {
|
|
6217
|
-
if (!isOptionId(optionId))
|
|
6425
|
+
if (!this.isOptionId(optionId))
|
|
6218
6426
|
throw new Error('removeOption: optionId must start with "o:"');
|
|
6219
6427
|
this.exec({
|
|
6220
6428
|
name: "removeOption",
|
|
@@ -6245,17 +6453,17 @@ var Editor = class {
|
|
|
6245
6453
|
name: "editLabel",
|
|
6246
6454
|
do: () => this.patchProps((p) => {
|
|
6247
6455
|
var _a, _b, _c, _d;
|
|
6248
|
-
if (isTagId(id)) {
|
|
6456
|
+
if (this.isTagId(id)) {
|
|
6249
6457
|
const t = ((_a = p.filters) != null ? _a : []).find((x) => x.id === id);
|
|
6250
6458
|
if (t) t.label = next;
|
|
6251
6459
|
return;
|
|
6252
6460
|
}
|
|
6253
|
-
if (isFieldId(id)) {
|
|
6461
|
+
if (this.isFieldId(id)) {
|
|
6254
6462
|
const f = ((_b = p.fields) != null ? _b : []).find((x) => x.id === id);
|
|
6255
6463
|
if (f) f.label = next;
|
|
6256
6464
|
return;
|
|
6257
6465
|
}
|
|
6258
|
-
if (isOptionId(id)) {
|
|
6466
|
+
if (this.isOptionId(id)) {
|
|
6259
6467
|
const own = ownerOfOption(p, id);
|
|
6260
6468
|
if (!own) return;
|
|
6261
6469
|
const f = ((_c = p.fields) != null ? _c : []).find(
|
|
@@ -6294,7 +6502,7 @@ var Editor = class {
|
|
|
6294
6502
|
const validId = hasSidKey && typeof input.service_id === "number" && Number.isFinite(input.service_id);
|
|
6295
6503
|
const sid = validId ? Number(input.service_id) : void 0;
|
|
6296
6504
|
const nextRole = input.pricing_role;
|
|
6297
|
-
if (isTagId(id)) {
|
|
6505
|
+
if (this.isTagId(id)) {
|
|
6298
6506
|
const t = ((_a = p.filters) != null ? _a : []).find((x) => x.id === id);
|
|
6299
6507
|
if (!t) return;
|
|
6300
6508
|
if (hasSidKey) {
|
|
@@ -6303,7 +6511,7 @@ var Editor = class {
|
|
|
6303
6511
|
}
|
|
6304
6512
|
return;
|
|
6305
6513
|
}
|
|
6306
|
-
if (isOptionId(id)) {
|
|
6514
|
+
if (this.isOptionId(id)) {
|
|
6307
6515
|
const own = ownerOfOption(p, id);
|
|
6308
6516
|
if (!own) return;
|
|
6309
6517
|
const f2 = ((_b = p.fields) != null ? _b : []).find(
|
|
@@ -6510,7 +6718,7 @@ var Editor = class {
|
|
|
6510
6718
|
});
|
|
6511
6719
|
}
|
|
6512
6720
|
remove(id) {
|
|
6513
|
-
if (isTagId(id)) {
|
|
6721
|
+
if (this.isTagId(id)) {
|
|
6514
6722
|
this.exec({
|
|
6515
6723
|
name: "removeTag",
|
|
6516
6724
|
do: () => this.patchProps((p) => {
|
|
@@ -6550,7 +6758,7 @@ var Editor = class {
|
|
|
6550
6758
|
});
|
|
6551
6759
|
return;
|
|
6552
6760
|
}
|
|
6553
|
-
if (isFieldId(id)) {
|
|
6761
|
+
if (this.isFieldId(id)) {
|
|
6554
6762
|
this.exec({
|
|
6555
6763
|
name: "removeField",
|
|
6556
6764
|
do: () => this.patchProps((p) => {
|
|
@@ -6586,7 +6794,7 @@ var Editor = class {
|
|
|
6586
6794
|
});
|
|
6587
6795
|
return;
|
|
6588
6796
|
}
|
|
6589
|
-
if (isOptionId(id)) {
|
|
6797
|
+
if (this.isOptionId(id)) {
|
|
6590
6798
|
this.removeOption(id);
|
|
6591
6799
|
return;
|
|
6592
6800
|
}
|
|
@@ -6595,7 +6803,7 @@ var Editor = class {
|
|
|
6595
6803
|
getNode(id) {
|
|
6596
6804
|
var _a, _b, _c, _d;
|
|
6597
6805
|
const props = this.builder.getProps();
|
|
6598
|
-
if (isTagId(id)) {
|
|
6806
|
+
if (this.isTagId(id)) {
|
|
6599
6807
|
const t = ((_a = props.filters) != null ? _a : []).find((x) => x.id === id);
|
|
6600
6808
|
return {
|
|
6601
6809
|
kind: "tag",
|
|
@@ -6603,12 +6811,12 @@ var Editor = class {
|
|
|
6603
6811
|
owners: { parentTagId: t == null ? void 0 : t.bind_id }
|
|
6604
6812
|
};
|
|
6605
6813
|
}
|
|
6606
|
-
if (isFieldId(id)) {
|
|
6814
|
+
if (this.isFieldId(id)) {
|
|
6607
6815
|
const f = ((_b = props.fields) != null ? _b : []).find((x) => x.id === id);
|
|
6608
6816
|
const bind = Array.isArray(f == null ? void 0 : f.bind_id) ? f.bind_id : (f == null ? void 0 : f.bind_id) ? [f.bind_id] : [];
|
|
6609
6817
|
return { kind: "field", data: f, owners: { bindTagIds: bind } };
|
|
6610
6818
|
}
|
|
6611
|
-
if (isOptionId(id)) {
|
|
6819
|
+
if (this.isOptionId(id)) {
|
|
6612
6820
|
const own = ownerOfOption(props, id);
|
|
6613
6821
|
const f = own ? ((_c = props.fields) != null ? _c : []).find((x) => x.id === own.fieldId) : void 0;
|
|
6614
6822
|
const o = (_d = f == null ? void 0 : f.options) == null ? void 0 : _d.find((x) => x.id === id);
|
|
@@ -6686,7 +6894,7 @@ var Editor = class {
|
|
|
6686
6894
|
if (receiverId === targetId) return true;
|
|
6687
6895
|
const getDirectRelations = (id) => {
|
|
6688
6896
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
6689
|
-
if (isTagId(id)) {
|
|
6897
|
+
if (this.isTagId(id)) {
|
|
6690
6898
|
const t = ((_a = p.filters) != null ? _a : []).find((x) => x.id === id);
|
|
6691
6899
|
return [...(_b = t == null ? void 0 : t.includes) != null ? _b : [], ...(_c = t == null ? void 0 : t.excludes) != null ? _c : []];
|
|
6692
6900
|
}
|
|
@@ -6906,7 +7114,7 @@ var Editor = class {
|
|
|
6906
7114
|
do: () => this.patchProps((p) => {
|
|
6907
7115
|
var _a, _b, _c, _d, _e;
|
|
6908
7116
|
if (kind === "bind") {
|
|
6909
|
-
if (isTagId(fromId) && isTagId(toId2)) {
|
|
7117
|
+
if (this.isTagId(fromId) && this.isTagId(toId2)) {
|
|
6910
7118
|
if (this.wouldCreateTagCycle(p, fromId, toId2)) {
|
|
6911
7119
|
throw new Error(
|
|
6912
7120
|
`bind would create a cycle: ${fromId} \u2192 ${toId2}`
|
|
@@ -6918,9 +7126,9 @@ var Editor = class {
|
|
|
6918
7126
|
if (child) child.bind_id = fromId;
|
|
6919
7127
|
return;
|
|
6920
7128
|
}
|
|
6921
|
-
if (isTagId(fromId) && isFieldId(toId2) || isFieldId(fromId) && isTagId(toId2)) {
|
|
6922
|
-
const fieldId = isFieldId(toId2) ? toId2 : fromId;
|
|
6923
|
-
const tagId = isTagId(fromId) ? fromId : toId2;
|
|
7129
|
+
if (this.isTagId(fromId) && this.isFieldId(toId2) || this.isFieldId(fromId) && this.isTagId(toId2)) {
|
|
7130
|
+
const fieldId = this.isFieldId(toId2) ? toId2 : fromId;
|
|
7131
|
+
const tagId = this.isTagId(fromId) ? fromId : toId2;
|
|
6924
7132
|
const f = ((_b = p.fields) != null ? _b : []).find(
|
|
6925
7133
|
(x) => x.id === fieldId
|
|
6926
7134
|
);
|
|
@@ -6944,7 +7152,7 @@ var Editor = class {
|
|
|
6944
7152
|
}
|
|
6945
7153
|
if (kind === "include" || kind === "exclude") {
|
|
6946
7154
|
const key = kind === "include" ? "includes" : "excludes";
|
|
6947
|
-
if (isTagId(fromId) && isFieldId(toId2)) {
|
|
7155
|
+
if (this.isTagId(fromId) && this.isFieldId(toId2)) {
|
|
6948
7156
|
const t = ((_c = p.filters) != null ? _c : []).find(
|
|
6949
7157
|
(x) => x.id === fromId
|
|
6950
7158
|
);
|
|
@@ -6953,7 +7161,7 @@ var Editor = class {
|
|
|
6953
7161
|
if (!arr.includes(toId2)) arr.push(toId2);
|
|
6954
7162
|
return;
|
|
6955
7163
|
}
|
|
6956
|
-
if (isOptionId(fromId) && isFieldId(toId2)) {
|
|
7164
|
+
if (this.isOptionId(fromId) && this.isFieldId(toId2)) {
|
|
6957
7165
|
const mapKey = kind === "include" ? "includes_for_options" : "excludes_for_options";
|
|
6958
7166
|
const maps = p[mapKey];
|
|
6959
7167
|
const next = { ...maps != null ? maps : {} };
|
|
@@ -7021,16 +7229,16 @@ var Editor = class {
|
|
|
7021
7229
|
do: () => this.patchProps((p) => {
|
|
7022
7230
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
7023
7231
|
if (kind === "bind") {
|
|
7024
|
-
if (isTagId(fromId) && isTagId(toId2)) {
|
|
7232
|
+
if (this.isTagId(fromId) && this.isTagId(toId2)) {
|
|
7025
7233
|
const child = ((_a = p.filters) != null ? _a : []).find(
|
|
7026
7234
|
(t) => t.id === toId2
|
|
7027
7235
|
);
|
|
7028
7236
|
if ((child == null ? void 0 : child.bind_id) === fromId) delete child.bind_id;
|
|
7029
7237
|
return;
|
|
7030
7238
|
}
|
|
7031
|
-
if (isTagId(fromId) && isFieldId(toId2) || isFieldId(fromId) && isTagId(toId2)) {
|
|
7032
|
-
const fieldId = isFieldId(toId2) ? toId2 : fromId;
|
|
7033
|
-
const tagId = isTagId(fromId) ? fromId : toId2;
|
|
7239
|
+
if (this.isTagId(fromId) && this.isFieldId(toId2) || this.isFieldId(fromId) && this.isTagId(toId2)) {
|
|
7240
|
+
const fieldId = this.isFieldId(toId2) ? toId2 : fromId;
|
|
7241
|
+
const tagId = this.isTagId(fromId) ? fromId : toId2;
|
|
7034
7242
|
const f = ((_b = p.fields) != null ? _b : []).find(
|
|
7035
7243
|
(x) => x.id === fieldId
|
|
7036
7244
|
);
|
|
@@ -7051,7 +7259,7 @@ var Editor = class {
|
|
|
7051
7259
|
}
|
|
7052
7260
|
if (kind === "include" || kind === "exclude") {
|
|
7053
7261
|
const key = kind === "include" ? "includes" : "excludes";
|
|
7054
|
-
if (isTagId(fromId) && isFieldId(toId2)) {
|
|
7262
|
+
if (this.isTagId(fromId) && this.isFieldId(toId2)) {
|
|
7055
7263
|
const t = ((_d = p.filters) != null ? _d : []).find(
|
|
7056
7264
|
(x) => x.id === fromId
|
|
7057
7265
|
);
|
|
@@ -7060,7 +7268,7 @@ var Editor = class {
|
|
|
7060
7268
|
if (!((_f = t[key]) == null ? void 0 : _f.length)) delete t[key];
|
|
7061
7269
|
return;
|
|
7062
7270
|
}
|
|
7063
|
-
if (isOptionId(fromId) && isFieldId(toId2)) {
|
|
7271
|
+
if (this.isOptionId(fromId) && this.isFieldId(toId2)) {
|
|
7064
7272
|
const mapKey = kind === "include" ? "includes_for_options" : "excludes_for_options";
|
|
7065
7273
|
const maps = p[mapKey];
|
|
7066
7274
|
if (!maps) return;
|
|
@@ -7527,8 +7735,6 @@ function toStrSet(v) {
|
|
|
7527
7735
|
}
|
|
7528
7736
|
|
|
7529
7737
|
// src/react/canvas/selection.ts
|
|
7530
|
-
var isTagId2 = (id) => typeof id === "string" && id.startsWith("t:");
|
|
7531
|
-
var isOptionId2 = (id) => typeof id === "string" && id.startsWith("o:");
|
|
7532
7738
|
var Selection = class {
|
|
7533
7739
|
constructor(builder, opts) {
|
|
7534
7740
|
this.builder = builder;
|
|
@@ -7546,6 +7752,7 @@ var Selection = class {
|
|
|
7546
7752
|
this.emit();
|
|
7547
7753
|
}
|
|
7548
7754
|
add(id) {
|
|
7755
|
+
if (this.set.has(id)) this.set.delete(id);
|
|
7549
7756
|
this.set.add(id);
|
|
7550
7757
|
this.primaryId = id;
|
|
7551
7758
|
this.updateCurrentTagFrom(id);
|
|
@@ -7600,7 +7807,9 @@ var Selection = class {
|
|
|
7600
7807
|
var _a;
|
|
7601
7808
|
const props = this.builder.getProps();
|
|
7602
7809
|
if (((_a = this.opts.env) != null ? _a : "client") === "workspace") {
|
|
7603
|
-
const tagIds = Array.from(this.set).filter(
|
|
7810
|
+
const tagIds = Array.from(this.set).filter(
|
|
7811
|
+
this.builder.isTagId.bind(this.builder)
|
|
7812
|
+
);
|
|
7604
7813
|
if (tagIds.length > 1) {
|
|
7605
7814
|
return { kind: "multi", groups: Array.from(this.set) };
|
|
7606
7815
|
}
|
|
@@ -7611,6 +7820,98 @@ var Selection = class {
|
|
|
7611
7820
|
const group = this.computeGroupForTag(props, tagId);
|
|
7612
7821
|
return { kind: "single", group };
|
|
7613
7822
|
}
|
|
7823
|
+
/**
|
|
7824
|
+
* Build a fieldId -> triggerKeys[] map from the current selection set.
|
|
7825
|
+
*
|
|
7826
|
+
* What counts as a "button selection" (trigger key):
|
|
7827
|
+
* - field key where the field has button === true (e.g. "f:dripfeed")
|
|
7828
|
+
* - option key (e.g. "o:fast")
|
|
7829
|
+
* - composite key "fieldId::optionId" (e.g. "f:speed::o:fast")
|
|
7830
|
+
*
|
|
7831
|
+
* Grouping:
|
|
7832
|
+
* - button-field trigger groups under its own fieldId
|
|
7833
|
+
* - option/composite groups under the option's owning fieldId (from nodeMap)
|
|
7834
|
+
*
|
|
7835
|
+
* Deterministic:
|
|
7836
|
+
* - preserves selection insertion order
|
|
7837
|
+
* - de-dupes per field
|
|
7838
|
+
*/
|
|
7839
|
+
buttonSelectionsByFieldId() {
|
|
7840
|
+
var _a, _b, _c, _d, _e;
|
|
7841
|
+
const nodeMap = this.builder.getNodeMap();
|
|
7842
|
+
const out = {};
|
|
7843
|
+
const push = (fieldId, triggerKey) => {
|
|
7844
|
+
var _a2;
|
|
7845
|
+
const arr = (_a2 = out[fieldId]) != null ? _a2 : out[fieldId] = [];
|
|
7846
|
+
if (!arr.includes(triggerKey)) arr.push(triggerKey);
|
|
7847
|
+
};
|
|
7848
|
+
for (const key of this.set) {
|
|
7849
|
+
if (!key) continue;
|
|
7850
|
+
const idx = key.indexOf("::");
|
|
7851
|
+
if (idx !== -1) {
|
|
7852
|
+
const optionId = key.slice(idx + 2);
|
|
7853
|
+
const optRef = nodeMap.get(optionId);
|
|
7854
|
+
if ((optRef == null ? void 0 : optRef.kind) === "option" && typeof optRef.fieldId === "string") {
|
|
7855
|
+
push(optRef.fieldId, key);
|
|
7856
|
+
}
|
|
7857
|
+
continue;
|
|
7858
|
+
}
|
|
7859
|
+
const ref = nodeMap.get(key);
|
|
7860
|
+
if (!ref) continue;
|
|
7861
|
+
if (ref.kind === "option" && typeof ref.fieldId === "string") {
|
|
7862
|
+
push(ref.fieldId, (_a = ref.id) != null ? _a : key);
|
|
7863
|
+
continue;
|
|
7864
|
+
}
|
|
7865
|
+
if (ref.kind === "field") {
|
|
7866
|
+
const field = (_c = (_b = ref.node) != null ? _b : ref.field) != null ? _c : ref;
|
|
7867
|
+
const fieldId = (_e = (_d = ref.id) != null ? _d : field == null ? void 0 : field.id) != null ? _e : key;
|
|
7868
|
+
if ((field == null ? void 0 : field.button) === true && typeof fieldId === "string") {
|
|
7869
|
+
push(fieldId, fieldId);
|
|
7870
|
+
}
|
|
7871
|
+
}
|
|
7872
|
+
}
|
|
7873
|
+
return out;
|
|
7874
|
+
}
|
|
7875
|
+
/**
|
|
7876
|
+
* Returns only selection keys that are valid "trigger buttons":
|
|
7877
|
+
* - field keys where field.button === true
|
|
7878
|
+
* - option keys
|
|
7879
|
+
* - composite keys "fieldId::optionId" (validated by optionId)
|
|
7880
|
+
* Excludes tags and non-button fields.
|
|
7881
|
+
*/
|
|
7882
|
+
selectedButtons() {
|
|
7883
|
+
var _a, _b;
|
|
7884
|
+
const nodeMap = this.builder.getNodeMap();
|
|
7885
|
+
const out = [];
|
|
7886
|
+
const seen = /* @__PURE__ */ new Set();
|
|
7887
|
+
const push = (k) => {
|
|
7888
|
+
if (!seen.has(k)) {
|
|
7889
|
+
seen.add(k);
|
|
7890
|
+
out.push(k);
|
|
7891
|
+
}
|
|
7892
|
+
};
|
|
7893
|
+
for (const key of this.set) {
|
|
7894
|
+
if (!key) continue;
|
|
7895
|
+
const idx = key.indexOf("::");
|
|
7896
|
+
if (idx !== -1) {
|
|
7897
|
+
const optionId = key.slice(idx + 2);
|
|
7898
|
+
const optRef = nodeMap.get(optionId);
|
|
7899
|
+
if ((optRef == null ? void 0 : optRef.kind) === "option") push(key);
|
|
7900
|
+
continue;
|
|
7901
|
+
}
|
|
7902
|
+
const ref = nodeMap.get(key);
|
|
7903
|
+
if (!ref) continue;
|
|
7904
|
+
if (ref.kind === "option") {
|
|
7905
|
+
push(key);
|
|
7906
|
+
continue;
|
|
7907
|
+
}
|
|
7908
|
+
if (ref.kind === "field") {
|
|
7909
|
+
const field = (_b = (_a = ref.node) != null ? _a : ref.field) != null ? _b : ref;
|
|
7910
|
+
if ((field == null ? void 0 : field.button) === true) push(key);
|
|
7911
|
+
}
|
|
7912
|
+
}
|
|
7913
|
+
return out;
|
|
7914
|
+
}
|
|
7614
7915
|
// ── Internals ────────────────────────────────────────────────────────────
|
|
7615
7916
|
emit() {
|
|
7616
7917
|
const payload = {
|
|
@@ -7633,7 +7934,7 @@ var Selection = class {
|
|
|
7633
7934
|
this.currentTagId = Array.isArray(f.bind_id) ? f.bind_id[0] : f.bind_id;
|
|
7634
7935
|
return;
|
|
7635
7936
|
}
|
|
7636
|
-
if (
|
|
7937
|
+
if (this.builder.isOptionId(id)) {
|
|
7637
7938
|
const host = fields.find(
|
|
7638
7939
|
(x) => {
|
|
7639
7940
|
var _a2;
|
|
@@ -7657,7 +7958,7 @@ var Selection = class {
|
|
|
7657
7958
|
resolveTagContextId(props) {
|
|
7658
7959
|
var _a;
|
|
7659
7960
|
if (this.currentTagId) return this.currentTagId;
|
|
7660
|
-
for (const id of this.set) if (
|
|
7961
|
+
for (const id of this.set) if (this.builder.isTagId(id)) return id;
|
|
7661
7962
|
const fields = (_a = props.fields) != null ? _a : [];
|
|
7662
7963
|
for (const id of this.set) {
|
|
7663
7964
|
const f = fields.find((x) => x.id === id);
|
|
@@ -7665,7 +7966,7 @@ var Selection = class {
|
|
|
7665
7966
|
return Array.isArray(f.bind_id) ? f.bind_id[0] : f.bind_id;
|
|
7666
7967
|
}
|
|
7667
7968
|
for (const id of this.set) {
|
|
7668
|
-
if (
|
|
7969
|
+
if (this.builder.isOptionId(id)) {
|
|
7669
7970
|
const host = fields.find(
|
|
7670
7971
|
(x) => {
|
|
7671
7972
|
var _a2;
|
|
@@ -7684,28 +7985,13 @@ var Selection = class {
|
|
|
7684
7985
|
}
|
|
7685
7986
|
return this.opts.rootTagId;
|
|
7686
7987
|
}
|
|
7687
|
-
selectedButtonTriggerIds(props) {
|
|
7688
|
-
var _a;
|
|
7689
|
-
const fields = (_a = props.fields) != null ? _a : [];
|
|
7690
|
-
const fieldById = new Map(fields.map((f) => [f.id, f]));
|
|
7691
|
-
const out = [];
|
|
7692
|
-
for (const selId of this.set) {
|
|
7693
|
-
if (selId.startsWith("o:")) {
|
|
7694
|
-
out.push(selId);
|
|
7695
|
-
continue;
|
|
7696
|
-
}
|
|
7697
|
-
const f = fieldById.get(selId);
|
|
7698
|
-
if ((f == null ? void 0 : f.button) === true) out.push(selId);
|
|
7699
|
-
}
|
|
7700
|
-
return out;
|
|
7701
|
-
}
|
|
7702
7988
|
computeGroupForTag(props, tagId) {
|
|
7703
7989
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
7704
7990
|
const tags = (_a = props.filters) != null ? _a : [];
|
|
7705
7991
|
const fields = (_b = props.fields) != null ? _b : [];
|
|
7706
7992
|
const tagById = new Map(tags.map((t) => [t.id, t]));
|
|
7707
7993
|
const tag = tagById.get(tagId);
|
|
7708
|
-
const selectedTriggerIds = this.
|
|
7994
|
+
const selectedTriggerIds = this.selectedButtons();
|
|
7709
7995
|
const fieldIds = this.builder.visibleFields(tagId, selectedTriggerIds);
|
|
7710
7996
|
const fieldById = new Map(fields.map((f) => [f.id, f]));
|
|
7711
7997
|
const visible = fieldIds.map((id) => fieldById.get(id)).filter(Boolean);
|
|
@@ -7786,7 +8072,7 @@ var Selection = class {
|
|
|
7786
8072
|
}
|
|
7787
8073
|
findOptionById(fields, selId) {
|
|
7788
8074
|
var _a, _b;
|
|
7789
|
-
if (
|
|
8075
|
+
if (this.builder.isOptionId(selId)) {
|
|
7790
8076
|
for (const f of fields) {
|
|
7791
8077
|
const o = (_a = f.options) == null ? void 0 : _a.find((x) => x.id === selId);
|
|
7792
8078
|
if (o) return o;
|
|
@@ -8208,8 +8494,8 @@ function useCanvasOwned(initialProps, canvasOpts, builderOpts) {
|
|
|
8208
8494
|
// src/react/workspace/context/hooks/use-canvas.ts
|
|
8209
8495
|
import * as React16 from "react";
|
|
8210
8496
|
import { useMemo as useMemo15 } from "react";
|
|
8211
|
-
var
|
|
8212
|
-
var
|
|
8497
|
+
var isTagId = (id) => id.startsWith("t:");
|
|
8498
|
+
var isOptionId = (id) => id.startsWith("o:");
|
|
8213
8499
|
function deriveSelectionInfo(props, ids) {
|
|
8214
8500
|
var _a, _b, _c, _d;
|
|
8215
8501
|
const tags = [];
|
|
@@ -8218,11 +8504,11 @@ function deriveSelectionInfo(props, ids) {
|
|
|
8218
8504
|
const fieldById = /* @__PURE__ */ new Map();
|
|
8219
8505
|
for (const f of (_a = props.fields) != null ? _a : []) fieldById.set(f.id, f);
|
|
8220
8506
|
for (const id of ids) {
|
|
8221
|
-
if (
|
|
8507
|
+
if (isTagId(id)) {
|
|
8222
8508
|
tags.push(id);
|
|
8223
8509
|
continue;
|
|
8224
8510
|
}
|
|
8225
|
-
if (
|
|
8511
|
+
if (isOptionId(id)) {
|
|
8226
8512
|
options.push(id);
|
|
8227
8513
|
continue;
|
|
8228
8514
|
}
|