@timeax/digital-service-engine 0.2.1 → 0.2.2
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 +364 -119
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +8 -11
- package/dist/core/index.d.ts +8 -11
- package/dist/core/index.js +363 -119
- package/dist/core/index.js.map +1 -1
- package/dist/react/index.cjs +561 -335
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +2 -0
- package/dist/react/index.d.ts +2 -0
- package/dist/react/index.js +561 -335
- package/dist/react/index.js.map +1 -1
- package/dist/schema/index.d.cts +12 -1
- package/dist/schema/index.d.ts +12 -1
- package/dist/workspace/index.cjs +154 -68
- package/dist/workspace/index.cjs.map +1 -1
- package/dist/workspace/index.js +154 -68
- package/dist/workspace/index.js.map +1 -1
- package/package.json +1 -1
package/dist/react/index.js
CHANGED
|
@@ -1845,6 +1845,9 @@ function toFiniteNumber(v) {
|
|
|
1845
1845
|
const n = Number(v);
|
|
1846
1846
|
return Number.isFinite(n) ? n : NaN;
|
|
1847
1847
|
}
|
|
1848
|
+
function isValidServiceIdRef(value) {
|
|
1849
|
+
return typeof value === "number" && Number.isFinite(value) || typeof value === "string" && value.trim().length > 0;
|
|
1850
|
+
}
|
|
1848
1851
|
function constraintFitOk(svcMap, candidate, constraints) {
|
|
1849
1852
|
const cap = getServiceCapability(svcMap, candidate);
|
|
1850
1853
|
if (!cap) return false;
|
|
@@ -1853,18 +1856,32 @@ function constraintFitOk(svcMap, candidate, constraints) {
|
|
|
1853
1856
|
return !(constraints.cancel === true && !cap.cancel);
|
|
1854
1857
|
}
|
|
1855
1858
|
function getServiceCapability(svcMap, candidate) {
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
if (
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1859
|
+
var _a;
|
|
1860
|
+
return (_a = getServiceCapabilityEntry(svcMap, candidate)) == null ? void 0 : _a.capability;
|
|
1861
|
+
}
|
|
1862
|
+
function getServiceCapabilityCanonicalRef(svcMap, candidate) {
|
|
1863
|
+
const entry = getServiceCapabilityEntry(svcMap, candidate);
|
|
1864
|
+
if (!entry) return void 0;
|
|
1865
|
+
return getCanonicalServiceRef(entry.key, entry.capability);
|
|
1866
|
+
}
|
|
1867
|
+
function getServiceCapabilityAliases(svcMap, candidate) {
|
|
1868
|
+
const entry = getServiceCapabilityEntry(svcMap, candidate);
|
|
1869
|
+
if (!entry) return [];
|
|
1870
|
+
return collectServiceRefAliases(entry.key, entry.capability);
|
|
1871
|
+
}
|
|
1872
|
+
function isSameServiceCapabilityRef(svcMap, left, right) {
|
|
1873
|
+
if (!isValidServiceIdRef(left) || !isValidServiceIdRef(right)) return false;
|
|
1874
|
+
const leftAliases = new Set(
|
|
1875
|
+
getServiceCapabilityAliases(svcMap, left).map((value) => String(value))
|
|
1876
|
+
);
|
|
1877
|
+
if (!leftAliases.size) {
|
|
1878
|
+
leftAliases.add(String(left));
|
|
1866
1879
|
}
|
|
1867
|
-
|
|
1880
|
+
const rightAliases = getServiceCapabilityAliases(svcMap, right);
|
|
1881
|
+
if (!rightAliases.length) {
|
|
1882
|
+
return leftAliases.has(String(right));
|
|
1883
|
+
}
|
|
1884
|
+
return rightAliases.some((value) => leftAliases.has(String(value)));
|
|
1868
1885
|
}
|
|
1869
1886
|
function normalizeRatePolicy(policy) {
|
|
1870
1887
|
var _a;
|
|
@@ -1900,6 +1917,74 @@ function rateOk(svcMap, candidate, primary, policy) {
|
|
|
1900
1917
|
if (!Number.isFinite(cRate) || !Number.isFinite(pRate)) return false;
|
|
1901
1918
|
return passesRatePolicy(policy.ratePolicy, pRate, cRate);
|
|
1902
1919
|
}
|
|
1920
|
+
function getServiceCapabilityEntry(svcMap, candidate) {
|
|
1921
|
+
if (candidate === void 0 || candidate === null) return void 0;
|
|
1922
|
+
const direct = svcMap[candidate];
|
|
1923
|
+
if (direct) {
|
|
1924
|
+
return { key: String(candidate), capability: direct };
|
|
1925
|
+
}
|
|
1926
|
+
const byString = svcMap[String(candidate)];
|
|
1927
|
+
if (byString) {
|
|
1928
|
+
return { key: String(candidate), capability: byString };
|
|
1929
|
+
}
|
|
1930
|
+
if (typeof candidate === "string") {
|
|
1931
|
+
const maybeNumber = Number(candidate);
|
|
1932
|
+
if (Number.isFinite(maybeNumber)) {
|
|
1933
|
+
const byNumber = svcMap[maybeNumber];
|
|
1934
|
+
if (byNumber) {
|
|
1935
|
+
return { key: String(maybeNumber), capability: byNumber };
|
|
1936
|
+
}
|
|
1937
|
+
}
|
|
1938
|
+
}
|
|
1939
|
+
const target = String(candidate);
|
|
1940
|
+
for (const [key, capability] of Object.entries(svcMap != null ? svcMap : {})) {
|
|
1941
|
+
if (collectServiceRefAliases(key, capability).some(
|
|
1942
|
+
(alias) => String(alias) === target
|
|
1943
|
+
)) {
|
|
1944
|
+
return { key, capability };
|
|
1945
|
+
}
|
|
1946
|
+
}
|
|
1947
|
+
return void 0;
|
|
1948
|
+
}
|
|
1949
|
+
function collectServiceRefAliases(key, capability) {
|
|
1950
|
+
const out = [];
|
|
1951
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1952
|
+
const push = (value) => {
|
|
1953
|
+
if (!isValidServiceIdRef(value)) return;
|
|
1954
|
+
const normalized = normalizeServiceRef(value);
|
|
1955
|
+
if (!normalized) return;
|
|
1956
|
+
const aliasKey = String(normalized);
|
|
1957
|
+
if (seen.has(aliasKey)) return;
|
|
1958
|
+
seen.add(aliasKey);
|
|
1959
|
+
out.push(normalized);
|
|
1960
|
+
};
|
|
1961
|
+
push(getCanonicalServiceRef(key, capability));
|
|
1962
|
+
push(capability.service);
|
|
1963
|
+
push(capability.key);
|
|
1964
|
+
push(capability.id);
|
|
1965
|
+
return out;
|
|
1966
|
+
}
|
|
1967
|
+
function getCanonicalServiceRef(key, capability) {
|
|
1968
|
+
const explicitRefs = [capability.service, capability.key, capability.id];
|
|
1969
|
+
for (const ref of explicitRefs) {
|
|
1970
|
+
if (!isValidServiceIdRef(ref)) continue;
|
|
1971
|
+
if (String(ref) === key) {
|
|
1972
|
+
return ref;
|
|
1973
|
+
}
|
|
1974
|
+
}
|
|
1975
|
+
return normalizeServiceRef(key);
|
|
1976
|
+
}
|
|
1977
|
+
function normalizeServiceRef(value) {
|
|
1978
|
+
if (!isValidServiceIdRef(value)) return void 0;
|
|
1979
|
+
if (typeof value === "number") return value;
|
|
1980
|
+
const trimmed = value.trim();
|
|
1981
|
+
if (!trimmed) return void 0;
|
|
1982
|
+
const asNumber = Number(trimmed);
|
|
1983
|
+
if (Number.isFinite(asNumber) && String(asNumber) === trimmed) {
|
|
1984
|
+
return asNumber;
|
|
1985
|
+
}
|
|
1986
|
+
return trimmed;
|
|
1987
|
+
}
|
|
1903
1988
|
|
|
1904
1989
|
// src/core/validate/steps/rates.ts
|
|
1905
1990
|
function validateRates(v) {
|
|
@@ -3345,7 +3430,7 @@ function collectFailedFallbacks(props, services, settings) {
|
|
|
3345
3430
|
const s = { ...DEFAULT_SETTINGS, ...settings != null ? settings : {} };
|
|
3346
3431
|
const out = [];
|
|
3347
3432
|
const fb = (_a = props.fallbacks) != null ? _a : {};
|
|
3348
|
-
const primaryRate = (
|
|
3433
|
+
const primaryRate = (primary) => rateOf(services, primary);
|
|
3349
3434
|
for (const [nodeId, list] of Object.entries((_b = fb.nodes) != null ? _b : {})) {
|
|
3350
3435
|
const { primary, tagContexts } = primaryForNode(props, nodeId);
|
|
3351
3436
|
if (!primary) {
|
|
@@ -3358,34 +3443,34 @@ function collectFailedFallbacks(props, services, settings) {
|
|
|
3358
3443
|
});
|
|
3359
3444
|
continue;
|
|
3360
3445
|
}
|
|
3361
|
-
for (const
|
|
3362
|
-
const
|
|
3363
|
-
if (!
|
|
3446
|
+
for (const candidate of list) {
|
|
3447
|
+
const capability = getCap(services, candidate);
|
|
3448
|
+
if (!capability) {
|
|
3364
3449
|
out.push({
|
|
3365
3450
|
scope: "node",
|
|
3366
3451
|
nodeId,
|
|
3367
3452
|
primary,
|
|
3368
|
-
candidate
|
|
3453
|
+
candidate,
|
|
3369
3454
|
reason: "unknown_service"
|
|
3370
3455
|
});
|
|
3371
3456
|
continue;
|
|
3372
3457
|
}
|
|
3373
|
-
if (
|
|
3458
|
+
if (isSameServiceCapabilityRef(services, candidate, primary)) {
|
|
3374
3459
|
out.push({
|
|
3375
3460
|
scope: "node",
|
|
3376
3461
|
nodeId,
|
|
3377
3462
|
primary,
|
|
3378
|
-
candidate
|
|
3463
|
+
candidate,
|
|
3379
3464
|
reason: "cycle"
|
|
3380
3465
|
});
|
|
3381
3466
|
continue;
|
|
3382
3467
|
}
|
|
3383
|
-
if (!passesRate(s.ratePolicy, primaryRate(primary),
|
|
3468
|
+
if (!passesRate(s.ratePolicy, primaryRate(primary), capability.rate)) {
|
|
3384
3469
|
out.push({
|
|
3385
3470
|
scope: "node",
|
|
3386
3471
|
nodeId,
|
|
3387
3472
|
primary,
|
|
3388
|
-
candidate
|
|
3473
|
+
candidate,
|
|
3389
3474
|
reason: "rate_violation"
|
|
3390
3475
|
});
|
|
3391
3476
|
continue;
|
|
@@ -3395,58 +3480,55 @@ function collectFailedFallbacks(props, services, settings) {
|
|
|
3395
3480
|
scope: "node",
|
|
3396
3481
|
nodeId,
|
|
3397
3482
|
primary,
|
|
3398
|
-
candidate
|
|
3483
|
+
candidate,
|
|
3399
3484
|
reason: "no_tag_context"
|
|
3400
3485
|
});
|
|
3401
3486
|
continue;
|
|
3402
3487
|
}
|
|
3403
|
-
let anyPass = false;
|
|
3404
|
-
let anyFail = false;
|
|
3405
3488
|
for (const tagId of tagContexts) {
|
|
3406
|
-
const
|
|
3407
|
-
|
|
3408
|
-
|
|
3409
|
-
|
|
3410
|
-
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
|
|
3416
|
-
|
|
3417
|
-
|
|
3418
|
-
|
|
3489
|
+
const fitsConstraints = s.requireConstraintFit ? satisfiesTagConstraints(
|
|
3490
|
+
tagId,
|
|
3491
|
+
{ services, props },
|
|
3492
|
+
capability
|
|
3493
|
+
) : true;
|
|
3494
|
+
if (fitsConstraints) continue;
|
|
3495
|
+
out.push({
|
|
3496
|
+
scope: "node",
|
|
3497
|
+
nodeId,
|
|
3498
|
+
primary,
|
|
3499
|
+
candidate,
|
|
3500
|
+
tagContext: tagId,
|
|
3501
|
+
reason: "constraint_mismatch"
|
|
3502
|
+
});
|
|
3419
3503
|
}
|
|
3420
|
-
void anyPass;
|
|
3421
|
-
void anyFail;
|
|
3422
3504
|
}
|
|
3423
3505
|
}
|
|
3424
3506
|
for (const [primary, list] of Object.entries((_c = fb.global) != null ? _c : {})) {
|
|
3425
|
-
for (const
|
|
3426
|
-
const
|
|
3427
|
-
if (!
|
|
3507
|
+
for (const candidate of list) {
|
|
3508
|
+
const capability = getCap(services, candidate);
|
|
3509
|
+
if (!capability) {
|
|
3428
3510
|
out.push({
|
|
3429
3511
|
scope: "global",
|
|
3430
3512
|
primary,
|
|
3431
|
-
candidate
|
|
3513
|
+
candidate,
|
|
3432
3514
|
reason: "unknown_service"
|
|
3433
3515
|
});
|
|
3434
3516
|
continue;
|
|
3435
3517
|
}
|
|
3436
|
-
if (
|
|
3518
|
+
if (isSameServiceCapabilityRef(services, candidate, primary)) {
|
|
3437
3519
|
out.push({
|
|
3438
3520
|
scope: "global",
|
|
3439
3521
|
primary,
|
|
3440
|
-
candidate
|
|
3522
|
+
candidate,
|
|
3441
3523
|
reason: "cycle"
|
|
3442
3524
|
});
|
|
3443
3525
|
continue;
|
|
3444
3526
|
}
|
|
3445
|
-
if (!passesRate(s.ratePolicy, primaryRate(primary),
|
|
3527
|
+
if (!passesRate(s.ratePolicy, primaryRate(primary), capability.rate)) {
|
|
3446
3528
|
out.push({
|
|
3447
3529
|
scope: "global",
|
|
3448
3530
|
primary,
|
|
3449
|
-
candidate
|
|
3531
|
+
candidate,
|
|
3450
3532
|
reason: "rate_violation"
|
|
3451
3533
|
});
|
|
3452
3534
|
}
|
|
@@ -3455,52 +3537,61 @@ function collectFailedFallbacks(props, services, settings) {
|
|
|
3455
3537
|
return out;
|
|
3456
3538
|
}
|
|
3457
3539
|
function rateOf(map, id) {
|
|
3458
|
-
var _a;
|
|
3540
|
+
var _a, _b;
|
|
3459
3541
|
if (id === void 0 || id === null) return void 0;
|
|
3460
|
-
|
|
3461
|
-
return (_a = c == null ? void 0 : c.rate) != null ? _a : void 0;
|
|
3542
|
+
return (_b = (_a = getCap(map, id)) == null ? void 0 : _a.rate) != null ? _b : void 0;
|
|
3462
3543
|
}
|
|
3463
|
-
function passesRate(policy, primaryRate,
|
|
3464
|
-
if (typeof
|
|
3544
|
+
function passesRate(policy, primaryRate, candidateRate) {
|
|
3545
|
+
if (typeof candidateRate !== "number" || !Number.isFinite(candidateRate)) {
|
|
3465
3546
|
return false;
|
|
3466
|
-
|
|
3547
|
+
}
|
|
3548
|
+
if (typeof primaryRate !== "number" || !Number.isFinite(primaryRate)) {
|
|
3467
3549
|
return false;
|
|
3468
|
-
|
|
3550
|
+
}
|
|
3551
|
+
return passesRatePolicy(
|
|
3552
|
+
normalizeRatePolicy(policy),
|
|
3553
|
+
primaryRate,
|
|
3554
|
+
candidateRate
|
|
3555
|
+
);
|
|
3469
3556
|
}
|
|
3470
3557
|
function getCap(map, id) {
|
|
3471
3558
|
return getServiceCapability(map, id);
|
|
3472
3559
|
}
|
|
3473
|
-
function isCapFlagEnabled(
|
|
3560
|
+
function isCapFlagEnabled(capability, flagId) {
|
|
3474
3561
|
var _a, _b;
|
|
3475
|
-
const fromFlags = (_b = (_a =
|
|
3562
|
+
const fromFlags = (_b = (_a = capability.flags) == null ? void 0 : _a[flagId]) == null ? void 0 : _b.enabled;
|
|
3476
3563
|
if (fromFlags === true) return true;
|
|
3477
3564
|
if (fromFlags === false) return false;
|
|
3478
|
-
const legacy =
|
|
3565
|
+
const legacy = capability[flagId];
|
|
3479
3566
|
return legacy === true;
|
|
3480
3567
|
}
|
|
3481
|
-
function satisfiesTagConstraints(tagId, ctx,
|
|
3482
|
-
const tag = ctx.props.filters.find((
|
|
3483
|
-
const
|
|
3484
|
-
if (!
|
|
3485
|
-
for (const [key, value] of Object.entries(
|
|
3486
|
-
if (value === true && !isCapFlagEnabled(
|
|
3568
|
+
function satisfiesTagConstraints(tagId, ctx, capability) {
|
|
3569
|
+
const tag = ctx.props.filters.find((item) => item.id === tagId);
|
|
3570
|
+
const effectiveConstraints2 = tag == null ? void 0 : tag.constraints;
|
|
3571
|
+
if (!effectiveConstraints2) return true;
|
|
3572
|
+
for (const [key, value] of Object.entries(effectiveConstraints2)) {
|
|
3573
|
+
if (value === true && !isCapFlagEnabled(capability, key)) {
|
|
3487
3574
|
return false;
|
|
3488
3575
|
}
|
|
3489
3576
|
}
|
|
3490
3577
|
return true;
|
|
3491
3578
|
}
|
|
3492
3579
|
function primaryForNode(props, nodeId) {
|
|
3493
|
-
const tag = props.filters.find((
|
|
3580
|
+
const tag = props.filters.find((item) => item.id === nodeId);
|
|
3494
3581
|
if (tag) {
|
|
3495
3582
|
return { primary: tag.service_id, tagContexts: [tag.id] };
|
|
3496
3583
|
}
|
|
3497
3584
|
const field = props.fields.find(
|
|
3498
|
-
(
|
|
3585
|
+
(item) => Array.isArray(item.options) && item.options.some((option2) => option2.id === nodeId)
|
|
3499
3586
|
);
|
|
3500
|
-
if (!field)
|
|
3501
|
-
|
|
3502
|
-
|
|
3503
|
-
|
|
3587
|
+
if (!field) {
|
|
3588
|
+
return { tagContexts: [], reasonNoPrimary: "no_parent_field" };
|
|
3589
|
+
}
|
|
3590
|
+
const option = field.options.find((item) => item.id === nodeId);
|
|
3591
|
+
return {
|
|
3592
|
+
primary: option.service_id,
|
|
3593
|
+
tagContexts: bindIdsToArray(field.bind_id)
|
|
3594
|
+
};
|
|
3504
3595
|
}
|
|
3505
3596
|
function bindIdsToArray(bind) {
|
|
3506
3597
|
if (!bind) return [];
|
|
@@ -3510,43 +3601,54 @@ function getEligibleFallbacks(params) {
|
|
|
3510
3601
|
var _a, _b, _c, _d, _e, _f;
|
|
3511
3602
|
const s = { ...DEFAULT_SETTINGS, ...(_a = params.settings) != null ? _a : {} };
|
|
3512
3603
|
const { primary, nodeId, tagId, services } = params;
|
|
3513
|
-
const
|
|
3514
|
-
const
|
|
3515
|
-
|
|
3516
|
-
|
|
3517
|
-
|
|
3518
|
-
|
|
3519
|
-
|
|
3520
|
-
|
|
3604
|
+
const excludes = /* @__PURE__ */ new Set();
|
|
3605
|
+
for (const ref of (_b = params.exclude) != null ? _b : []) {
|
|
3606
|
+
addComparableServiceRef(excludes, services, ref);
|
|
3607
|
+
}
|
|
3608
|
+
addComparableServiceRef(excludes, services, primary);
|
|
3609
|
+
const source = (_c = params.source) != null ? _c : "registered";
|
|
3610
|
+
const candidateLists = source === "all_services" ? [listServicePoolCandidates(services)] : listRegisteredFallbackCandidates(
|
|
3611
|
+
(_d = params.fallbacks) != null ? _d : {},
|
|
3612
|
+
primary,
|
|
3613
|
+
nodeId,
|
|
3614
|
+
services
|
|
3615
|
+
);
|
|
3616
|
+
if (!candidateLists.length) return [];
|
|
3521
3617
|
const primaryRate = rateOf(services, primary);
|
|
3522
3618
|
const seen = /* @__PURE__ */ new Set();
|
|
3523
3619
|
const eligible = [];
|
|
3524
|
-
for (const list of
|
|
3525
|
-
for (const
|
|
3526
|
-
|
|
3527
|
-
|
|
3528
|
-
if (
|
|
3529
|
-
|
|
3530
|
-
const
|
|
3531
|
-
|
|
3532
|
-
|
|
3620
|
+
for (const list of candidateLists) {
|
|
3621
|
+
for (const candidate of list) {
|
|
3622
|
+
if (hasComparableServiceRef(excludes, services, candidate)) continue;
|
|
3623
|
+
const capability = getCap(services, candidate);
|
|
3624
|
+
if (!capability) continue;
|
|
3625
|
+
const candidateId = (_e = getServiceCapabilityCanonicalRef(services, candidate)) != null ? _e : candidate;
|
|
3626
|
+
const candidateIdentity = getComparableServiceRefKey(
|
|
3627
|
+
services,
|
|
3628
|
+
candidateId
|
|
3629
|
+
);
|
|
3630
|
+
if (((_f = params.unique) != null ? _f : true) && seen.has(candidateIdentity)) continue;
|
|
3631
|
+
seen.add(candidateIdentity);
|
|
3632
|
+
if (!passesRate(s.ratePolicy, primaryRate, capability.rate)) {
|
|
3633
|
+
continue;
|
|
3634
|
+
}
|
|
3533
3635
|
if (s.requireConstraintFit && tagId) {
|
|
3534
|
-
const
|
|
3636
|
+
const fitsConstraints = satisfiesTagConstraints(
|
|
3535
3637
|
tagId,
|
|
3536
3638
|
{ props: params.props, services },
|
|
3537
|
-
|
|
3639
|
+
capability
|
|
3538
3640
|
);
|
|
3539
|
-
if (!
|
|
3641
|
+
if (!fitsConstraints) continue;
|
|
3540
3642
|
}
|
|
3541
|
-
eligible.push(
|
|
3643
|
+
eligible.push(candidateId);
|
|
3542
3644
|
}
|
|
3543
3645
|
}
|
|
3544
3646
|
if (s.selectionStrategy === "cheapest") {
|
|
3545
|
-
eligible.sort((
|
|
3647
|
+
eligible.sort((left, right) => {
|
|
3546
3648
|
var _a2, _b2;
|
|
3547
|
-
const
|
|
3548
|
-
const
|
|
3549
|
-
return
|
|
3649
|
+
const leftRate = (_a2 = rateOf(services, left)) != null ? _a2 : Infinity;
|
|
3650
|
+
const rightRate = (_b2 = rateOf(services, right)) != null ? _b2 : Infinity;
|
|
3651
|
+
return leftRate - rightRate;
|
|
3550
3652
|
});
|
|
3551
3653
|
}
|
|
3552
3654
|
if (typeof params.limit === "number" && params.limit >= 0) {
|
|
@@ -3554,10 +3656,104 @@ function getEligibleFallbacks(params) {
|
|
|
3554
3656
|
}
|
|
3555
3657
|
return eligible;
|
|
3556
3658
|
}
|
|
3659
|
+
function getAssignedServiceIds(params) {
|
|
3660
|
+
var _a, _b, _c, _d, _e;
|
|
3661
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3662
|
+
const out = [];
|
|
3663
|
+
const push = (value) => {
|
|
3664
|
+
if (!isValidServiceIdRef(value)) return;
|
|
3665
|
+
const key = String(value);
|
|
3666
|
+
if (seen.has(key)) return;
|
|
3667
|
+
seen.add(key);
|
|
3668
|
+
out.push(value);
|
|
3669
|
+
};
|
|
3670
|
+
const props = params.props;
|
|
3671
|
+
if (props) {
|
|
3672
|
+
for (const tag of (_a = props.filters) != null ? _a : []) {
|
|
3673
|
+
push(tag.service_id);
|
|
3674
|
+
}
|
|
3675
|
+
for (const field of (_b = props.fields) != null ? _b : []) {
|
|
3676
|
+
const fieldService = field.service_id;
|
|
3677
|
+
if (field.button === true) {
|
|
3678
|
+
push(fieldService);
|
|
3679
|
+
}
|
|
3680
|
+
for (const option of (_c = field.options) != null ? _c : []) {
|
|
3681
|
+
if (option.pricing_role === "utility") continue;
|
|
3682
|
+
push(option.service_id);
|
|
3683
|
+
}
|
|
3684
|
+
}
|
|
3685
|
+
}
|
|
3686
|
+
const snapshot = params.snapshot;
|
|
3687
|
+
if (snapshot) {
|
|
3688
|
+
for (const serviceId of (_d = snapshot.services) != null ? _d : []) {
|
|
3689
|
+
push(serviceId);
|
|
3690
|
+
}
|
|
3691
|
+
for (const list of Object.values((_e = snapshot.serviceMap) != null ? _e : {})) {
|
|
3692
|
+
for (const serviceId of list != null ? list : []) {
|
|
3693
|
+
push(serviceId);
|
|
3694
|
+
}
|
|
3695
|
+
}
|
|
3696
|
+
}
|
|
3697
|
+
return out;
|
|
3698
|
+
}
|
|
3557
3699
|
function getFallbackRegistrationInfo(props, nodeId) {
|
|
3558
3700
|
const { primary, tagContexts } = primaryForNode(props, nodeId);
|
|
3559
3701
|
return { primary, tagContexts };
|
|
3560
3702
|
}
|
|
3703
|
+
function listRegisteredFallbackCandidates(fallbacks, primary, nodeId, services) {
|
|
3704
|
+
var _a, _b;
|
|
3705
|
+
const lists = [];
|
|
3706
|
+
if (nodeId && ((_a = fallbacks.nodes) == null ? void 0 : _a[nodeId])) {
|
|
3707
|
+
lists.push(fallbacks.nodes[nodeId]);
|
|
3708
|
+
}
|
|
3709
|
+
for (const [registeredPrimary, list] of Object.entries((_b = fallbacks.global) != null ? _b : {})) {
|
|
3710
|
+
if (!isMatchingServiceRef(services, registeredPrimary, primary)) continue;
|
|
3711
|
+
lists.push(list);
|
|
3712
|
+
}
|
|
3713
|
+
return lists;
|
|
3714
|
+
}
|
|
3715
|
+
function listServicePoolCandidates(services) {
|
|
3716
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3717
|
+
const out = [];
|
|
3718
|
+
for (const [key, capability] of Object.entries(services != null ? services : {})) {
|
|
3719
|
+
const candidate = getServicePoolCandidateId(key, capability);
|
|
3720
|
+
if (!isValidServiceIdRef(candidate)) continue;
|
|
3721
|
+
const identity = getComparableServiceRefKey(services, candidate);
|
|
3722
|
+
if (seen.has(identity)) continue;
|
|
3723
|
+
seen.add(identity);
|
|
3724
|
+
out.push(candidate);
|
|
3725
|
+
}
|
|
3726
|
+
return out;
|
|
3727
|
+
}
|
|
3728
|
+
function getServicePoolCandidateId(key, capability) {
|
|
3729
|
+
var _a;
|
|
3730
|
+
return (_a = getServiceCapabilityCanonicalRef({ [key]: capability }, key)) != null ? _a : key;
|
|
3731
|
+
}
|
|
3732
|
+
function addComparableServiceRef(target, services, value) {
|
|
3733
|
+
for (const ref of getComparableServiceRefs(services, value)) {
|
|
3734
|
+
target.add(ref);
|
|
3735
|
+
}
|
|
3736
|
+
}
|
|
3737
|
+
function hasComparableServiceRef(target, services, value) {
|
|
3738
|
+
return getComparableServiceRefs(services, value).some((ref) => target.has(ref));
|
|
3739
|
+
}
|
|
3740
|
+
function getComparableServiceRefKey(services, value) {
|
|
3741
|
+
if (!isValidServiceIdRef(value)) return "";
|
|
3742
|
+
const canonical = getServiceCapabilityCanonicalRef(services, value);
|
|
3743
|
+
return String(canonical != null ? canonical : value);
|
|
3744
|
+
}
|
|
3745
|
+
function getComparableServiceRefs(services, value) {
|
|
3746
|
+
if (!isValidServiceIdRef(value)) return [];
|
|
3747
|
+
const aliases = getServiceCapabilityAliases(services, value);
|
|
3748
|
+
if (!aliases.length) {
|
|
3749
|
+
return [String(value)];
|
|
3750
|
+
}
|
|
3751
|
+
return aliases.map((ref) => String(ref));
|
|
3752
|
+
}
|
|
3753
|
+
function isMatchingServiceRef(services, left, right) {
|
|
3754
|
+
if (!services) return String(left) === String(right);
|
|
3755
|
+
return isSameServiceCapabilityRef(services, left, right);
|
|
3756
|
+
}
|
|
3561
3757
|
|
|
3562
3758
|
// src/core/tag-relations.ts
|
|
3563
3759
|
var toId = (x) => typeof x === "string" ? x : x.id;
|
|
@@ -5096,6 +5292,7 @@ function createFallbackEditor(options = {}) {
|
|
|
5096
5292
|
const original = cloneFallbacks(options.fallbacks);
|
|
5097
5293
|
let current = cloneFallbacks(options.fallbacks);
|
|
5098
5294
|
const props = options.props;
|
|
5295
|
+
const snapshot = options.snapshot;
|
|
5099
5296
|
const services = (_a = options.services) != null ? _a : {};
|
|
5100
5297
|
const settings = (_b = options.settings) != null ? _b : {};
|
|
5101
5298
|
function state() {
|
|
@@ -5190,7 +5387,11 @@ function createFallbackEditor(options = {}) {
|
|
|
5190
5387
|
const allowed2 = [];
|
|
5191
5388
|
for (const candidate of normalized) {
|
|
5192
5389
|
const reasons = [];
|
|
5193
|
-
if (
|
|
5390
|
+
if (isSameServiceCapabilityRef(
|
|
5391
|
+
services,
|
|
5392
|
+
candidate,
|
|
5393
|
+
context.primary
|
|
5394
|
+
)) {
|
|
5194
5395
|
reasons.push("self_reference");
|
|
5195
5396
|
}
|
|
5196
5397
|
if (reasons.length) {
|
|
@@ -5278,7 +5479,19 @@ function createFallbackEditor(options = {}) {
|
|
|
5278
5479
|
return writeScope(context, []);
|
|
5279
5480
|
}
|
|
5280
5481
|
function eligible(context, opt) {
|
|
5482
|
+
var _a2, _b2;
|
|
5281
5483
|
if (!props) return [];
|
|
5484
|
+
const source = (_a2 = opt == null ? void 0 : opt.source) != null ? _a2 : "all_services";
|
|
5485
|
+
const exclude2 = normalizeCandidateList(
|
|
5486
|
+
[
|
|
5487
|
+
...(_b2 = opt == null ? void 0 : opt.exclude) != null ? _b2 : [],
|
|
5488
|
+
...source === "all_services" ? [
|
|
5489
|
+
...getAssignedServiceIds({ props, snapshot }),
|
|
5490
|
+
...getScope(context)
|
|
5491
|
+
] : []
|
|
5492
|
+
],
|
|
5493
|
+
true
|
|
5494
|
+
);
|
|
5282
5495
|
if (context.scope === "global") {
|
|
5283
5496
|
return getEligibleFallbacks({
|
|
5284
5497
|
primary: context.primary,
|
|
@@ -5286,9 +5499,10 @@ function createFallbackEditor(options = {}) {
|
|
|
5286
5499
|
fallbacks: current,
|
|
5287
5500
|
settings,
|
|
5288
5501
|
props,
|
|
5289
|
-
exclude:
|
|
5502
|
+
exclude: exclude2,
|
|
5290
5503
|
unique: opt == null ? void 0 : opt.unique,
|
|
5291
|
-
limit: opt == null ? void 0 : opt.limit
|
|
5504
|
+
limit: opt == null ? void 0 : opt.limit,
|
|
5505
|
+
source
|
|
5292
5506
|
});
|
|
5293
5507
|
}
|
|
5294
5508
|
const info = getFallbackRegistrationInfo(props, context.nodeId);
|
|
@@ -5296,14 +5510,19 @@ function createFallbackEditor(options = {}) {
|
|
|
5296
5510
|
return getEligibleFallbacks({
|
|
5297
5511
|
primary: info.primary,
|
|
5298
5512
|
nodeId: context.nodeId,
|
|
5299
|
-
tagId:
|
|
5513
|
+
tagId: resolveNodeTagContext({
|
|
5514
|
+
nodeId: context.nodeId,
|
|
5515
|
+
snapshot,
|
|
5516
|
+
fallbackTagContexts: info.tagContexts
|
|
5517
|
+
}),
|
|
5300
5518
|
services,
|
|
5301
5519
|
fallbacks: current,
|
|
5302
5520
|
settings,
|
|
5303
5521
|
props,
|
|
5304
|
-
exclude:
|
|
5522
|
+
exclude: exclude2,
|
|
5305
5523
|
unique: opt == null ? void 0 : opt.unique,
|
|
5306
|
-
limit: opt == null ? void 0 : opt.limit
|
|
5524
|
+
limit: opt == null ? void 0 : opt.limit,
|
|
5525
|
+
source
|
|
5307
5526
|
});
|
|
5308
5527
|
}
|
|
5309
5528
|
function writeScope(context, nextList) {
|
|
@@ -5361,14 +5580,14 @@ function sameFallbacks(a, b) {
|
|
|
5361
5580
|
function normalizeCandidateList(input, preserveOrder) {
|
|
5362
5581
|
const out = [];
|
|
5363
5582
|
for (const item of input != null ? input : []) {
|
|
5364
|
-
if (!
|
|
5583
|
+
if (!isValidServiceIdRef2(item)) continue;
|
|
5365
5584
|
const exists = out.some((x) => String(x) === String(item));
|
|
5366
5585
|
if (exists) continue;
|
|
5367
5586
|
out.push(item);
|
|
5368
5587
|
}
|
|
5369
5588
|
return preserveOrder ? out : out;
|
|
5370
5589
|
}
|
|
5371
|
-
function
|
|
5590
|
+
function isValidServiceIdRef2(value) {
|
|
5372
5591
|
return typeof value === "number" && Number.isFinite(value) || typeof value === "string" && value.trim().length > 0;
|
|
5373
5592
|
}
|
|
5374
5593
|
function clamp(n, min, max) {
|
|
@@ -5377,7 +5596,7 @@ function clamp(n, min, max) {
|
|
|
5377
5596
|
function getNodeRegistrationInfo(props, nodeId) {
|
|
5378
5597
|
const tag = props.filters.find((t) => t.id === nodeId);
|
|
5379
5598
|
if (tag) {
|
|
5380
|
-
if (!
|
|
5599
|
+
if (!isValidServiceIdRef2(tag.service_id)) {
|
|
5381
5600
|
return { ok: false, reasons: ["no_primary"] };
|
|
5382
5601
|
}
|
|
5383
5602
|
return {
|
|
@@ -5390,7 +5609,7 @@ function getNodeRegistrationInfo(props, nodeId) {
|
|
|
5390
5609
|
if (!hit) {
|
|
5391
5610
|
return { ok: false, reasons: ["node_not_found"] };
|
|
5392
5611
|
}
|
|
5393
|
-
if (!
|
|
5612
|
+
if (!isValidServiceIdRef2(hit.option.service_id)) {
|
|
5394
5613
|
return { ok: false, reasons: ["no_primary"] };
|
|
5395
5614
|
}
|
|
5396
5615
|
return {
|
|
@@ -5412,6 +5631,15 @@ function bindIdsToArray2(v) {
|
|
|
5412
5631
|
if (Array.isArray(v)) return v.filter(Boolean);
|
|
5413
5632
|
return v ? [v] : [];
|
|
5414
5633
|
}
|
|
5634
|
+
function resolveNodeTagContext(params) {
|
|
5635
|
+
var _a, _b, _c;
|
|
5636
|
+
const nodeContexts = (_c = (_b = (_a = params.snapshot) == null ? void 0 : _a.meta) == null ? void 0 : _b.context) == null ? void 0 : _c.nodeContexts;
|
|
5637
|
+
if (nodeContexts && Object.prototype.hasOwnProperty.call(nodeContexts, params.nodeId)) {
|
|
5638
|
+
const tagId = nodeContexts[params.nodeId];
|
|
5639
|
+
return typeof tagId === "string" && tagId.trim().length > 0 ? tagId : void 0;
|
|
5640
|
+
}
|
|
5641
|
+
return params.fallbackTagContexts[0];
|
|
5642
|
+
}
|
|
5415
5643
|
function mapDiagReason(reason) {
|
|
5416
5644
|
switch (String(reason)) {
|
|
5417
5645
|
case "unknown_service":
|
|
@@ -12113,10 +12341,10 @@ function FallbackEditorInner({ className }) {
|
|
|
12113
12341
|
"div",
|
|
12114
12342
|
{
|
|
12115
12343
|
className: [
|
|
12116
|
-
"min-h-
|
|
12344
|
+
"h-full min-h-0 overflow-hidden bg-zinc-100 p-4 text-zinc-900 dark:bg-zinc-950 dark:text-zinc-100",
|
|
12117
12345
|
className
|
|
12118
12346
|
].filter(Boolean).join(" "),
|
|
12119
|
-
children: /* @__PURE__ */ jsxs2("div", { className: "
|
|
12347
|
+
children: /* @__PURE__ */ jsxs2("div", { className: "flex h-full min-h-0 flex-col gap-4", children: [
|
|
12120
12348
|
/* @__PURE__ */ jsx6(
|
|
12121
12349
|
FallbackEditorHeader,
|
|
12122
12350
|
{
|
|
@@ -12128,9 +12356,9 @@ function FallbackEditorInner({ className }) {
|
|
|
12128
12356
|
saving: headerSaving
|
|
12129
12357
|
}
|
|
12130
12358
|
),
|
|
12131
|
-
/* @__PURE__ */ jsxs2("div", { className: "grid gap-4 xl:grid-cols-[300px_minmax(0,1fr)_360px]", children: [
|
|
12359
|
+
/* @__PURE__ */ jsxs2("div", { className: "grid min-h-0 flex-1 gap-4 overflow-hidden xl:grid-cols-[300px_minmax(0,1fr)_360px]", children: [
|
|
12132
12360
|
/* @__PURE__ */ jsx6(FallbackServiceSidebar, {}),
|
|
12133
|
-
/* @__PURE__ */ jsxs2("div", { className: "flex min-h-0 flex-col gap-4", children: [
|
|
12361
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex min-h-0 flex-col gap-4 overflow-y-auto", children: [
|
|
12134
12362
|
/* @__PURE__ */ jsx6("section", { className: "rounded-2xl border border-zinc-200 bg-white p-4 shadow-sm dark:border-zinc-800 dark:bg-zinc-900", children: /* @__PURE__ */ jsxs2("div", { className: "flex flex-wrap items-start justify-between gap-4", children: [
|
|
12135
12363
|
/* @__PURE__ */ jsxs2("div", { children: [
|
|
12136
12364
|
/* @__PURE__ */ jsx6("h2", { className: "text-lg font-semibold text-zinc-900 dark:text-zinc-100", children: activeServiceId !== void 0 ? `Service #${String(activeServiceId)}` : "No service selected" }),
|
|
@@ -12274,7 +12502,7 @@ function FallbackDetailsPanel() {
|
|
|
12274
12502
|
() => services.find((s) => String(s.id) === String(activeServiceId)),
|
|
12275
12503
|
[services, activeServiceId]
|
|
12276
12504
|
);
|
|
12277
|
-
return /* @__PURE__ */ jsxs4("aside", { className: "flex min-h-0 flex-col gap-4", children: [
|
|
12505
|
+
return /* @__PURE__ */ jsxs4("aside", { className: "flex min-h-0 flex-col gap-4 overflow-y-auto", children: [
|
|
12278
12506
|
/* @__PURE__ */ jsxs4("section", { className: "rounded-2xl border border-zinc-200 bg-white p-4 shadow-sm dark:border-zinc-800 dark:bg-zinc-900", children: [
|
|
12279
12507
|
/* @__PURE__ */ jsx8("h3", { className: "text-sm font-semibold text-zinc-900 dark:text-zinc-100", children: "Primary service info" }),
|
|
12280
12508
|
!service ? /* @__PURE__ */ jsx8("p", { className: "mt-3 text-sm text-zinc-500 dark:text-zinc-400", children: "No service selected." }) : /* @__PURE__ */ jsxs4("div", { className: "mt-3 space-y-2 text-sm", children: [
|
|
@@ -12436,7 +12664,7 @@ function FallbackSettingsPanel() {
|
|
|
12436
12664
|
kind: "lte_primary",
|
|
12437
12665
|
pct: 5
|
|
12438
12666
|
};
|
|
12439
|
-
return /* @__PURE__ */ jsxs6("section", { className: "rounded-2xl border border-zinc-200 bg-white p-4 shadow-sm dark:border-zinc-800 dark:bg-zinc-900", children: [
|
|
12667
|
+
return /* @__PURE__ */ jsxs6("section", { className: "rounded-2xl border border-zinc-200 bg-white p-4 shadow-sm dark:border-zinc-800 dark:bg-zinc-900 overflow-y-auto", children: [
|
|
12440
12668
|
/* @__PURE__ */ jsxs6("div", { className: "mb-4 flex items-start justify-between gap-3", children: [
|
|
12441
12669
|
/* @__PURE__ */ jsxs6("div", { children: [
|
|
12442
12670
|
/* @__PURE__ */ jsx10("h3", { className: "text-sm font-semibold text-zinc-900 dark:text-zinc-100", children: "Fallback settings" }),
|
|
@@ -12635,7 +12863,7 @@ function FallbackServiceSidebar() {
|
|
|
12635
12863
|
}
|
|
12636
12864
|
);
|
|
12637
12865
|
}, [query, services]);
|
|
12638
|
-
return /* @__PURE__ */ jsxs7("aside", { className: "flex min-h-0 flex-col rounded-2xl border border-zinc-200 bg-white shadow-sm dark:border-zinc-800 dark:bg-zinc-900", children: [
|
|
12866
|
+
return /* @__PURE__ */ jsxs7("aside", { className: "flex h-full min-h-0 flex-col overflow-hidden rounded-2xl border border-zinc-200 bg-white shadow-sm dark:border-zinc-800 dark:bg-zinc-900", children: [
|
|
12639
12867
|
/* @__PURE__ */ jsxs7("div", { className: "border-b border-zinc-200 p-4 dark:border-zinc-800", children: [
|
|
12640
12868
|
/* @__PURE__ */ jsx11("h2", { className: "text-sm font-semibold text-zinc-900 dark:text-zinc-100", children: "Primary services" }),
|
|
12641
12869
|
/* @__PURE__ */ jsx11("p", { className: "mt-1 text-xs text-zinc-500 dark:text-zinc-400", children: "Services currently active in the builder/runtime context." })
|
|
@@ -12650,7 +12878,7 @@ function FallbackServiceSidebar() {
|
|
|
12650
12878
|
className: "rounded-xl border border-zinc-300 bg-white px-3 py-2 text-sm outline-none focus:border-blue-500 dark:border-zinc-700 dark:bg-zinc-950 dark:text-zinc-100"
|
|
12651
12879
|
}
|
|
12652
12880
|
),
|
|
12653
|
-
/* @__PURE__ */ jsx11("div", { className: "mt-3 flex-1 space-y-2 overflow-auto", children: filtered.map((service) => {
|
|
12881
|
+
/* @__PURE__ */ jsx11("div", { className: "mt-3 flex-1 space-y-2 overflow-y-auto", children: filtered.map((service) => {
|
|
12654
12882
|
var _a, _b;
|
|
12655
12883
|
const active = String(service.id) === String(activeServiceId);
|
|
12656
12884
|
const count = get(service.id).length;
|
|
@@ -12691,11 +12919,172 @@ function FallbackServiceSidebar() {
|
|
|
12691
12919
|
}
|
|
12692
12920
|
|
|
12693
12921
|
// src/react/fallback-editor/FallbackRegistrationsPanel.tsx
|
|
12694
|
-
import
|
|
12922
|
+
import React11 from "react";
|
|
12923
|
+
import { Fragment, jsx as jsx12, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
12924
|
+
function FallbackRegistrationsPanel() {
|
|
12925
|
+
const { activeServiceId, remove: remove2, clear, check } = useFallbackEditor();
|
|
12926
|
+
const registrations = useActiveFallbackRegistrations();
|
|
12927
|
+
const eligibleServices = useEligibleServiceList();
|
|
12928
|
+
const [candidatePickerOpen, setCandidatePickerOpen] = React11.useState(false);
|
|
12929
|
+
const [candidateContext, setCandidateContext] = React11.useState(null);
|
|
12930
|
+
const [candidatePrimaryId, setCandidatePrimaryId] = React11.useState(void 0);
|
|
12931
|
+
const [registrationDialogOpen, setRegistrationDialogOpen] = React11.useState(false);
|
|
12932
|
+
const makeContext = React11.useCallback(
|
|
12933
|
+
(registration) => {
|
|
12934
|
+
if (registration.scope === "global") {
|
|
12935
|
+
return {
|
|
12936
|
+
scope: "global",
|
|
12937
|
+
primary: registration.primary
|
|
12938
|
+
};
|
|
12939
|
+
}
|
|
12940
|
+
return {
|
|
12941
|
+
scope: "node",
|
|
12942
|
+
nodeId: registration.scopeId
|
|
12943
|
+
};
|
|
12944
|
+
},
|
|
12945
|
+
[]
|
|
12946
|
+
);
|
|
12947
|
+
const openCandidatePicker = React11.useCallback(
|
|
12948
|
+
(context, primaryId) => {
|
|
12949
|
+
setCandidateContext(context);
|
|
12950
|
+
setCandidatePrimaryId(primaryId);
|
|
12951
|
+
setCandidatePickerOpen(true);
|
|
12952
|
+
},
|
|
12953
|
+
[]
|
|
12954
|
+
);
|
|
12955
|
+
if (activeServiceId === void 0 || activeServiceId === null) {
|
|
12956
|
+
return /* @__PURE__ */ jsx12("section", { className: "rounded-2xl border border-zinc-200 bg-white p-4 shadow-sm dark:border-zinc-800 dark:bg-zinc-900 ", children: /* @__PURE__ */ jsx12("div", { className: "rounded-2xl border border-dashed border-zinc-300 p-6 text-sm text-zinc-500 dark:border-zinc-700 dark:text-zinc-400", children: "Select a primary service to start editing." }) });
|
|
12957
|
+
}
|
|
12958
|
+
return /* @__PURE__ */ jsxs8(Fragment, { children: [
|
|
12959
|
+
/* @__PURE__ */ jsxs8("section", { className: "rounded-2xl border border-zinc-200 bg-white p-4 shadow-sm dark:border-zinc-800 dark:bg-zinc-900 overflow-y-auto", children: [
|
|
12960
|
+
/* @__PURE__ */ jsxs8("div", { className: "mb-4 flex items-start justify-between gap-3", children: [
|
|
12961
|
+
/* @__PURE__ */ jsxs8("div", { children: [
|
|
12962
|
+
/* @__PURE__ */ jsx12("h3", { className: "text-sm font-semibold text-zinc-900 dark:text-zinc-100", children: "Registered fallbacks" }),
|
|
12963
|
+
/* @__PURE__ */ jsx12("p", { className: "mt-1 text-xs text-zinc-500 dark:text-zinc-400", children: "Use eligible services as fallback candidates for the selected primary." })
|
|
12964
|
+
] }),
|
|
12965
|
+
/* @__PURE__ */ jsx12(
|
|
12966
|
+
"button",
|
|
12967
|
+
{
|
|
12968
|
+
type: "button",
|
|
12969
|
+
onClick: () => setRegistrationDialogOpen(true),
|
|
12970
|
+
className: "rounded-xl border border-zinc-300 bg-white px-3 py-2 text-sm font-medium text-zinc-700 hover:bg-zinc-50 dark:border-zinc-700 dark:bg-zinc-950 dark:text-zinc-200 dark:hover:bg-zinc-800",
|
|
12971
|
+
children: "Add registration"
|
|
12972
|
+
}
|
|
12973
|
+
)
|
|
12974
|
+
] }),
|
|
12975
|
+
/* @__PURE__ */ jsx12("div", { className: "space-y-4", children: registrations.length === 0 ? /* @__PURE__ */ jsx12("div", { className: "rounded-2xl border border-dashed border-zinc-300 p-6 text-sm text-zinc-500 dark:border-zinc-700 dark:text-zinc-400", children: "No registrations yet for this primary service." }) : registrations.map((reg, index) => {
|
|
12976
|
+
var _a;
|
|
12977
|
+
const context = makeContext(reg);
|
|
12978
|
+
const candidates = reg.services;
|
|
12979
|
+
return /* @__PURE__ */ jsxs8(
|
|
12980
|
+
"div",
|
|
12981
|
+
{
|
|
12982
|
+
className: "rounded-2xl border border-zinc-200 bg-zinc-50 p-4 dark:border-zinc-800 dark:bg-zinc-950",
|
|
12983
|
+
children: [
|
|
12984
|
+
/* @__PURE__ */ jsxs8("div", { className: "flex flex-wrap items-start justify-between gap-3", children: [
|
|
12985
|
+
/* @__PURE__ */ jsxs8("div", { children: [
|
|
12986
|
+
/* @__PURE__ */ jsx12("div", { className: "text-sm font-semibold text-zinc-900 dark:text-zinc-100", children: reg.scope === "global" ? "Global registration" : `Node \xB7 ${reg.scopeId}` }),
|
|
12987
|
+
/* @__PURE__ */ jsxs8("div", { className: "mt-1 text-xs text-zinc-500 dark:text-zinc-400", children: [
|
|
12988
|
+
"Primary #",
|
|
12989
|
+
String(reg.primary)
|
|
12990
|
+
] })
|
|
12991
|
+
] }),
|
|
12992
|
+
/* @__PURE__ */ jsxs8("span", { className: "rounded-full border border-zinc-200 bg-white px-2 py-1 text-[11px] text-zinc-600 dark:border-zinc-700 dark:bg-zinc-900 dark:text-zinc-300", children: [
|
|
12993
|
+
reg.scope,
|
|
12994
|
+
reg.scopeId ? ` \xB7 ${reg.scopeId}` : ""
|
|
12995
|
+
] })
|
|
12996
|
+
] }),
|
|
12997
|
+
/* @__PURE__ */ jsx12("div", { className: "mt-4 flex flex-wrap gap-2", children: candidates.length === 0 ? /* @__PURE__ */ jsx12("span", { className: "text-xs text-zinc-500 dark:text-zinc-400", children: "No fallback services yet." }) : candidates.map((candidate) => {
|
|
12998
|
+
var _a2;
|
|
12999
|
+
const preview = check(context, [
|
|
13000
|
+
candidate
|
|
13001
|
+
]);
|
|
13002
|
+
const rejected = preview.rejected[0];
|
|
13003
|
+
const tone = rejected ? "border-red-200 bg-red-50 text-red-700 dark:border-red-900/50 dark:bg-red-950/30 dark:text-red-300" : "border-zinc-200 bg-white text-zinc-700 dark:border-zinc-700 dark:bg-zinc-900 dark:text-zinc-200";
|
|
13004
|
+
const service = eligibleServices.find(
|
|
13005
|
+
(s) => String(s.id) === String(candidate)
|
|
13006
|
+
);
|
|
13007
|
+
return /* @__PURE__ */ jsxs8(
|
|
13008
|
+
"div",
|
|
13009
|
+
{
|
|
13010
|
+
className: `inline-flex items-center gap-2 rounded-xl border px-3 py-2 text-xs ${tone}`,
|
|
13011
|
+
children: [
|
|
13012
|
+
/* @__PURE__ */ jsx12("span", { children: service ? `#${String(service.id)} \xB7 ${(_a2 = service.name) != null ? _a2 : "Unnamed"}` : `#${String(candidate)}` }),
|
|
13013
|
+
rejected ? /* @__PURE__ */ jsx12("span", { className: "rounded-full border border-current/20 px-2 py-0.5 text-[10px]", children: rejected.reasons.join(
|
|
13014
|
+
", "
|
|
13015
|
+
) }) : /* @__PURE__ */ jsx12("span", { className: "rounded-full border border-current/20 px-2 py-0.5 text-[10px]", children: "valid" }),
|
|
13016
|
+
/* @__PURE__ */ jsx12(
|
|
13017
|
+
"button",
|
|
13018
|
+
{
|
|
13019
|
+
type: "button",
|
|
13020
|
+
onClick: () => remove2(
|
|
13021
|
+
context,
|
|
13022
|
+
candidate
|
|
13023
|
+
),
|
|
13024
|
+
className: "text-current/70 hover:text-current",
|
|
13025
|
+
children: "\xD7"
|
|
13026
|
+
}
|
|
13027
|
+
)
|
|
13028
|
+
]
|
|
13029
|
+
},
|
|
13030
|
+
String(candidate)
|
|
13031
|
+
);
|
|
13032
|
+
}) }),
|
|
13033
|
+
/* @__PURE__ */ jsxs8("div", { className: "mt-4 flex gap-2", children: [
|
|
13034
|
+
/* @__PURE__ */ jsx12(
|
|
13035
|
+
"button",
|
|
13036
|
+
{
|
|
13037
|
+
type: "button",
|
|
13038
|
+
onClick: () => openCandidatePicker(
|
|
13039
|
+
context,
|
|
13040
|
+
reg.primary
|
|
13041
|
+
),
|
|
13042
|
+
className: "rounded-xl border border-zinc-300 bg-white px-3 py-2 text-sm font-medium text-zinc-700 hover:bg-zinc-50 dark:border-zinc-700 dark:bg-zinc-900 dark:text-zinc-200 dark:hover:bg-zinc-800",
|
|
13043
|
+
children: "Add fallback"
|
|
13044
|
+
}
|
|
13045
|
+
),
|
|
13046
|
+
/* @__PURE__ */ jsx12(
|
|
13047
|
+
"button",
|
|
13048
|
+
{
|
|
13049
|
+
type: "button",
|
|
13050
|
+
onClick: () => clear(context),
|
|
13051
|
+
className: "rounded-xl border border-red-300 bg-white px-3 py-2 text-sm font-medium text-red-600 hover:bg-red-50 dark:border-red-900/50 dark:bg-zinc-900 dark:text-red-300 dark:hover:bg-red-950/20",
|
|
13052
|
+
children: "Clear"
|
|
13053
|
+
}
|
|
13054
|
+
)
|
|
13055
|
+
] })
|
|
13056
|
+
]
|
|
13057
|
+
},
|
|
13058
|
+
`${reg.scope}:${String((_a = reg.scopeId) != null ? _a : "global")}:${index}`
|
|
13059
|
+
);
|
|
13060
|
+
}) })
|
|
13061
|
+
] }),
|
|
13062
|
+
/* @__PURE__ */ jsx12(
|
|
13063
|
+
FallbackAddRegistrationDialog,
|
|
13064
|
+
{
|
|
13065
|
+
open: registrationDialogOpen,
|
|
13066
|
+
onClose: () => setRegistrationDialogOpen(false),
|
|
13067
|
+
onSelect: (context, primaryId) => {
|
|
13068
|
+
setRegistrationDialogOpen(false);
|
|
13069
|
+
openCandidatePicker(context, primaryId);
|
|
13070
|
+
}
|
|
13071
|
+
}
|
|
13072
|
+
),
|
|
13073
|
+
/* @__PURE__ */ jsx12(
|
|
13074
|
+
FallbackAddCandidatesDialog,
|
|
13075
|
+
{
|
|
13076
|
+
open: candidatePickerOpen,
|
|
13077
|
+
onClose: () => setCandidatePickerOpen(false),
|
|
13078
|
+
context: candidateContext,
|
|
13079
|
+
primaryId: candidatePrimaryId
|
|
13080
|
+
}
|
|
13081
|
+
)
|
|
13082
|
+
] });
|
|
13083
|
+
}
|
|
12695
13084
|
|
|
12696
13085
|
// src/react/fallback-editor/FallbackAddCandidatesDialog.tsx
|
|
12697
|
-
import
|
|
12698
|
-
import { jsx as
|
|
13086
|
+
import React12 from "react";
|
|
13087
|
+
import { jsx as jsx13, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
12699
13088
|
function FallbackAddCandidatesDialog({
|
|
12700
13089
|
open,
|
|
12701
13090
|
onClose,
|
|
@@ -12704,23 +13093,23 @@ function FallbackAddCandidatesDialog({
|
|
|
12704
13093
|
}) {
|
|
12705
13094
|
const { eligible, addMany } = useFallbackEditor();
|
|
12706
13095
|
const eligibleServices = useEligibleServiceList();
|
|
12707
|
-
const [query, setQuery] =
|
|
12708
|
-
const [filterEligibleOnly, setFilterEligibleOnly] =
|
|
12709
|
-
const [selected, setSelected] =
|
|
12710
|
-
const [submitting, setSubmitting] =
|
|
12711
|
-
|
|
13096
|
+
const [query, setQuery] = React12.useState("");
|
|
13097
|
+
const [filterEligibleOnly, setFilterEligibleOnly] = React12.useState(true);
|
|
13098
|
+
const [selected, setSelected] = React12.useState(/* @__PURE__ */ new Set());
|
|
13099
|
+
const [submitting, setSubmitting] = React12.useState(false);
|
|
13100
|
+
React12.useEffect(() => {
|
|
12712
13101
|
if (!open) {
|
|
12713
13102
|
setQuery("");
|
|
12714
13103
|
setFilterEligibleOnly(true);
|
|
12715
13104
|
setSelected(/* @__PURE__ */ new Set());
|
|
12716
13105
|
}
|
|
12717
13106
|
}, [open]);
|
|
12718
|
-
const allowedIds =
|
|
13107
|
+
const allowedIds = React12.useMemo(() => {
|
|
12719
13108
|
if (!context) return null;
|
|
12720
13109
|
if (!filterEligibleOnly) return null;
|
|
12721
13110
|
return new Set(eligible(context).map((id) => String(id)));
|
|
12722
13111
|
}, [context, filterEligibleOnly, eligible]);
|
|
12723
|
-
const items =
|
|
13112
|
+
const items = React12.useMemo(() => {
|
|
12724
13113
|
const q = query.trim().toLowerCase();
|
|
12725
13114
|
return eligibleServices.filter((service) => {
|
|
12726
13115
|
var _a, _b;
|
|
@@ -12755,13 +13144,13 @@ function FallbackAddCandidatesDialog({
|
|
|
12755
13144
|
}
|
|
12756
13145
|
}
|
|
12757
13146
|
if (!open || !context) return null;
|
|
12758
|
-
return /* @__PURE__ */
|
|
12759
|
-
/* @__PURE__ */
|
|
12760
|
-
/* @__PURE__ */
|
|
12761
|
-
/* @__PURE__ */
|
|
13147
|
+
return /* @__PURE__ */ jsx13("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4", children: /* @__PURE__ */ jsxs9("div", { className: "flex max-h-[85vh] w-full max-w-3xl flex-col rounded-2xl border border-zinc-200 bg-white shadow-2xl dark:border-zinc-800 dark:bg-zinc-900", children: [
|
|
13148
|
+
/* @__PURE__ */ jsxs9("div", { className: "border-b border-zinc-200 p-4 dark:border-zinc-800", children: [
|
|
13149
|
+
/* @__PURE__ */ jsx13("h3", { className: "text-base font-semibold text-zinc-900 dark:text-zinc-100", children: "Add fallback services" }),
|
|
13150
|
+
/* @__PURE__ */ jsx13("p", { className: "mt-1 text-sm text-zinc-500 dark:text-zinc-400", children: "Search and select one or more eligible fallback candidates." })
|
|
12762
13151
|
] }),
|
|
12763
|
-
/* @__PURE__ */
|
|
12764
|
-
/* @__PURE__ */
|
|
13152
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex flex-col gap-3 p-4", children: [
|
|
13153
|
+
/* @__PURE__ */ jsx13(
|
|
12765
13154
|
"input",
|
|
12766
13155
|
{
|
|
12767
13156
|
value: query,
|
|
@@ -12770,8 +13159,8 @@ function FallbackAddCandidatesDialog({
|
|
|
12770
13159
|
className: "rounded-xl border border-zinc-300 bg-white px-3 py-2 text-sm outline-none focus:border-blue-500 dark:border-zinc-700 dark:bg-zinc-950 dark:text-zinc-100"
|
|
12771
13160
|
}
|
|
12772
13161
|
),
|
|
12773
|
-
/* @__PURE__ */
|
|
12774
|
-
/* @__PURE__ */
|
|
13162
|
+
/* @__PURE__ */ jsxs9("label", { className: "inline-flex items-center gap-2 text-sm text-zinc-700 dark:text-zinc-300", children: [
|
|
13163
|
+
/* @__PURE__ */ jsx13(
|
|
12775
13164
|
"input",
|
|
12776
13165
|
{
|
|
12777
13166
|
type: "checkbox",
|
|
@@ -12782,7 +13171,7 @@ function FallbackAddCandidatesDialog({
|
|
|
12782
13171
|
),
|
|
12783
13172
|
"Filter eligible only"
|
|
12784
13173
|
] }),
|
|
12785
|
-
/* @__PURE__ */
|
|
13174
|
+
/* @__PURE__ */ jsx13(
|
|
12786
13175
|
VirtualServiceList,
|
|
12787
13176
|
{
|
|
12788
13177
|
items,
|
|
@@ -12792,13 +13181,13 @@ function FallbackAddCandidatesDialog({
|
|
|
12792
13181
|
}
|
|
12793
13182
|
)
|
|
12794
13183
|
] }),
|
|
12795
|
-
/* @__PURE__ */
|
|
12796
|
-
/* @__PURE__ */
|
|
13184
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex items-center justify-between border-t border-zinc-200 p-4 dark:border-zinc-800", children: [
|
|
13185
|
+
/* @__PURE__ */ jsxs9("div", { className: "text-sm text-zinc-500 dark:text-zinc-400", children: [
|
|
12797
13186
|
selected.size,
|
|
12798
13187
|
" selected"
|
|
12799
13188
|
] }),
|
|
12800
|
-
/* @__PURE__ */
|
|
12801
|
-
/* @__PURE__ */
|
|
13189
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex gap-2", children: [
|
|
13190
|
+
/* @__PURE__ */ jsx13(
|
|
12802
13191
|
"button",
|
|
12803
13192
|
{
|
|
12804
13193
|
type: "button",
|
|
@@ -12807,7 +13196,7 @@ function FallbackAddCandidatesDialog({
|
|
|
12807
13196
|
children: "Cancel"
|
|
12808
13197
|
}
|
|
12809
13198
|
),
|
|
12810
|
-
/* @__PURE__ */
|
|
13199
|
+
/* @__PURE__ */ jsx13(
|
|
12811
13200
|
"button",
|
|
12812
13201
|
{
|
|
12813
13202
|
type: "button",
|
|
@@ -12823,8 +13212,8 @@ function FallbackAddCandidatesDialog({
|
|
|
12823
13212
|
}
|
|
12824
13213
|
|
|
12825
13214
|
// src/react/fallback-editor/FallbackAddRegistrationDialog.tsx
|
|
12826
|
-
import
|
|
12827
|
-
import { jsx as
|
|
13215
|
+
import React13 from "react";
|
|
13216
|
+
import { jsx as jsx14, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
12828
13217
|
function FallbackAddRegistrationDialog({
|
|
12829
13218
|
open,
|
|
12830
13219
|
onClose,
|
|
@@ -12832,23 +13221,23 @@ function FallbackAddRegistrationDialog({
|
|
|
12832
13221
|
}) {
|
|
12833
13222
|
const { activeServiceId, serviceProps, snapshot } = useFallbackEditor();
|
|
12834
13223
|
const registrations = useActiveFallbackRegistrations();
|
|
12835
|
-
const [scope, setScope] =
|
|
12836
|
-
const [nodeId, setNodeId] =
|
|
12837
|
-
const mode =
|
|
13224
|
+
const [scope, setScope] = React13.useState("global");
|
|
13225
|
+
const [nodeId, setNodeId] = React13.useState("");
|
|
13226
|
+
const mode = React13.useMemo(() => {
|
|
12838
13227
|
if (snapshot) return "snapshot";
|
|
12839
13228
|
if (serviceProps) return "props";
|
|
12840
13229
|
return "none";
|
|
12841
13230
|
}, [snapshot, serviceProps]);
|
|
12842
|
-
|
|
13231
|
+
React13.useEffect(() => {
|
|
12843
13232
|
if (open) {
|
|
12844
13233
|
setScope("global");
|
|
12845
13234
|
setNodeId("");
|
|
12846
13235
|
}
|
|
12847
13236
|
}, [open]);
|
|
12848
|
-
const hasGlobal =
|
|
13237
|
+
const hasGlobal = React13.useMemo(() => {
|
|
12849
13238
|
return registrations.some((r) => r.scope === "global");
|
|
12850
13239
|
}, [registrations]);
|
|
12851
|
-
const nodeTargets =
|
|
13240
|
+
const nodeTargets = React13.useMemo(() => {
|
|
12852
13241
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
12853
13242
|
if (activeServiceId === void 0 || activeServiceId === null) {
|
|
12854
13243
|
return [];
|
|
@@ -12938,12 +13327,12 @@ function FallbackAddRegistrationDialog({
|
|
|
12938
13327
|
}
|
|
12939
13328
|
return [];
|
|
12940
13329
|
}, [mode, snapshot, serviceProps, activeServiceId]);
|
|
12941
|
-
|
|
13330
|
+
React13.useEffect(() => {
|
|
12942
13331
|
if (hasGlobal && scope === "global") {
|
|
12943
13332
|
setScope("node");
|
|
12944
13333
|
}
|
|
12945
13334
|
}, [hasGlobal, scope]);
|
|
12946
|
-
|
|
13335
|
+
React13.useEffect(() => {
|
|
12947
13336
|
if (scope === "node" && nodeId) {
|
|
12948
13337
|
const exists = nodeTargets.some((node) => node.id === nodeId);
|
|
12949
13338
|
if (!exists) setNodeId("");
|
|
@@ -12974,17 +13363,17 @@ function FallbackAddRegistrationDialog({
|
|
|
12974
13363
|
}
|
|
12975
13364
|
if (!open) return null;
|
|
12976
13365
|
const nodeScopeDisabled = nodeTargets.length === 0;
|
|
12977
|
-
return /* @__PURE__ */
|
|
12978
|
-
/* @__PURE__ */
|
|
12979
|
-
/* @__PURE__ */
|
|
12980
|
-
/* @__PURE__ */
|
|
13366
|
+
return /* @__PURE__ */ jsx14("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4", children: /* @__PURE__ */ jsxs10("div", { className: "w-full max-w-lg rounded-2xl border border-zinc-200 bg-white shadow-2xl dark:border-zinc-800 dark:bg-zinc-900", children: [
|
|
13367
|
+
/* @__PURE__ */ jsxs10("div", { className: "border-b border-zinc-200 p-4 dark:border-zinc-800", children: [
|
|
13368
|
+
/* @__PURE__ */ jsx14("h3", { className: "text-base font-semibold text-zinc-900 dark:text-zinc-100", children: "Add registration" }),
|
|
13369
|
+
/* @__PURE__ */ jsx14("p", { className: "mt-1 text-sm text-zinc-500 dark:text-zinc-400", children: "Choose the registration scope before selecting fallback candidates." })
|
|
12981
13370
|
] }),
|
|
12982
|
-
/* @__PURE__ */
|
|
12983
|
-
/* @__PURE__ */
|
|
12984
|
-
/* @__PURE__ */
|
|
12985
|
-
/* @__PURE__ */
|
|
12986
|
-
!hasGlobal && /* @__PURE__ */
|
|
12987
|
-
/* @__PURE__ */
|
|
13371
|
+
/* @__PURE__ */ jsxs10("div", { className: "space-y-4 p-4", children: [
|
|
13372
|
+
/* @__PURE__ */ jsxs10("div", { className: "space-y-2", children: [
|
|
13373
|
+
/* @__PURE__ */ jsx14("div", { className: "text-sm font-medium text-zinc-900 dark:text-zinc-100", children: "Scope" }),
|
|
13374
|
+
/* @__PURE__ */ jsxs10("div", { className: "grid gap-2", children: [
|
|
13375
|
+
!hasGlobal && /* @__PURE__ */ jsxs10("label", { className: "flex cursor-pointer items-start gap-3 rounded-xl border border-zinc-200 p-3 dark:border-zinc-800", children: [
|
|
13376
|
+
/* @__PURE__ */ jsx14(
|
|
12988
13377
|
"input",
|
|
12989
13378
|
{
|
|
12990
13379
|
type: "radio",
|
|
@@ -12994,12 +13383,12 @@ function FallbackAddRegistrationDialog({
|
|
|
12994
13383
|
className: "mt-1 h-4 w-4"
|
|
12995
13384
|
}
|
|
12996
13385
|
),
|
|
12997
|
-
/* @__PURE__ */
|
|
12998
|
-
/* @__PURE__ */
|
|
12999
|
-
/* @__PURE__ */
|
|
13386
|
+
/* @__PURE__ */ jsxs10("div", { children: [
|
|
13387
|
+
/* @__PURE__ */ jsx14("div", { className: "text-sm font-medium text-zinc-900 dark:text-zinc-100", children: "Global" }),
|
|
13388
|
+
/* @__PURE__ */ jsx14("div", { className: "mt-1 text-xs text-zinc-500 dark:text-zinc-400", children: "Use one global registration for this primary service." })
|
|
13000
13389
|
] })
|
|
13001
13390
|
] }),
|
|
13002
|
-
/* @__PURE__ */
|
|
13391
|
+
/* @__PURE__ */ jsxs10(
|
|
13003
13392
|
"label",
|
|
13004
13393
|
{
|
|
13005
13394
|
className: [
|
|
@@ -13007,7 +13396,7 @@ function FallbackAddRegistrationDialog({
|
|
|
13007
13396
|
nodeScopeDisabled ? "cursor-not-allowed border-zinc-200 opacity-60 dark:border-zinc-800" : "cursor-pointer border-zinc-200 dark:border-zinc-800"
|
|
13008
13397
|
].join(" "),
|
|
13009
13398
|
children: [
|
|
13010
|
-
/* @__PURE__ */
|
|
13399
|
+
/* @__PURE__ */ jsx14(
|
|
13011
13400
|
"input",
|
|
13012
13401
|
{
|
|
13013
13402
|
type: "radio",
|
|
@@ -13018,26 +13407,26 @@ function FallbackAddRegistrationDialog({
|
|
|
13018
13407
|
className: "mt-1 h-4 w-4"
|
|
13019
13408
|
}
|
|
13020
13409
|
),
|
|
13021
|
-
/* @__PURE__ */
|
|
13022
|
-
/* @__PURE__ */
|
|
13023
|
-
/* @__PURE__ */
|
|
13410
|
+
/* @__PURE__ */ jsxs10("div", { children: [
|
|
13411
|
+
/* @__PURE__ */ jsx14("div", { className: "text-sm font-medium text-zinc-900 dark:text-zinc-100", children: "Node" }),
|
|
13412
|
+
/* @__PURE__ */ jsx14("div", { className: "mt-1 text-xs text-zinc-500 dark:text-zinc-400", children: mode === "snapshot" ? "Pick a node currently active in the order snapshot for this primary service." : mode === "props" ? "Pick a tag, field, or option from ServiceProps that maps to this primary service." : "Node-scoped registration is unavailable without OrderSnapshot or ServiceProps." })
|
|
13024
13413
|
] })
|
|
13025
13414
|
]
|
|
13026
13415
|
}
|
|
13027
13416
|
)
|
|
13028
13417
|
] })
|
|
13029
13418
|
] }),
|
|
13030
|
-
scope === "node" && /* @__PURE__ */
|
|
13031
|
-
/* @__PURE__ */
|
|
13032
|
-
/* @__PURE__ */
|
|
13419
|
+
scope === "node" && /* @__PURE__ */ jsxs10("div", { className: "space-y-2", children: [
|
|
13420
|
+
/* @__PURE__ */ jsx14("div", { className: "text-sm font-medium text-zinc-900 dark:text-zinc-100", children: "Node id" }),
|
|
13421
|
+
/* @__PURE__ */ jsxs10(
|
|
13033
13422
|
"select",
|
|
13034
13423
|
{
|
|
13035
13424
|
value: nodeId,
|
|
13036
13425
|
onChange: (e) => setNodeId(e.target.value),
|
|
13037
13426
|
className: "w-full rounded-xl border border-zinc-300 bg-white px-3 py-2 text-sm outline-none focus:border-blue-500 dark:border-zinc-700 dark:bg-zinc-950 dark:text-zinc-100",
|
|
13038
13427
|
children: [
|
|
13039
|
-
/* @__PURE__ */
|
|
13040
|
-
nodeTargets.map((node) => /* @__PURE__ */
|
|
13428
|
+
/* @__PURE__ */ jsx14("option", { value: "", children: "Select node\u2026" }),
|
|
13429
|
+
nodeTargets.map((node) => /* @__PURE__ */ jsxs10("option", { value: node.id, children: [
|
|
13041
13430
|
"[",
|
|
13042
13431
|
node.kind,
|
|
13043
13432
|
"] ",
|
|
@@ -13048,11 +13437,11 @@ function FallbackAddRegistrationDialog({
|
|
|
13048
13437
|
]
|
|
13049
13438
|
}
|
|
13050
13439
|
),
|
|
13051
|
-
nodeScopeDisabled ? /* @__PURE__ */
|
|
13440
|
+
nodeScopeDisabled ? /* @__PURE__ */ jsx14("div", { className: "text-xs text-zinc-500 dark:text-zinc-400", children: mode === "snapshot" ? "No active snapshot nodes were found for this primary service." : mode === "props" ? "No ServiceProps nodes were found for this primary service." : "Node-scoped registration requires either OrderSnapshot or ServiceProps." }) : null
|
|
13052
13441
|
] })
|
|
13053
13442
|
] }),
|
|
13054
|
-
/* @__PURE__ */
|
|
13055
|
-
/* @__PURE__ */
|
|
13443
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex items-center justify-end gap-2 border-t border-zinc-200 p-4 dark:border-zinc-800", children: [
|
|
13444
|
+
/* @__PURE__ */ jsx14(
|
|
13056
13445
|
"button",
|
|
13057
13446
|
{
|
|
13058
13447
|
type: "button",
|
|
@@ -13061,7 +13450,7 @@ function FallbackAddRegistrationDialog({
|
|
|
13061
13450
|
children: "Cancel"
|
|
13062
13451
|
}
|
|
13063
13452
|
),
|
|
13064
|
-
/* @__PURE__ */
|
|
13453
|
+
/* @__PURE__ */ jsx14(
|
|
13065
13454
|
"button",
|
|
13066
13455
|
{
|
|
13067
13456
|
type: "button",
|
|
@@ -13104,169 +13493,6 @@ function resolveNodeMeta(props, nodeId) {
|
|
|
13104
13493
|
}
|
|
13105
13494
|
return { kind: "node", label: nodeId };
|
|
13106
13495
|
}
|
|
13107
|
-
|
|
13108
|
-
// src/react/fallback-editor/FallbackRegistrationsPanel.tsx
|
|
13109
|
-
import { Fragment, jsx as jsx14, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
13110
|
-
function FallbackRegistrationsPanel() {
|
|
13111
|
-
const { activeServiceId, remove: remove2, clear, check } = useFallbackEditor();
|
|
13112
|
-
const registrations = useActiveFallbackRegistrations();
|
|
13113
|
-
const eligibleServices = useEligibleServiceList();
|
|
13114
|
-
const [candidatePickerOpen, setCandidatePickerOpen] = React13.useState(false);
|
|
13115
|
-
const [candidateContext, setCandidateContext] = React13.useState(null);
|
|
13116
|
-
const [candidatePrimaryId, setCandidatePrimaryId] = React13.useState(void 0);
|
|
13117
|
-
const [registrationDialogOpen, setRegistrationDialogOpen] = React13.useState(false);
|
|
13118
|
-
const makeContext = React13.useCallback(
|
|
13119
|
-
(registration) => {
|
|
13120
|
-
if (registration.scope === "global") {
|
|
13121
|
-
return {
|
|
13122
|
-
scope: "global",
|
|
13123
|
-
primary: registration.primary
|
|
13124
|
-
};
|
|
13125
|
-
}
|
|
13126
|
-
return {
|
|
13127
|
-
scope: "node",
|
|
13128
|
-
nodeId: registration.scopeId
|
|
13129
|
-
};
|
|
13130
|
-
},
|
|
13131
|
-
[]
|
|
13132
|
-
);
|
|
13133
|
-
const openCandidatePicker = React13.useCallback(
|
|
13134
|
-
(context, primaryId) => {
|
|
13135
|
-
setCandidateContext(context);
|
|
13136
|
-
setCandidatePrimaryId(primaryId);
|
|
13137
|
-
setCandidatePickerOpen(true);
|
|
13138
|
-
},
|
|
13139
|
-
[]
|
|
13140
|
-
);
|
|
13141
|
-
if (activeServiceId === void 0 || activeServiceId === null) {
|
|
13142
|
-
return /* @__PURE__ */ jsx14("section", { className: "rounded-2xl border border-zinc-200 bg-white p-4 shadow-sm dark:border-zinc-800 dark:bg-zinc-900", children: /* @__PURE__ */ jsx14("div", { className: "rounded-2xl border border-dashed border-zinc-300 p-6 text-sm text-zinc-500 dark:border-zinc-700 dark:text-zinc-400", children: "Select a primary service to start editing." }) });
|
|
13143
|
-
}
|
|
13144
|
-
return /* @__PURE__ */ jsxs10(Fragment, { children: [
|
|
13145
|
-
/* @__PURE__ */ jsxs10("section", { className: "rounded-2xl border border-zinc-200 bg-white p-4 shadow-sm dark:border-zinc-800 dark:bg-zinc-900", children: [
|
|
13146
|
-
/* @__PURE__ */ jsxs10("div", { className: "mb-4 flex items-start justify-between gap-3", children: [
|
|
13147
|
-
/* @__PURE__ */ jsxs10("div", { children: [
|
|
13148
|
-
/* @__PURE__ */ jsx14("h3", { className: "text-sm font-semibold text-zinc-900 dark:text-zinc-100", children: "Registered fallbacks" }),
|
|
13149
|
-
/* @__PURE__ */ jsx14("p", { className: "mt-1 text-xs text-zinc-500 dark:text-zinc-400", children: "Use eligible services as fallback candidates for the selected primary." })
|
|
13150
|
-
] }),
|
|
13151
|
-
/* @__PURE__ */ jsx14(
|
|
13152
|
-
"button",
|
|
13153
|
-
{
|
|
13154
|
-
type: "button",
|
|
13155
|
-
onClick: () => setRegistrationDialogOpen(true),
|
|
13156
|
-
className: "rounded-xl border border-zinc-300 bg-white px-3 py-2 text-sm font-medium text-zinc-700 hover:bg-zinc-50 dark:border-zinc-700 dark:bg-zinc-950 dark:text-zinc-200 dark:hover:bg-zinc-800",
|
|
13157
|
-
children: "Add registration"
|
|
13158
|
-
}
|
|
13159
|
-
)
|
|
13160
|
-
] }),
|
|
13161
|
-
/* @__PURE__ */ jsx14("div", { className: "space-y-4", children: registrations.length === 0 ? /* @__PURE__ */ jsx14("div", { className: "rounded-2xl border border-dashed border-zinc-300 p-6 text-sm text-zinc-500 dark:border-zinc-700 dark:text-zinc-400", children: "No registrations yet for this primary service." }) : registrations.map((reg, index) => {
|
|
13162
|
-
var _a;
|
|
13163
|
-
const context = makeContext(reg);
|
|
13164
|
-
const candidates = reg.services;
|
|
13165
|
-
return /* @__PURE__ */ jsxs10(
|
|
13166
|
-
"div",
|
|
13167
|
-
{
|
|
13168
|
-
className: "rounded-2xl border border-zinc-200 bg-zinc-50 p-4 dark:border-zinc-800 dark:bg-zinc-950",
|
|
13169
|
-
children: [
|
|
13170
|
-
/* @__PURE__ */ jsxs10("div", { className: "flex flex-wrap items-start justify-between gap-3", children: [
|
|
13171
|
-
/* @__PURE__ */ jsxs10("div", { children: [
|
|
13172
|
-
/* @__PURE__ */ jsx14("div", { className: "text-sm font-semibold text-zinc-900 dark:text-zinc-100", children: reg.scope === "global" ? "Global registration" : `Node \xB7 ${reg.scopeId}` }),
|
|
13173
|
-
/* @__PURE__ */ jsxs10("div", { className: "mt-1 text-xs text-zinc-500 dark:text-zinc-400", children: [
|
|
13174
|
-
"Primary #",
|
|
13175
|
-
String(reg.primary)
|
|
13176
|
-
] })
|
|
13177
|
-
] }),
|
|
13178
|
-
/* @__PURE__ */ jsxs10("span", { className: "rounded-full border border-zinc-200 bg-white px-2 py-1 text-[11px] text-zinc-600 dark:border-zinc-700 dark:bg-zinc-900 dark:text-zinc-300", children: [
|
|
13179
|
-
reg.scope,
|
|
13180
|
-
reg.scopeId ? ` \xB7 ${reg.scopeId}` : ""
|
|
13181
|
-
] })
|
|
13182
|
-
] }),
|
|
13183
|
-
/* @__PURE__ */ jsx14("div", { className: "mt-4 flex flex-wrap gap-2", children: candidates.length === 0 ? /* @__PURE__ */ jsx14("span", { className: "text-xs text-zinc-500 dark:text-zinc-400", children: "No fallback services yet." }) : candidates.map((candidate) => {
|
|
13184
|
-
var _a2;
|
|
13185
|
-
const preview = check(context, [
|
|
13186
|
-
candidate
|
|
13187
|
-
]);
|
|
13188
|
-
const rejected = preview.rejected[0];
|
|
13189
|
-
const tone = rejected ? "border-red-200 bg-red-50 text-red-700 dark:border-red-900/50 dark:bg-red-950/30 dark:text-red-300" : "border-zinc-200 bg-white text-zinc-700 dark:border-zinc-700 dark:bg-zinc-900 dark:text-zinc-200";
|
|
13190
|
-
const service = eligibleServices.find(
|
|
13191
|
-
(s) => String(s.id) === String(candidate)
|
|
13192
|
-
);
|
|
13193
|
-
return /* @__PURE__ */ jsxs10(
|
|
13194
|
-
"div",
|
|
13195
|
-
{
|
|
13196
|
-
className: `inline-flex items-center gap-2 rounded-xl border px-3 py-2 text-xs ${tone}`,
|
|
13197
|
-
children: [
|
|
13198
|
-
/* @__PURE__ */ jsx14("span", { children: service ? `#${String(service.id)} \xB7 ${(_a2 = service.name) != null ? _a2 : "Unnamed"}` : `#${String(candidate)}` }),
|
|
13199
|
-
rejected ? /* @__PURE__ */ jsx14("span", { className: "rounded-full border border-current/20 px-2 py-0.5 text-[10px]", children: rejected.reasons.join(
|
|
13200
|
-
", "
|
|
13201
|
-
) }) : /* @__PURE__ */ jsx14("span", { className: "rounded-full border border-current/20 px-2 py-0.5 text-[10px]", children: "valid" }),
|
|
13202
|
-
/* @__PURE__ */ jsx14(
|
|
13203
|
-
"button",
|
|
13204
|
-
{
|
|
13205
|
-
type: "button",
|
|
13206
|
-
onClick: () => remove2(
|
|
13207
|
-
context,
|
|
13208
|
-
candidate
|
|
13209
|
-
),
|
|
13210
|
-
className: "text-current/70 hover:text-current",
|
|
13211
|
-
children: "\xD7"
|
|
13212
|
-
}
|
|
13213
|
-
)
|
|
13214
|
-
]
|
|
13215
|
-
},
|
|
13216
|
-
String(candidate)
|
|
13217
|
-
);
|
|
13218
|
-
}) }),
|
|
13219
|
-
/* @__PURE__ */ jsxs10("div", { className: "mt-4 flex gap-2", children: [
|
|
13220
|
-
/* @__PURE__ */ jsx14(
|
|
13221
|
-
"button",
|
|
13222
|
-
{
|
|
13223
|
-
type: "button",
|
|
13224
|
-
onClick: () => openCandidatePicker(
|
|
13225
|
-
context,
|
|
13226
|
-
reg.primary
|
|
13227
|
-
),
|
|
13228
|
-
className: "rounded-xl border border-zinc-300 bg-white px-3 py-2 text-sm font-medium text-zinc-700 hover:bg-zinc-50 dark:border-zinc-700 dark:bg-zinc-900 dark:text-zinc-200 dark:hover:bg-zinc-800",
|
|
13229
|
-
children: "Add fallback"
|
|
13230
|
-
}
|
|
13231
|
-
),
|
|
13232
|
-
/* @__PURE__ */ jsx14(
|
|
13233
|
-
"button",
|
|
13234
|
-
{
|
|
13235
|
-
type: "button",
|
|
13236
|
-
onClick: () => clear(context),
|
|
13237
|
-
className: "rounded-xl border border-red-300 bg-white px-3 py-2 text-sm font-medium text-red-600 hover:bg-red-50 dark:border-red-900/50 dark:bg-zinc-900 dark:text-red-300 dark:hover:bg-red-950/20",
|
|
13238
|
-
children: "Clear"
|
|
13239
|
-
}
|
|
13240
|
-
)
|
|
13241
|
-
] })
|
|
13242
|
-
]
|
|
13243
|
-
},
|
|
13244
|
-
`${reg.scope}:${String((_a = reg.scopeId) != null ? _a : "global")}:${index}`
|
|
13245
|
-
);
|
|
13246
|
-
}) })
|
|
13247
|
-
] }),
|
|
13248
|
-
/* @__PURE__ */ jsx14(
|
|
13249
|
-
FallbackAddRegistrationDialog,
|
|
13250
|
-
{
|
|
13251
|
-
open: registrationDialogOpen,
|
|
13252
|
-
onClose: () => setRegistrationDialogOpen(false),
|
|
13253
|
-
onSelect: (context, primaryId) => {
|
|
13254
|
-
setRegistrationDialogOpen(false);
|
|
13255
|
-
openCandidatePicker(context, primaryId);
|
|
13256
|
-
}
|
|
13257
|
-
}
|
|
13258
|
-
),
|
|
13259
|
-
/* @__PURE__ */ jsx14(
|
|
13260
|
-
FallbackAddCandidatesDialog,
|
|
13261
|
-
{
|
|
13262
|
-
open: candidatePickerOpen,
|
|
13263
|
-
onClose: () => setCandidatePickerOpen(false),
|
|
13264
|
-
context: candidateContext,
|
|
13265
|
-
primaryId: candidatePrimaryId
|
|
13266
|
-
}
|
|
13267
|
-
)
|
|
13268
|
-
] });
|
|
13269
|
-
}
|
|
13270
13496
|
export {
|
|
13271
13497
|
CanvasAPI,
|
|
13272
13498
|
EventBus,
|