jupiter-dynamic-forms 1.20.2 → 1.20.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/concept-tree.d.ts.map +1 -1
- package/dist/core/dynamic-form.d.ts +41 -0
- package/dist/core/dynamic-form.d.ts.map +1 -1
- package/dist/core/form-field.d.ts.map +1 -1
- package/dist/core/form-section.d.ts +4 -0
- package/dist/core/form-section.d.ts.map +1 -1
- package/dist/core/formula-validation-dialog.d.ts +30 -0
- package/dist/core/formula-validation-dialog.d.ts.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +349 -75
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1666 -293
- package/dist/index.mjs.map +1 -1
- package/dist/schema/types.d.ts +26 -0
- package/dist/schema/types.d.ts.map +1 -1
- package/dist/schema/xbrl-types.d.ts +67 -0
- package/dist/schema/xbrl-types.d.ts.map +1 -1
- package/dist/utils/formula-constants.d.ts +7 -0
- package/dist/utils/formula-constants.d.ts.map +1 -0
- package/dist/utils/formula-expression-evaluator.d.ts +64 -0
- package/dist/utils/formula-expression-evaluator.d.ts.map +1 -0
- package/dist/utils/formula-precondition-evaluator.d.ts +33 -0
- package/dist/utils/formula-precondition-evaluator.d.ts.map +1 -0
- package/dist/utils/formula-resolution-context.d.ts +45 -0
- package/dist/utils/formula-resolution-context.d.ts.map +1 -0
- package/dist/utils/formula-variable-resolver.d.ts +30 -0
- package/dist/utils/formula-variable-resolver.d.ts.map +1 -0
- package/dist/utils/total-group-resolver.d.ts +68 -0
- package/dist/utils/total-group-resolver.d.ts.map +1 -0
- package/dist/utils/total-label.d.ts +9 -0
- package/dist/utils/total-label.d.ts.map +1 -0
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1817,6 +1817,15 @@ const calculationWarning$1 = {
|
|
|
1817
1817
|
added: "Added",
|
|
1818
1818
|
subtracted: "Subtracted (opposite balance)"
|
|
1819
1819
|
};
|
|
1820
|
+
const formulaValidation$1 = {
|
|
1821
|
+
dialogTitle: "Formula check results",
|
|
1822
|
+
allPassed: "All formula checks passed",
|
|
1823
|
+
summaryCount: "{{failed}} of {{total}} checks failed",
|
|
1824
|
+
summaryCountBreakdown: "{{warnings}} warnings, {{errors}} errors",
|
|
1825
|
+
severityWarning: "Warning",
|
|
1826
|
+
severityError: "Error",
|
|
1827
|
+
close: "Close"
|
|
1828
|
+
};
|
|
1820
1829
|
const enTranslations = {
|
|
1821
1830
|
conceptInfo: conceptInfo$1,
|
|
1822
1831
|
form: form$1,
|
|
@@ -1828,7 +1837,8 @@ const enTranslations = {
|
|
|
1828
1837
|
validation: validation$1,
|
|
1829
1838
|
xbrlValidation: xbrlValidation$1,
|
|
1830
1839
|
error: error$1,
|
|
1831
|
-
calculationWarning: calculationWarning$1
|
|
1840
|
+
calculationWarning: calculationWarning$1,
|
|
1841
|
+
formulaValidation: formulaValidation$1
|
|
1832
1842
|
};
|
|
1833
1843
|
const conceptInfo = {
|
|
1834
1844
|
title: "Conceptinformatie",
|
|
@@ -2012,6 +2022,15 @@ const calculationWarning = {
|
|
|
2012
2022
|
added: "Opgeteld",
|
|
2013
2023
|
subtracted: "Afgetrokken (tegengestelde balans)"
|
|
2014
2024
|
};
|
|
2025
|
+
const formulaValidation = {
|
|
2026
|
+
dialogTitle: "Resultaten formulecontrole",
|
|
2027
|
+
allPassed: "Alle formulecontroles geslaagd",
|
|
2028
|
+
summaryCount: "{{failed}} van {{total}} controles mislukt",
|
|
2029
|
+
summaryCountBreakdown: "{{warnings}} waarschuwingen, {{errors}} fouten",
|
|
2030
|
+
severityWarning: "Waarschuwing",
|
|
2031
|
+
severityError: "Fout",
|
|
2032
|
+
close: "Sluiten"
|
|
2033
|
+
};
|
|
2015
2034
|
const nlTranslations = {
|
|
2016
2035
|
conceptInfo,
|
|
2017
2036
|
form,
|
|
@@ -2023,7 +2042,8 @@ const nlTranslations = {
|
|
|
2023
2042
|
validation,
|
|
2024
2043
|
xbrlValidation,
|
|
2025
2044
|
error,
|
|
2026
|
-
calculationWarning
|
|
2045
|
+
calculationWarning,
|
|
2046
|
+
formulaValidation
|
|
2027
2047
|
};
|
|
2028
2048
|
const translations = {
|
|
2029
2049
|
en: enTranslations,
|
|
@@ -2102,6 +2122,9 @@ class I18n {
|
|
|
2102
2122
|
}
|
|
2103
2123
|
}
|
|
2104
2124
|
I18n.currentLanguage = "en";
|
|
2125
|
+
function isTotalLabel$1(preferredLabel) {
|
|
2126
|
+
return !!(preferredLabel == null ? void 0 : preferredLabel.toLowerCase().includes("totallabel"));
|
|
2127
|
+
}
|
|
2105
2128
|
class DraftStorageService {
|
|
2106
2129
|
constructor(useSessionStorage = false) {
|
|
2107
2130
|
this.DRAFT_DATA_KEY = "jupiter-form-draft-data";
|
|
@@ -2261,7 +2284,7 @@ class DraftStorageService {
|
|
|
2261
2284
|
/**
|
|
2262
2285
|
* Create metadata snapshot from current form state
|
|
2263
2286
|
*/
|
|
2264
|
-
createMetadataSnapshot(periodStartDate, periodEndDate, language, selectedRoleIds, allSections, typedMemberData, periodPreferences, periodData, unitData, reportingLanguage = "en", repeatCounts, decimalsData, roleCompletedStates, hiddenColumns) {
|
|
2287
|
+
createMetadataSnapshot(periodStartDate, periodEndDate, language, selectedRoleIds, allSections, typedMemberData, periodPreferences, periodData, unitData, reportingLanguage = "en", repeatCounts, decimalsData, roleCompletedStates, hiddenColumns, totalManuallyEditedData) {
|
|
2265
2288
|
return {
|
|
2266
2289
|
periodStartDate,
|
|
2267
2290
|
periodEndDate,
|
|
@@ -2278,6 +2301,7 @@ class DraftStorageService {
|
|
|
2278
2301
|
repeatCounts,
|
|
2279
2302
|
roleCompletedStates,
|
|
2280
2303
|
hiddenColumns,
|
|
2304
|
+
totalManuallyEditedData,
|
|
2281
2305
|
schemaVersion: this.STORAGE_VERSION
|
|
2282
2306
|
};
|
|
2283
2307
|
}
|
|
@@ -2300,6 +2324,801 @@ class DraftStorageService {
|
|
|
2300
2324
|
return { compatible, warnings };
|
|
2301
2325
|
}
|
|
2302
2326
|
}
|
|
2327
|
+
const CALCULATION_TOLERANCE = 0.01;
|
|
2328
|
+
class FormulaExpressionError extends Error {
|
|
2329
|
+
constructor(message, test, reason = "unsupported-syntax") {
|
|
2330
|
+
super(message);
|
|
2331
|
+
this.test = test;
|
|
2332
|
+
this.reason = reason;
|
|
2333
|
+
this.name = "FormulaExpressionError";
|
|
2334
|
+
}
|
|
2335
|
+
}
|
|
2336
|
+
const TOKEN_PATTERN = /\s*(?:(\$[A-Za-z_][\w-]*)|(-?\d+(?:\.\d+)?)|([A-Za-z][\w:-]*)|('[^']*')|(\()|(\))|(\+)|(-)|(=))/y;
|
|
2337
|
+
function tokenize(test) {
|
|
2338
|
+
const tokens = [];
|
|
2339
|
+
TOKEN_PATTERN.lastIndex = 0;
|
|
2340
|
+
let index = 0;
|
|
2341
|
+
while (index < test.length) {
|
|
2342
|
+
TOKEN_PATTERN.lastIndex = index;
|
|
2343
|
+
const match = TOKEN_PATTERN.exec(test);
|
|
2344
|
+
if (!match || match.index !== index) {
|
|
2345
|
+
if (/^\s*$/.test(test.slice(index)))
|
|
2346
|
+
break;
|
|
2347
|
+
throw new FormulaExpressionError(`Unrecognized token at position ${index}: "${test.slice(index, index + 10)}..."`, test, "unsupported-syntax");
|
|
2348
|
+
}
|
|
2349
|
+
const [full, variable, number, ident, string, lparen, rparen, plus, minus, equals] = match;
|
|
2350
|
+
if (variable)
|
|
2351
|
+
tokens.push({ type: "VARIABLE", value: variable.slice(1) });
|
|
2352
|
+
else if (number)
|
|
2353
|
+
tokens.push({ type: "NUMBER", value: number });
|
|
2354
|
+
else if (ident)
|
|
2355
|
+
tokens.push({ type: "IDENT", value: ident });
|
|
2356
|
+
else if (string)
|
|
2357
|
+
tokens.push({ type: "STRING", value: string.slice(1, -1) });
|
|
2358
|
+
else if (lparen)
|
|
2359
|
+
tokens.push({ type: "LPAREN", value: lparen });
|
|
2360
|
+
else if (rparen)
|
|
2361
|
+
tokens.push({ type: "RPAREN", value: rparen });
|
|
2362
|
+
else if (plus)
|
|
2363
|
+
tokens.push({ type: "PLUS", value: plus });
|
|
2364
|
+
else if (minus)
|
|
2365
|
+
tokens.push({ type: "MINUS", value: minus });
|
|
2366
|
+
else if (equals)
|
|
2367
|
+
tokens.push({ type: "EQUALS", value: equals });
|
|
2368
|
+
index += full.length;
|
|
2369
|
+
}
|
|
2370
|
+
tokens.push({ type: "EOF", value: "" });
|
|
2371
|
+
return tokens;
|
|
2372
|
+
}
|
|
2373
|
+
class Parser {
|
|
2374
|
+
constructor(tokens, test) {
|
|
2375
|
+
this.tokens = tokens;
|
|
2376
|
+
this.test = test;
|
|
2377
|
+
this.pos = 0;
|
|
2378
|
+
}
|
|
2379
|
+
peek() {
|
|
2380
|
+
return this.tokens[this.pos];
|
|
2381
|
+
}
|
|
2382
|
+
next() {
|
|
2383
|
+
return this.tokens[this.pos++];
|
|
2384
|
+
}
|
|
2385
|
+
expect(type) {
|
|
2386
|
+
const token = this.next();
|
|
2387
|
+
if (token.type !== type) {
|
|
2388
|
+
throw new FormulaExpressionError(
|
|
2389
|
+
`Expected ${type} but got ${token.type} ("${token.value}")`,
|
|
2390
|
+
this.test,
|
|
2391
|
+
"parse-error"
|
|
2392
|
+
);
|
|
2393
|
+
}
|
|
2394
|
+
return token;
|
|
2395
|
+
}
|
|
2396
|
+
parseBoolExpr() {
|
|
2397
|
+
const node = this.parseOrExpr();
|
|
2398
|
+
if (this.peek().type !== "EOF") {
|
|
2399
|
+
throw new FormulaExpressionError(
|
|
2400
|
+
`Unexpected trailing token "${this.peek().value}"`,
|
|
2401
|
+
this.test,
|
|
2402
|
+
"unsupported-syntax"
|
|
2403
|
+
);
|
|
2404
|
+
}
|
|
2405
|
+
return node;
|
|
2406
|
+
}
|
|
2407
|
+
parseOrExpr() {
|
|
2408
|
+
const terms = [this.parseAndExpr()];
|
|
2409
|
+
while (this.peek().type === "IDENT" && this.peek().value === "or") {
|
|
2410
|
+
this.next();
|
|
2411
|
+
terms.push(this.parseAndExpr());
|
|
2412
|
+
}
|
|
2413
|
+
return terms.length === 1 ? terms[0] : { kind: "or", terms };
|
|
2414
|
+
}
|
|
2415
|
+
parseAndExpr() {
|
|
2416
|
+
const terms = [this.parseBoolTerm()];
|
|
2417
|
+
while (this.peek().type === "IDENT" && this.peek().value === "and") {
|
|
2418
|
+
this.next();
|
|
2419
|
+
terms.push(this.parseBoolTerm());
|
|
2420
|
+
}
|
|
2421
|
+
return terms.length === 1 ? terms[0] : { kind: "and", terms };
|
|
2422
|
+
}
|
|
2423
|
+
parseBoolTerm() {
|
|
2424
|
+
const token = this.peek();
|
|
2425
|
+
if (token.type === "IDENT" && token.value === "not") {
|
|
2426
|
+
this.next();
|
|
2427
|
+
this.expect("LPAREN");
|
|
2428
|
+
const arg = this.parseOrExpr();
|
|
2429
|
+
this.expect("RPAREN");
|
|
2430
|
+
return { kind: "not", arg };
|
|
2431
|
+
}
|
|
2432
|
+
if (token.type === "IDENT" && token.value === "empty") {
|
|
2433
|
+
this.next();
|
|
2434
|
+
this.expect("LPAREN");
|
|
2435
|
+
const variable = this.expect("VARIABLE").value;
|
|
2436
|
+
this.expect("RPAREN");
|
|
2437
|
+
return { kind: "empty", variable };
|
|
2438
|
+
}
|
|
2439
|
+
if (token.type === "IDENT" && token.value === "xff:has-fallback-value") {
|
|
2440
|
+
this.next();
|
|
2441
|
+
this.expect("LPAREN");
|
|
2442
|
+
const inner = this.next();
|
|
2443
|
+
if (inner.type !== "IDENT" || inner.value !== "xs:QName") {
|
|
2444
|
+
throw new FormulaExpressionError(
|
|
2445
|
+
`Expected xs:QName(...) inside xff:has-fallback-value(...), got "${inner.value}"`,
|
|
2446
|
+
this.test,
|
|
2447
|
+
"unsupported-syntax"
|
|
2448
|
+
);
|
|
2449
|
+
}
|
|
2450
|
+
this.expect("LPAREN");
|
|
2451
|
+
const variableName = this.expect("STRING").value;
|
|
2452
|
+
this.expect("RPAREN");
|
|
2453
|
+
this.expect("RPAREN");
|
|
2454
|
+
return { kind: "hasFallbackValue", variableName };
|
|
2455
|
+
}
|
|
2456
|
+
const left = this.parseValueExpr();
|
|
2457
|
+
const opToken = this.peek();
|
|
2458
|
+
if (opToken.type === "EQUALS") {
|
|
2459
|
+
this.next();
|
|
2460
|
+
return { kind: "comparison", op: "=", left, right: this.parseValueExpr() };
|
|
2461
|
+
}
|
|
2462
|
+
if (opToken.type === "IDENT" && opToken.value === "eq") {
|
|
2463
|
+
this.next();
|
|
2464
|
+
return { kind: "comparison", op: "eq", left, right: this.parseValueExpr() };
|
|
2465
|
+
}
|
|
2466
|
+
throw new FormulaExpressionError(
|
|
2467
|
+
`Expected a comparison operator ("=" or "eq") after value expression, got "${opToken.value}"`,
|
|
2468
|
+
this.test,
|
|
2469
|
+
"unsupported-syntax"
|
|
2470
|
+
);
|
|
2471
|
+
}
|
|
2472
|
+
parseValueExpr() {
|
|
2473
|
+
const terms = [];
|
|
2474
|
+
let sign = 1;
|
|
2475
|
+
if (this.peek().type === "PLUS") {
|
|
2476
|
+
this.next();
|
|
2477
|
+
} else if (this.peek().type === "MINUS") {
|
|
2478
|
+
this.next();
|
|
2479
|
+
sign = -1;
|
|
2480
|
+
}
|
|
2481
|
+
terms.push({ sign, term: this.parseValueTerm() });
|
|
2482
|
+
while (this.peek().type === "PLUS" || this.peek().type === "MINUS") {
|
|
2483
|
+
const opSign = this.next().type === "PLUS" ? 1 : -1;
|
|
2484
|
+
terms.push({ sign: opSign, term: this.parseValueTerm() });
|
|
2485
|
+
}
|
|
2486
|
+
return terms.length === 1 && terms[0].sign === 1 ? terms[0].term : { kind: "additive", terms };
|
|
2487
|
+
}
|
|
2488
|
+
parseValueTerm() {
|
|
2489
|
+
const token = this.peek();
|
|
2490
|
+
if (token.type === "NUMBER") {
|
|
2491
|
+
this.next();
|
|
2492
|
+
return { kind: "number", value: Number(token.value) };
|
|
2493
|
+
}
|
|
2494
|
+
if (token.type === "VARIABLE") {
|
|
2495
|
+
this.next();
|
|
2496
|
+
return { kind: "variable", name: token.value };
|
|
2497
|
+
}
|
|
2498
|
+
if (token.type === "IDENT" && token.value === "sum") {
|
|
2499
|
+
this.next();
|
|
2500
|
+
this.expect("LPAREN");
|
|
2501
|
+
const variable = this.expect("VARIABLE").value;
|
|
2502
|
+
this.expect("RPAREN");
|
|
2503
|
+
return { kind: "sum", variable };
|
|
2504
|
+
}
|
|
2505
|
+
if (token.type === "LPAREN") {
|
|
2506
|
+
this.next();
|
|
2507
|
+
const inner = this.parseValueExpr();
|
|
2508
|
+
this.expect("RPAREN");
|
|
2509
|
+
return inner;
|
|
2510
|
+
}
|
|
2511
|
+
throw new FormulaExpressionError(
|
|
2512
|
+
`Expected a number, variable, sum(...), or parenthesized expression, got "${token.value}"`,
|
|
2513
|
+
this.test,
|
|
2514
|
+
"unsupported-syntax"
|
|
2515
|
+
);
|
|
2516
|
+
}
|
|
2517
|
+
}
|
|
2518
|
+
function lookup(bindings, name) {
|
|
2519
|
+
return bindings.get(name);
|
|
2520
|
+
}
|
|
2521
|
+
function evalSum(variable, bindings) {
|
|
2522
|
+
const binding = lookup(bindings, variable);
|
|
2523
|
+
if (binding === void 0)
|
|
2524
|
+
return 0;
|
|
2525
|
+
if (Array.isArray(binding))
|
|
2526
|
+
return binding.reduce((total, value) => total + value, 0);
|
|
2527
|
+
return binding;
|
|
2528
|
+
}
|
|
2529
|
+
function evalValue(node, bindings, test) {
|
|
2530
|
+
switch (node.kind) {
|
|
2531
|
+
case "number":
|
|
2532
|
+
return node.value;
|
|
2533
|
+
case "sum":
|
|
2534
|
+
return evalSum(node.variable, bindings);
|
|
2535
|
+
case "variable": {
|
|
2536
|
+
const binding = lookup(bindings, node.name);
|
|
2537
|
+
if (binding === void 0) {
|
|
2538
|
+
throw new FormulaExpressionError(
|
|
2539
|
+
`Variable "$${node.name}" has no bound fact and cannot be evaluated directly (only sum()/empty() tolerate an unbound variable)`,
|
|
2540
|
+
test,
|
|
2541
|
+
"unbound-variable"
|
|
2542
|
+
);
|
|
2543
|
+
}
|
|
2544
|
+
if (Array.isArray(binding)) {
|
|
2545
|
+
throw new FormulaExpressionError(
|
|
2546
|
+
`Variable "$${node.name}" is a sequence and must be wrapped in sum(...) to be used in arithmetic`,
|
|
2547
|
+
test,
|
|
2548
|
+
"unsupported-syntax"
|
|
2549
|
+
);
|
|
2550
|
+
}
|
|
2551
|
+
return binding;
|
|
2552
|
+
}
|
|
2553
|
+
case "additive":
|
|
2554
|
+
return node.terms.reduce((total, { sign, term }) => total + sign * evalValue(term, bindings, test), 0);
|
|
2555
|
+
}
|
|
2556
|
+
}
|
|
2557
|
+
function evalBool(node, bindings, test, fallbackUsage) {
|
|
2558
|
+
switch (node.kind) {
|
|
2559
|
+
case "or":
|
|
2560
|
+
return node.terms.some((term) => evalBool(term, bindings, test, fallbackUsage));
|
|
2561
|
+
case "and":
|
|
2562
|
+
return node.terms.every((term) => evalBool(term, bindings, test, fallbackUsage));
|
|
2563
|
+
case "not":
|
|
2564
|
+
return !evalBool(node.arg, bindings, test, fallbackUsage);
|
|
2565
|
+
case "empty": {
|
|
2566
|
+
const binding = lookup(bindings, node.variable);
|
|
2567
|
+
return binding === void 0 || Array.isArray(binding) && binding.length === 0;
|
|
2568
|
+
}
|
|
2569
|
+
case "hasFallbackValue": {
|
|
2570
|
+
const usedFallback = fallbackUsage.get(node.variableName);
|
|
2571
|
+
if (usedFallback === void 0) {
|
|
2572
|
+
throw new FormulaExpressionError(
|
|
2573
|
+
`xff:has-fallback-value(xs:QName('${node.variableName}')) could not be evaluated — no fallback-usage tracked for this variable (either not one of this assertion's FACT_VARIABLEs, or it matched zero facts with no fallbackValue declared)`,
|
|
2574
|
+
test,
|
|
2575
|
+
"unbound-variable"
|
|
2576
|
+
);
|
|
2577
|
+
}
|
|
2578
|
+
return usedFallback;
|
|
2579
|
+
}
|
|
2580
|
+
case "comparison": {
|
|
2581
|
+
const left = evalValue(node.left, bindings, test);
|
|
2582
|
+
const right = evalValue(node.right, bindings, test);
|
|
2583
|
+
return Math.abs(left - right) < CALCULATION_TOLERANCE;
|
|
2584
|
+
}
|
|
2585
|
+
}
|
|
2586
|
+
}
|
|
2587
|
+
function evaluateFormulaTest(test, bindings, fallbackUsage = /* @__PURE__ */ new Map()) {
|
|
2588
|
+
const tokens = tokenize(test);
|
|
2589
|
+
const ast = new Parser(tokens, test).parseBoolExpr();
|
|
2590
|
+
return evalBool(ast, bindings, test, fallbackUsage);
|
|
2591
|
+
}
|
|
2592
|
+
const EXISTENCE_TEST_PATTERN = /^\.\s*(eq|ne|gt|lt|ge|le)\s+(-?\d+(?:\.\d+)?)$/;
|
|
2593
|
+
function compareExistence(op, count, threshold) {
|
|
2594
|
+
switch (op) {
|
|
2595
|
+
case "eq":
|
|
2596
|
+
return count === threshold;
|
|
2597
|
+
case "ne":
|
|
2598
|
+
return count !== threshold;
|
|
2599
|
+
case "gt":
|
|
2600
|
+
return count > threshold;
|
|
2601
|
+
case "lt":
|
|
2602
|
+
return count < threshold;
|
|
2603
|
+
case "ge":
|
|
2604
|
+
return count >= threshold;
|
|
2605
|
+
case "le":
|
|
2606
|
+
return count <= threshold;
|
|
2607
|
+
}
|
|
2608
|
+
}
|
|
2609
|
+
function evaluateExistenceTest(test, matchedFactCount) {
|
|
2610
|
+
const trimmed = (test ?? "").trim();
|
|
2611
|
+
if (trimmed === "") {
|
|
2612
|
+
return matchedFactCount > 0;
|
|
2613
|
+
}
|
|
2614
|
+
const clauses = trimmed.split(/\bor\b/);
|
|
2615
|
+
return clauses.some((clause) => {
|
|
2616
|
+
const match = EXISTENCE_TEST_PATTERN.exec(clause.trim());
|
|
2617
|
+
if (!match) {
|
|
2618
|
+
throw new FormulaExpressionError(`Unsupported existence-assertion test shape: "${clause.trim()}"`, trimmed, "unsupported-syntax");
|
|
2619
|
+
}
|
|
2620
|
+
const [, op, thresholdText] = match;
|
|
2621
|
+
return compareExistence(op, matchedFactCount, Number(thresholdText));
|
|
2622
|
+
});
|
|
2623
|
+
}
|
|
2624
|
+
function isTotalLabel(preferredLabel) {
|
|
2625
|
+
return !!(preferredLabel == null ? void 0 : preferredLabel.toLowerCase().includes("totallabel"));
|
|
2626
|
+
}
|
|
2627
|
+
function isNegatedTotalLabel(preferredLabel) {
|
|
2628
|
+
return !!(preferredLabel == null ? void 0 : preferredLabel.toLowerCase().includes("negatedtotallabel"));
|
|
2629
|
+
}
|
|
2630
|
+
function resolveValueNode(node, accessors, depth = 0) {
|
|
2631
|
+
if (!accessors.isAbstract(node))
|
|
2632
|
+
return node;
|
|
2633
|
+
if (depth > 5)
|
|
2634
|
+
return null;
|
|
2635
|
+
const children = accessors.getChildren(node);
|
|
2636
|
+
const nestedTotal = children.find((child) => isTotalLabel(accessors.getPreferredLabel(child)));
|
|
2637
|
+
if (!nestedTotal)
|
|
2638
|
+
return null;
|
|
2639
|
+
return resolveValueNode(nestedTotal, accessors, depth + 1);
|
|
2640
|
+
}
|
|
2641
|
+
function resolveTotalGroupMembers(nodes, i2, lastTotalIdx, rawSiblings, accessors) {
|
|
2642
|
+
if (lastTotalIdx < 0)
|
|
2643
|
+
return rawSiblings;
|
|
2644
|
+
const node = nodes[i2];
|
|
2645
|
+
if (isNegatedTotalLabel(accessors.getPreferredLabel(node))) {
|
|
2646
|
+
return rawSiblings.length > 0 ? rawSiblings : [nodes[lastTotalIdx]];
|
|
2647
|
+
}
|
|
2648
|
+
if (rawSiblings.length > 0) {
|
|
2649
|
+
return [nodes[lastTotalIdx], ...rawSiblings];
|
|
2650
|
+
}
|
|
2651
|
+
if (isNegatedTotalLabel(accessors.getPreferredLabel(nodes[lastTotalIdx]))) {
|
|
2652
|
+
let grandTotalIdx = -1;
|
|
2653
|
+
for (let k = lastTotalIdx - 1; k >= 0; k--) {
|
|
2654
|
+
if (isTotalLabel(accessors.getPreferredLabel(nodes[k]))) {
|
|
2655
|
+
grandTotalIdx = k;
|
|
2656
|
+
break;
|
|
2657
|
+
}
|
|
2658
|
+
}
|
|
2659
|
+
return grandTotalIdx >= 0 ? [nodes[grandTotalIdx], nodes[lastTotalIdx]] : [nodes[lastTotalIdx]];
|
|
2660
|
+
}
|
|
2661
|
+
return [nodes[lastTotalIdx]];
|
|
2662
|
+
}
|
|
2663
|
+
function buildTotalGroupChildrenIndex(roots, accessors) {
|
|
2664
|
+
const index = /* @__PURE__ */ new Map();
|
|
2665
|
+
function registerGroup(totalNode, members) {
|
|
2666
|
+
const resolvedIds = [];
|
|
2667
|
+
for (const member of members) {
|
|
2668
|
+
const resolved = resolveValueNode(member, accessors);
|
|
2669
|
+
if (resolved)
|
|
2670
|
+
resolvedIds.push(accessors.getId(resolved));
|
|
2671
|
+
}
|
|
2672
|
+
if (resolvedIds.length === 0)
|
|
2673
|
+
return;
|
|
2674
|
+
index.set(accessors.getId(totalNode), resolvedIds);
|
|
2675
|
+
}
|
|
2676
|
+
function traverse(nodes) {
|
|
2677
|
+
for (let i2 = 0; i2 < nodes.length; i2++) {
|
|
2678
|
+
const node = nodes[i2];
|
|
2679
|
+
if (isTotalLabel(accessors.getPreferredLabel(node))) {
|
|
2680
|
+
const children2 = accessors.getChildren(node);
|
|
2681
|
+
if (children2.length === 0) {
|
|
2682
|
+
let lastTotalIdx = -1;
|
|
2683
|
+
for (let j = i2 - 1; j >= 0; j--) {
|
|
2684
|
+
if (isTotalLabel(accessors.getPreferredLabel(nodes[j]))) {
|
|
2685
|
+
lastTotalIdx = j;
|
|
2686
|
+
break;
|
|
2687
|
+
}
|
|
2688
|
+
}
|
|
2689
|
+
const rawSiblings = nodes.slice(lastTotalIdx + 1, i2);
|
|
2690
|
+
const members = resolveTotalGroupMembers(nodes, i2, lastTotalIdx, rawSiblings, accessors);
|
|
2691
|
+
if (members.length > 0)
|
|
2692
|
+
registerGroup(node, members);
|
|
2693
|
+
}
|
|
2694
|
+
}
|
|
2695
|
+
const children = accessors.getChildren(node);
|
|
2696
|
+
if (children.length > 0)
|
|
2697
|
+
traverse(children);
|
|
2698
|
+
}
|
|
2699
|
+
}
|
|
2700
|
+
traverse(roots);
|
|
2701
|
+
return index;
|
|
2702
|
+
}
|
|
2703
|
+
function isNonEmptyRawValue(rawValue) {
|
|
2704
|
+
return rawValue !== void 0 && rawValue !== null && rawValue !== "";
|
|
2705
|
+
}
|
|
2706
|
+
function collectAllCandidates(formData) {
|
|
2707
|
+
const candidates = [];
|
|
2708
|
+
for (const conceptId of Object.keys(formData)) {
|
|
2709
|
+
const columnValues = formData[conceptId] || {};
|
|
2710
|
+
for (const columnId of Object.keys(columnValues)) {
|
|
2711
|
+
if (isNonEmptyRawValue(columnValues[columnId])) {
|
|
2712
|
+
candidates.push({ conceptId, columnId });
|
|
2713
|
+
}
|
|
2714
|
+
}
|
|
2715
|
+
}
|
|
2716
|
+
return candidates;
|
|
2717
|
+
}
|
|
2718
|
+
function indexConceptTree(concept, conceptByQName, conceptById, childrenIndex) {
|
|
2719
|
+
const info = {
|
|
2720
|
+
conceptId: concept.id,
|
|
2721
|
+
qname: concept.conceptName,
|
|
2722
|
+
balance: concept.balance
|
|
2723
|
+
};
|
|
2724
|
+
if (!conceptById.has(concept.id))
|
|
2725
|
+
conceptById.set(concept.id, info);
|
|
2726
|
+
if (!conceptByQName.has(concept.conceptName))
|
|
2727
|
+
conceptByQName.set(concept.conceptName, info);
|
|
2728
|
+
const children = concept.children || [];
|
|
2729
|
+
childrenIndex.set(
|
|
2730
|
+
concept.id,
|
|
2731
|
+
children.map((child) => child.id)
|
|
2732
|
+
);
|
|
2733
|
+
children.forEach((child) => indexConceptTree(child, conceptByQName, conceptById, childrenIndex));
|
|
2734
|
+
}
|
|
2735
|
+
function indexMemberTree(member, memberQNameToId) {
|
|
2736
|
+
if (!memberQNameToId.has(member.conceptName))
|
|
2737
|
+
memberQNameToId.set(member.conceptName, member.id);
|
|
2738
|
+
(member.children || []).forEach((child) => indexMemberTree(child, memberQNameToId));
|
|
2739
|
+
}
|
|
2740
|
+
const PRESENTATION_TOTAL_GROUP_ACCESSORS = {
|
|
2741
|
+
getId: (concept) => concept.id,
|
|
2742
|
+
getPreferredLabel: (concept) => concept.preferredLabel,
|
|
2743
|
+
isAbstract: (concept) => concept.elementAbstract,
|
|
2744
|
+
getChildren: (concept) => concept.children || []
|
|
2745
|
+
};
|
|
2746
|
+
function buildFormulaResolutionContext(formData, columns, presentationRoles, hypercubeRoles, periodStartDate, periodEndDate) {
|
|
2747
|
+
const conceptByQName = /* @__PURE__ */ new Map();
|
|
2748
|
+
const conceptById = /* @__PURE__ */ new Map();
|
|
2749
|
+
const childrenByRole = /* @__PURE__ */ new Map();
|
|
2750
|
+
const totalGroupChildrenByRole = /* @__PURE__ */ new Map();
|
|
2751
|
+
presentationRoles.forEach((role) => {
|
|
2752
|
+
var _a;
|
|
2753
|
+
const concepts = ((_a = role.presentationLinkbase) == null ? void 0 : _a.concepts) || [];
|
|
2754
|
+
const childrenIndex = /* @__PURE__ */ new Map();
|
|
2755
|
+
concepts.forEach((concept) => indexConceptTree(concept, conceptByQName, conceptById, childrenIndex));
|
|
2756
|
+
childrenByRole.set(role.roleURI, childrenIndex);
|
|
2757
|
+
totalGroupChildrenByRole.set(role.roleURI, buildTotalGroupChildrenIndex(concepts, PRESENTATION_TOTAL_GROUP_ACCESSORS));
|
|
2758
|
+
});
|
|
2759
|
+
const dimensionQNameToId = /* @__PURE__ */ new Map();
|
|
2760
|
+
const memberQNameToId = /* @__PURE__ */ new Map();
|
|
2761
|
+
(hypercubeRoles || []).forEach((role) => {
|
|
2762
|
+
role.items.forEach((item) => {
|
|
2763
|
+
item.dimensions.forEach((dimension) => {
|
|
2764
|
+
if (!dimensionQNameToId.has(dimension.conceptName)) {
|
|
2765
|
+
dimensionQNameToId.set(dimension.conceptName, dimension.id);
|
|
2766
|
+
}
|
|
2767
|
+
(dimension.members || []).forEach((member) => indexMemberTree(member, memberQNameToId));
|
|
2768
|
+
});
|
|
2769
|
+
});
|
|
2770
|
+
});
|
|
2771
|
+
return {
|
|
2772
|
+
formData,
|
|
2773
|
+
columns,
|
|
2774
|
+
periodStartDate,
|
|
2775
|
+
periodEndDate,
|
|
2776
|
+
conceptByQName,
|
|
2777
|
+
conceptById,
|
|
2778
|
+
childrenByRole,
|
|
2779
|
+
totalGroupChildrenByRole,
|
|
2780
|
+
dimensionQNameToId,
|
|
2781
|
+
memberQNameToId,
|
|
2782
|
+
allCandidates: collectAllCandidates(formData)
|
|
2783
|
+
};
|
|
2784
|
+
}
|
|
2785
|
+
function collectDescendantConceptIds(childrenIndex, rootConceptId) {
|
|
2786
|
+
const result = [];
|
|
2787
|
+
const stack = [...childrenIndex.get(rootConceptId) || []];
|
|
2788
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2789
|
+
while (stack.length > 0) {
|
|
2790
|
+
const conceptId = stack.pop();
|
|
2791
|
+
if (seen.has(conceptId))
|
|
2792
|
+
continue;
|
|
2793
|
+
seen.add(conceptId);
|
|
2794
|
+
result.push(conceptId);
|
|
2795
|
+
stack.push(...childrenIndex.get(conceptId) || []);
|
|
2796
|
+
}
|
|
2797
|
+
return result;
|
|
2798
|
+
}
|
|
2799
|
+
function candidateKey(candidate) {
|
|
2800
|
+
return `${candidate.conceptId}::${candidate.columnId}`;
|
|
2801
|
+
}
|
|
2802
|
+
function resolveMatchedCandidates(variable, ctx) {
|
|
2803
|
+
return intersectCandidates(variable.filters.map((filter2) => resolveFilter(filter2, ctx.allCandidates, ctx)));
|
|
2804
|
+
}
|
|
2805
|
+
function getColumn(ctx, columnId) {
|
|
2806
|
+
return ctx.columns.find((column2) => column2.id === columnId);
|
|
2807
|
+
}
|
|
2808
|
+
function columnMatchesExplicitDimension(column2, axisId, memberId) {
|
|
2809
|
+
if (!(column2 == null ? void 0 : column2.dimensionData))
|
|
2810
|
+
return false;
|
|
2811
|
+
const primaryMatch = column2.dimensionData.axisId === axisId && (memberId === void 0 || column2.dimensionData.memberId === memberId);
|
|
2812
|
+
if (primaryMatch)
|
|
2813
|
+
return true;
|
|
2814
|
+
return (column2.dimensionData.combinations || []).some(
|
|
2815
|
+
(combo) => combo.axisId === axisId && (memberId === void 0 || combo.memberId === memberId)
|
|
2816
|
+
);
|
|
2817
|
+
}
|
|
2818
|
+
function columnMatchesTypedDimension(column2, axisId) {
|
|
2819
|
+
if (!(column2 == null ? void 0 : column2.dimensionData))
|
|
2820
|
+
return false;
|
|
2821
|
+
if (column2.dimensionData.typedMemberId !== void 0 && column2.dimensionData.axisId === axisId)
|
|
2822
|
+
return true;
|
|
2823
|
+
return (column2.dimensionData.typedMembers || []).some((typedMember) => typedMember.axisId === axisId);
|
|
2824
|
+
}
|
|
2825
|
+
function paramTokenName(rawDate) {
|
|
2826
|
+
if (!rawDate)
|
|
2827
|
+
return void 0;
|
|
2828
|
+
return rawDate.startsWith("$") ? rawDate.slice(1) : rawDate;
|
|
2829
|
+
}
|
|
2830
|
+
function resolveParamDate(paramToken, ctx) {
|
|
2831
|
+
const isStart = paramToken.includes("StartDate");
|
|
2832
|
+
const isEnd = paramToken.includes("EndDate") || paramToken === "FinancialReportingPeriodCurrentEndDateParam";
|
|
2833
|
+
if (paramToken.startsWith("FinancialReportingPeriodCurrent")) {
|
|
2834
|
+
return isStart ? { start: ctx.periodStartDate } : isEnd ? { end: ctx.periodEndDate } : void 0;
|
|
2835
|
+
}
|
|
2836
|
+
if (paramToken.startsWith("FinancialReportingPeriodPrePrevious") || paramToken.startsWith("FinancialReportingPeriodPrevious")) {
|
|
2837
|
+
const previousYearColumn = findPreviousYearColumn(ctx);
|
|
2838
|
+
if (!previousYearColumn)
|
|
2839
|
+
return void 0;
|
|
2840
|
+
return isStart ? { start: previousYearColumn.periodStartDate } : isEnd ? { end: previousYearColumn.periodEndDate } : void 0;
|
|
2841
|
+
}
|
|
2842
|
+
return void 0;
|
|
2843
|
+
}
|
|
2844
|
+
function findPreviousYearColumn(ctx) {
|
|
2845
|
+
return ctx.columns.find((column2) => column2.periodEndDate !== void 0 && column2.periodEndDate < ctx.periodEndDate);
|
|
2846
|
+
}
|
|
2847
|
+
function columnEffectivePeriod(column2, ctx) {
|
|
2848
|
+
return {
|
|
2849
|
+
start: (column2 == null ? void 0 : column2.periodStartDate) ?? ctx.periodStartDate,
|
|
2850
|
+
end: (column2 == null ? void 0 : column2.periodEndDate) ?? ctx.periodEndDate
|
|
2851
|
+
};
|
|
2852
|
+
}
|
|
2853
|
+
function columnMatchesPeriod(column2, dateAttribute, ctx) {
|
|
2854
|
+
const paramToken = paramTokenName(dateAttribute);
|
|
2855
|
+
if (!paramToken)
|
|
2856
|
+
return false;
|
|
2857
|
+
const resolved = resolveParamDate(paramToken, ctx);
|
|
2858
|
+
if (!resolved)
|
|
2859
|
+
return false;
|
|
2860
|
+
const period = columnEffectivePeriod(column2, ctx);
|
|
2861
|
+
const targetDate = resolved.end ?? resolved.start;
|
|
2862
|
+
return period.end === targetDate;
|
|
2863
|
+
}
|
|
2864
|
+
function unionCandidates(lists) {
|
|
2865
|
+
const merged = /* @__PURE__ */ new Map();
|
|
2866
|
+
lists.forEach((list) => list.forEach((candidate) => merged.set(candidateKey(candidate), candidate)));
|
|
2867
|
+
return Array.from(merged.values());
|
|
2868
|
+
}
|
|
2869
|
+
function matchFilter(filter2, universe, ctx) {
|
|
2870
|
+
var _a;
|
|
2871
|
+
switch (filter2.type) {
|
|
2872
|
+
case "CONCEPT_NAME": {
|
|
2873
|
+
const qname = filter2.attributes["concept.qname"];
|
|
2874
|
+
const info = qname ? ctx.conceptByQName.get(qname) : void 0;
|
|
2875
|
+
if (!info)
|
|
2876
|
+
return [];
|
|
2877
|
+
return universe.filter((candidate) => candidate.conceptId === info.conceptId);
|
|
2878
|
+
}
|
|
2879
|
+
case "CONCEPT_BALANCE": {
|
|
2880
|
+
const balance = filter2.attributes["balance"];
|
|
2881
|
+
return universe.filter((candidate) => {
|
|
2882
|
+
var _a2;
|
|
2883
|
+
return ((_a2 = ctx.conceptById.get(candidate.conceptId)) == null ? void 0 : _a2.balance) === balance;
|
|
2884
|
+
});
|
|
2885
|
+
}
|
|
2886
|
+
case "CONCEPT_RELATION": {
|
|
2887
|
+
const anchorQName = filter2.attributes["qname"];
|
|
2888
|
+
const linkrole = filter2.attributes["linkrole"];
|
|
2889
|
+
const axis = filter2.attributes["axis"];
|
|
2890
|
+
const anchorInfo = anchorQName ? ctx.conceptByQName.get(anchorQName) : void 0;
|
|
2891
|
+
const childrenIndex = linkrole ? ctx.childrenByRole.get(linkrole) : void 0;
|
|
2892
|
+
if (!anchorInfo || !childrenIndex)
|
|
2893
|
+
return [];
|
|
2894
|
+
let relatedConceptIds;
|
|
2895
|
+
if (axis === "descendant") {
|
|
2896
|
+
relatedConceptIds = collectDescendantConceptIds(childrenIndex, anchorInfo.conceptId);
|
|
2897
|
+
} else {
|
|
2898
|
+
const nestedChildren = childrenIndex.get(anchorInfo.conceptId) || [];
|
|
2899
|
+
relatedConceptIds = nestedChildren.length > 0 ? nestedChildren : ((_a = ctx.totalGroupChildrenByRole.get(linkrole ?? "")) == null ? void 0 : _a.get(anchorInfo.conceptId)) || [];
|
|
2900
|
+
}
|
|
2901
|
+
const relatedSet = new Set(relatedConceptIds);
|
|
2902
|
+
return universe.filter((candidate) => relatedSet.has(candidate.conceptId));
|
|
2903
|
+
}
|
|
2904
|
+
case "EXPLICIT_DIMENSION": {
|
|
2905
|
+
const dimensionQName = filter2.attributes["dimension.qname"];
|
|
2906
|
+
const memberQName = filter2.attributes["member.qname"];
|
|
2907
|
+
const axisId = dimensionQName ? ctx.dimensionQNameToId.get(dimensionQName) : void 0;
|
|
2908
|
+
const memberId = memberQName ? ctx.memberQNameToId.get(memberQName) : void 0;
|
|
2909
|
+
if (!axisId)
|
|
2910
|
+
return [];
|
|
2911
|
+
return universe.filter((candidate) => columnMatchesExplicitDimension(getColumn(ctx, candidate.columnId), axisId, memberId));
|
|
2912
|
+
}
|
|
2913
|
+
case "TYPED_DIMENSION": {
|
|
2914
|
+
const dimensionQName = filter2.attributes["dimension.qname"];
|
|
2915
|
+
const axisId = dimensionQName ? ctx.dimensionQNameToId.get(dimensionQName) : void 0;
|
|
2916
|
+
if (!axisId)
|
|
2917
|
+
return [];
|
|
2918
|
+
return universe.filter((candidate) => columnMatchesTypedDimension(getColumn(ctx, candidate.columnId), axisId));
|
|
2919
|
+
}
|
|
2920
|
+
case "PERIOD_INSTANT":
|
|
2921
|
+
case "PERIOD_END": {
|
|
2922
|
+
const dateAttribute = filter2.attributes["date"];
|
|
2923
|
+
return universe.filter((candidate) => columnMatchesPeriod(getColumn(ctx, candidate.columnId), dateAttribute, ctx));
|
|
2924
|
+
}
|
|
2925
|
+
case "OR_FILTER":
|
|
2926
|
+
return unionCandidates(filter2.children.map((child) => resolveFilter(child, universe, ctx)));
|
|
2927
|
+
default:
|
|
2928
|
+
return [];
|
|
2929
|
+
}
|
|
2930
|
+
}
|
|
2931
|
+
function resolveFilter(filter2, universe, ctx) {
|
|
2932
|
+
const matched = matchFilter(filter2, universe, ctx);
|
|
2933
|
+
if (!filter2.complement)
|
|
2934
|
+
return matched;
|
|
2935
|
+
const matchedKeys = new Set(matched.map(candidateKey));
|
|
2936
|
+
return universe.filter((candidate) => !matchedKeys.has(candidateKey(candidate)));
|
|
2937
|
+
}
|
|
2938
|
+
function intersectCandidates(sets) {
|
|
2939
|
+
if (sets.length === 0)
|
|
2940
|
+
return [];
|
|
2941
|
+
return sets.reduce((acc, set) => {
|
|
2942
|
+
const setKeys = new Set(set.map(candidateKey));
|
|
2943
|
+
return acc.filter((candidate) => setKeys.has(candidateKey(candidate)));
|
|
2944
|
+
});
|
|
2945
|
+
}
|
|
2946
|
+
function resolveFormulaVariable(variable, ctx) {
|
|
2947
|
+
const matched = resolveMatchedCandidates(variable, ctx);
|
|
2948
|
+
const values = matched.map((candidate) => {
|
|
2949
|
+
var _a;
|
|
2950
|
+
return parseFloat((_a = ctx.formData[candidate.conceptId]) == null ? void 0 : _a[candidate.columnId]);
|
|
2951
|
+
}).filter((value) => !Number.isNaN(value));
|
|
2952
|
+
if (variable.bindAsSequence) {
|
|
2953
|
+
if (values.length === 0 && variable.fallbackValue === "()")
|
|
2954
|
+
return [];
|
|
2955
|
+
if (values.length === 0)
|
|
2956
|
+
return void 0;
|
|
2957
|
+
return values;
|
|
2958
|
+
}
|
|
2959
|
+
if (values.length === 0)
|
|
2960
|
+
return void 0;
|
|
2961
|
+
if (values.length > 1) {
|
|
2962
|
+
console.warn(
|
|
2963
|
+
`[formula-variable-resolver] Variable "${variable.name}" is scalar (bindAsSequence: false) but matched ${values.length} facts; using the first match by column order. This can legitimately happen when filters under-constrain the candidate set.`
|
|
2964
|
+
);
|
|
2965
|
+
}
|
|
2966
|
+
return values[0];
|
|
2967
|
+
}
|
|
2968
|
+
function resolveFormulaVariableMatchCount(variable, ctx) {
|
|
2969
|
+
return resolveMatchedCandidates(variable, ctx).length;
|
|
2970
|
+
}
|
|
2971
|
+
function resolveFormulaVariableUsedFallback(variable, ctx) {
|
|
2972
|
+
const matchCount = resolveFormulaVariableMatchCount(variable, ctx);
|
|
2973
|
+
if (matchCount > 0)
|
|
2974
|
+
return false;
|
|
2975
|
+
if (variable.fallbackValue !== void 0)
|
|
2976
|
+
return true;
|
|
2977
|
+
return void 0;
|
|
2978
|
+
}
|
|
2979
|
+
function buildAssertionBindings(assertion, ctx) {
|
|
2980
|
+
const bindings = /* @__PURE__ */ new Map();
|
|
2981
|
+
for (const variable of assertion.variables) {
|
|
2982
|
+
bindings.set(variable.name, resolveFormulaVariable(variable, ctx));
|
|
2983
|
+
}
|
|
2984
|
+
return bindings;
|
|
2985
|
+
}
|
|
2986
|
+
function buildAssertionFallbackUsage(assertion, ctx) {
|
|
2987
|
+
var _a;
|
|
2988
|
+
const usesHasFallbackValue = ((_a = assertion.test) == null ? void 0 : _a.includes("has-fallback-value")) || assertion.preconditions.some((precondition) => precondition.test.includes("has-fallback-value"));
|
|
2989
|
+
if (!usesHasFallbackValue)
|
|
2990
|
+
return /* @__PURE__ */ new Map();
|
|
2991
|
+
const fallbackUsage = /* @__PURE__ */ new Map();
|
|
2992
|
+
for (const variable of assertion.variables) {
|
|
2993
|
+
const usedFallback = resolveFormulaVariableUsedFallback(variable, ctx);
|
|
2994
|
+
if (usedFallback !== void 0)
|
|
2995
|
+
fallbackUsage.set(variable.name, usedFallback);
|
|
2996
|
+
}
|
|
2997
|
+
return fallbackUsage;
|
|
2998
|
+
}
|
|
2999
|
+
function evaluateAssertionPreconditions(preconditions, bindings, fallbackUsage = /* @__PURE__ */ new Map()) {
|
|
3000
|
+
if (preconditions.length === 0)
|
|
3001
|
+
return { satisfied: true };
|
|
3002
|
+
for (const precondition of preconditions) {
|
|
3003
|
+
let result;
|
|
3004
|
+
try {
|
|
3005
|
+
result = evaluateFormulaTest(precondition.test, bindings, fallbackUsage);
|
|
3006
|
+
} catch (error2) {
|
|
3007
|
+
if (error2 instanceof FormulaExpressionError) {
|
|
3008
|
+
return { satisfied: false, skipReason: "unresolvable" };
|
|
3009
|
+
}
|
|
3010
|
+
throw error2;
|
|
3011
|
+
}
|
|
3012
|
+
if (!result) {
|
|
3013
|
+
return { satisfied: false, skipReason: "precondition" };
|
|
3014
|
+
}
|
|
3015
|
+
}
|
|
3016
|
+
return { satisfied: true };
|
|
3017
|
+
}
|
|
3018
|
+
class FormulaValidationService {
|
|
3019
|
+
/**
|
|
3020
|
+
* Evaluates every assertion in `xbrlInput.formula[0].roles` (only the first entrypoint,
|
|
3021
|
+
* consistent with how xbrl-form-builder.ts uses presentation/hypercube data) against the
|
|
3022
|
+
* given resolution context. One bad assertion never aborts the other 783 — resolution/
|
|
3023
|
+
* evaluation errors are caught per-assertion and recorded as skipped, not thrown.
|
|
3024
|
+
*/
|
|
3025
|
+
evaluate(xbrlInput, ctx, language) {
|
|
3026
|
+
var _a;
|
|
3027
|
+
const formulaData = (_a = xbrlInput.formula) == null ? void 0 : _a[0];
|
|
3028
|
+
if (!formulaData)
|
|
3029
|
+
return [];
|
|
3030
|
+
const results = [];
|
|
3031
|
+
for (const role of formulaData.roles) {
|
|
3032
|
+
for (const assertion of role.assertions) {
|
|
3033
|
+
results.push(this._evaluateAssertion(assertion, role, ctx, language));
|
|
3034
|
+
}
|
|
3035
|
+
}
|
|
3036
|
+
return results;
|
|
3037
|
+
}
|
|
3038
|
+
summarize(results) {
|
|
3039
|
+
const summary = {
|
|
3040
|
+
totalAssertions: results.length,
|
|
3041
|
+
evaluated: 0,
|
|
3042
|
+
skipped: 0,
|
|
3043
|
+
passed: 0,
|
|
3044
|
+
failed: 0,
|
|
3045
|
+
failedWarnings: 0,
|
|
3046
|
+
failedErrors: 0
|
|
3047
|
+
};
|
|
3048
|
+
for (const result of results) {
|
|
3049
|
+
if (result.skipped) {
|
|
3050
|
+
summary.skipped += 1;
|
|
3051
|
+
continue;
|
|
3052
|
+
}
|
|
3053
|
+
summary.evaluated += 1;
|
|
3054
|
+
if (result.satisfied) {
|
|
3055
|
+
summary.passed += 1;
|
|
3056
|
+
} else {
|
|
3057
|
+
summary.failed += 1;
|
|
3058
|
+
if (result.severity === "ERROR")
|
|
3059
|
+
summary.failedErrors += 1;
|
|
3060
|
+
else
|
|
3061
|
+
summary.failedWarnings += 1;
|
|
3062
|
+
}
|
|
3063
|
+
}
|
|
3064
|
+
return summary;
|
|
3065
|
+
}
|
|
3066
|
+
_evaluateAssertion(assertion, role, ctx, language) {
|
|
3067
|
+
try {
|
|
3068
|
+
const bindings = buildAssertionBindings(assertion, ctx);
|
|
3069
|
+
const fallbackUsage = buildAssertionFallbackUsage(assertion, ctx);
|
|
3070
|
+
const precondition = evaluateAssertionPreconditions(assertion.preconditions, bindings, fallbackUsage);
|
|
3071
|
+
if (!precondition.satisfied) {
|
|
3072
|
+
return this._skippedResult(assertion, role, precondition.skipReason ?? "unresolvable");
|
|
3073
|
+
}
|
|
3074
|
+
if (assertion.type === "EXISTENCE_ASSERTION") {
|
|
3075
|
+
const matchedFactCount = resolveFormulaVariableMatchCount(assertion.variables[0], ctx);
|
|
3076
|
+
const satisfied2 = evaluateExistenceTest(assertion.test, matchedFactCount);
|
|
3077
|
+
return this._evaluatedResult(assertion, role, satisfied2, language, matchedFactCount);
|
|
3078
|
+
}
|
|
3079
|
+
const satisfied = evaluateFormulaTest(assertion.test, bindings, fallbackUsage);
|
|
3080
|
+
return this._evaluatedResult(assertion, role, satisfied, language);
|
|
3081
|
+
} catch (error2) {
|
|
3082
|
+
if (error2 instanceof FormulaExpressionError) {
|
|
3083
|
+
console.warn(`[FormulaValidationService] Assertion "${assertion.id}" could not be evaluated (${error2.reason}): ${error2.message}`);
|
|
3084
|
+
return this._skippedResult(assertion, role, "unresolvable");
|
|
3085
|
+
}
|
|
3086
|
+
throw error2;
|
|
3087
|
+
}
|
|
3088
|
+
}
|
|
3089
|
+
_skippedResult(assertion, role, skipReason) {
|
|
3090
|
+
return {
|
|
3091
|
+
assertionId: assertion.id,
|
|
3092
|
+
roleURI: role.roleURI,
|
|
3093
|
+
roleLabel: role.role,
|
|
3094
|
+
type: assertion.type,
|
|
3095
|
+
severity: assertion.severity,
|
|
3096
|
+
satisfied: false,
|
|
3097
|
+
skipped: true,
|
|
3098
|
+
skipReason
|
|
3099
|
+
};
|
|
3100
|
+
}
|
|
3101
|
+
_evaluatedResult(assertion, role, satisfied, language, matchedFactCount) {
|
|
3102
|
+
return {
|
|
3103
|
+
assertionId: assertion.id,
|
|
3104
|
+
roleURI: role.roleURI,
|
|
3105
|
+
roleLabel: role.role,
|
|
3106
|
+
type: assertion.type,
|
|
3107
|
+
severity: assertion.severity,
|
|
3108
|
+
satisfied,
|
|
3109
|
+
skipped: false,
|
|
3110
|
+
message: satisfied ? void 0 : this._pickMessage(assertion, language),
|
|
3111
|
+
matchedFactCount
|
|
3112
|
+
};
|
|
3113
|
+
}
|
|
3114
|
+
_pickMessage(assertion, language) {
|
|
3115
|
+
const messages = assertion.messages;
|
|
3116
|
+
if (messages.length === 0)
|
|
3117
|
+
return void 0;
|
|
3118
|
+
const message = messages.find((m) => m.xmlLang === language) ?? messages.find((m) => m.xmlLang === "en") ?? messages[0];
|
|
3119
|
+
return message.text;
|
|
3120
|
+
}
|
|
3121
|
+
}
|
|
2303
3122
|
class FactMatcher {
|
|
2304
3123
|
/**
|
|
2305
3124
|
* Find a matching fact for a given cell context
|
|
@@ -3153,15 +3972,15 @@ function determineInputTypeFromBaseChain(baseTypeChain, datatypes) {
|
|
|
3153
3972
|
placeholder: I18n.t("field.enterValue")
|
|
3154
3973
|
};
|
|
3155
3974
|
}
|
|
3156
|
-
var __defProp$
|
|
3157
|
-
var __getOwnPropDesc$
|
|
3158
|
-
var __decorateClass$
|
|
3159
|
-
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$
|
|
3975
|
+
var __defProp$7 = Object.defineProperty;
|
|
3976
|
+
var __getOwnPropDesc$7 = Object.getOwnPropertyDescriptor;
|
|
3977
|
+
var __decorateClass$7 = (decorators, target, key, kind) => {
|
|
3978
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$7(target, key) : target;
|
|
3160
3979
|
for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
|
|
3161
3980
|
if (decorator = decorators[i2])
|
|
3162
3981
|
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
3163
3982
|
if (kind && result)
|
|
3164
|
-
__defProp$
|
|
3983
|
+
__defProp$7(target, key, result);
|
|
3165
3984
|
return result;
|
|
3166
3985
|
};
|
|
3167
3986
|
let JupiterFormField = class extends LitElement {
|
|
@@ -4178,6 +4997,7 @@ let JupiterFormField = class extends LitElement {
|
|
|
4178
4997
|
<button
|
|
4179
4998
|
class="period-icon-btn"
|
|
4180
4999
|
type="button"
|
|
5000
|
+
tabindex="-1"
|
|
4181
5001
|
@click="${this._handlePeriodIconClick}"
|
|
4182
5002
|
title="Edit period"
|
|
4183
5003
|
>
|
|
@@ -4674,99 +5494,99 @@ JupiterFormField.styles = css`
|
|
|
4674
5494
|
animation: concept-highlight-pulse 10s ease-out forwards;
|
|
4675
5495
|
}
|
|
4676
5496
|
`;
|
|
4677
|
-
__decorateClass$
|
|
5497
|
+
__decorateClass$7([
|
|
4678
5498
|
n2({ type: Object })
|
|
4679
5499
|
], JupiterFormField.prototype, "field", 2);
|
|
4680
|
-
__decorateClass$
|
|
5500
|
+
__decorateClass$7([
|
|
4681
5501
|
n2({ type: String })
|
|
4682
5502
|
], JupiterFormField.prototype, "conceptId", 2);
|
|
4683
|
-
__decorateClass$
|
|
5503
|
+
__decorateClass$7([
|
|
4684
5504
|
n2({ type: String })
|
|
4685
5505
|
], JupiterFormField.prototype, "conceptType", 2);
|
|
4686
|
-
__decorateClass$
|
|
5506
|
+
__decorateClass$7([
|
|
4687
5507
|
n2({ type: Array })
|
|
4688
5508
|
], JupiterFormField.prototype, "datatypes", 2);
|
|
4689
|
-
__decorateClass$
|
|
5509
|
+
__decorateClass$7([
|
|
4690
5510
|
n2({ type: Array })
|
|
4691
5511
|
], JupiterFormField.prototype, "defaultUnits", 2);
|
|
4692
|
-
__decorateClass$
|
|
5512
|
+
__decorateClass$7([
|
|
4693
5513
|
n2({ type: String })
|
|
4694
5514
|
], JupiterFormField.prototype, "columnId", 2);
|
|
4695
|
-
__decorateClass$
|
|
5515
|
+
__decorateClass$7([
|
|
4696
5516
|
n2()
|
|
4697
5517
|
], JupiterFormField.prototype, "value", 2);
|
|
4698
|
-
__decorateClass$
|
|
5518
|
+
__decorateClass$7([
|
|
4699
5519
|
n2({ type: Boolean })
|
|
4700
5520
|
], JupiterFormField.prototype, "disabled", 2);
|
|
4701
|
-
__decorateClass$
|
|
5521
|
+
__decorateClass$7([
|
|
4702
5522
|
n2({ type: String })
|
|
4703
5523
|
], JupiterFormField.prototype, "locale", 2);
|
|
4704
|
-
__decorateClass$
|
|
5524
|
+
__decorateClass$7([
|
|
4705
5525
|
n2({ type: Boolean })
|
|
4706
5526
|
], JupiterFormField.prototype, "hideLabel", 2);
|
|
4707
|
-
__decorateClass$
|
|
5527
|
+
__decorateClass$7([
|
|
4708
5528
|
n2({ type: String })
|
|
4709
5529
|
], JupiterFormField.prototype, "mode", 2);
|
|
4710
|
-
__decorateClass$
|
|
5530
|
+
__decorateClass$7([
|
|
4711
5531
|
n2({ type: Object })
|
|
4712
5532
|
], JupiterFormField.prototype, "masterData", 2);
|
|
4713
|
-
__decorateClass$
|
|
5533
|
+
__decorateClass$7([
|
|
4714
5534
|
n2({ type: Array })
|
|
4715
5535
|
], JupiterFormField.prototype, "facts", 2);
|
|
4716
|
-
__decorateClass$
|
|
5536
|
+
__decorateClass$7([
|
|
4717
5537
|
n2({ type: Object })
|
|
4718
5538
|
], JupiterFormField.prototype, "column", 2);
|
|
4719
|
-
__decorateClass$
|
|
5539
|
+
__decorateClass$7([
|
|
4720
5540
|
n2({ type: String })
|
|
4721
5541
|
], JupiterFormField.prototype, "periodStartDate", 2);
|
|
4722
|
-
__decorateClass$
|
|
5542
|
+
__decorateClass$7([
|
|
4723
5543
|
n2({ type: String })
|
|
4724
5544
|
], JupiterFormField.prototype, "periodEndDate", 2);
|
|
4725
|
-
__decorateClass$
|
|
5545
|
+
__decorateClass$7([
|
|
4726
5546
|
n2({ type: String })
|
|
4727
5547
|
], JupiterFormField.prototype, "periodInstantDate", 2);
|
|
4728
|
-
__decorateClass$
|
|
5548
|
+
__decorateClass$7([
|
|
4729
5549
|
n2({ type: String })
|
|
4730
5550
|
], JupiterFormField.prototype, "unit", 2);
|
|
4731
|
-
__decorateClass$
|
|
5551
|
+
__decorateClass$7([
|
|
4732
5552
|
n2({ type: String })
|
|
4733
5553
|
], JupiterFormField.prototype, "decimals", 2);
|
|
4734
|
-
__decorateClass$
|
|
5554
|
+
__decorateClass$7([
|
|
4735
5555
|
n2({ type: String })
|
|
4736
5556
|
], JupiterFormField.prototype, "globalDecimals", 2);
|
|
4737
|
-
__decorateClass$
|
|
5557
|
+
__decorateClass$7([
|
|
4738
5558
|
n2({ type: Object })
|
|
4739
5559
|
], JupiterFormField.prototype, "typedMemberValues", 2);
|
|
4740
|
-
__decorateClass$
|
|
5560
|
+
__decorateClass$7([
|
|
4741
5561
|
r()
|
|
4742
5562
|
], JupiterFormField.prototype, "_errors", 2);
|
|
4743
|
-
__decorateClass$
|
|
5563
|
+
__decorateClass$7([
|
|
4744
5564
|
r()
|
|
4745
5565
|
], JupiterFormField.prototype, "_xbrlErrors", 2);
|
|
4746
|
-
__decorateClass$
|
|
5566
|
+
__decorateClass$7([
|
|
4747
5567
|
r()
|
|
4748
5568
|
], JupiterFormField.prototype, "_touched", 2);
|
|
4749
|
-
__decorateClass$
|
|
5569
|
+
__decorateClass$7([
|
|
4750
5570
|
r()
|
|
4751
5571
|
], JupiterFormField.prototype, "_showPeriodPopup", 2);
|
|
4752
|
-
__decorateClass$
|
|
5572
|
+
__decorateClass$7([
|
|
4753
5573
|
r()
|
|
4754
5574
|
], JupiterFormField.prototype, "_availableUnits", 2);
|
|
4755
|
-
__decorateClass$
|
|
5575
|
+
__decorateClass$7([
|
|
4756
5576
|
r()
|
|
4757
5577
|
], JupiterFormField.prototype, "_numericDraftValue", 2);
|
|
4758
|
-
JupiterFormField = __decorateClass$
|
|
5578
|
+
JupiterFormField = __decorateClass$7([
|
|
4759
5579
|
t$1("jupiter-form-field")
|
|
4760
5580
|
], JupiterFormField);
|
|
4761
|
-
var __defProp$
|
|
4762
|
-
var __getOwnPropDesc$
|
|
4763
|
-
var __decorateClass$
|
|
4764
|
-
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$
|
|
5581
|
+
var __defProp$6 = Object.defineProperty;
|
|
5582
|
+
var __getOwnPropDesc$6 = Object.getOwnPropertyDescriptor;
|
|
5583
|
+
var __decorateClass$6 = (decorators, target, key, kind) => {
|
|
5584
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$6(target, key) : target;
|
|
4765
5585
|
for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
|
|
4766
5586
|
if (decorator = decorators[i2])
|
|
4767
5587
|
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
4768
5588
|
if (kind && result)
|
|
4769
|
-
__defProp$
|
|
5589
|
+
__defProp$6(target, key, result);
|
|
4770
5590
|
return result;
|
|
4771
5591
|
};
|
|
4772
5592
|
let JupiterConceptTree = class extends LitElement {
|
|
@@ -5036,6 +5856,7 @@ let JupiterConceptTree = class extends LitElement {
|
|
|
5036
5856
|
const hasChildren = this.concept.children && this.concept.children.length > 0;
|
|
5037
5857
|
const level = this.concept.level || 0;
|
|
5038
5858
|
const isAbstract = this.concept.abstract || false;
|
|
5859
|
+
const isTotal = isTotalLabel$1(this.concept.preferredLabel);
|
|
5039
5860
|
return html`
|
|
5040
5861
|
<!-- Concept Name Cell (Left Column) -->
|
|
5041
5862
|
<td class="concept-name-cell ${isAbstract ? "abstract" : hasChildren ? "" : "leaf"} ${this.rowFocused ? "row-focused" : ""}">
|
|
@@ -5045,7 +5866,7 @@ let JupiterConceptTree = class extends LitElement {
|
|
|
5045
5866
|
@click="${this._toggleExpanded}">
|
|
5046
5867
|
${hasChildren ? "▶" : ""}
|
|
5047
5868
|
</div>
|
|
5048
|
-
<div class="concept-label"
|
|
5869
|
+
<div class="concept-label ${isTotal ? "total-concept-label" : ""}"
|
|
5049
5870
|
@click="${this._toggleExpanded}"
|
|
5050
5871
|
title="${this.concept.id}${this.concept.description ? " - " + this.concept.description : ""}">
|
|
5051
5872
|
${this.concept.label}
|
|
@@ -5053,14 +5874,14 @@ let JupiterConceptTree = class extends LitElement {
|
|
|
5053
5874
|
${this.concept.balance ? html`
|
|
5054
5875
|
<div class="concept-balance ${this.concept.balance}">${this.concept.balance}</div>
|
|
5055
5876
|
` : ""}
|
|
5056
|
-
<button class="concept-info-btn" type="button" title="${I18n.t("conceptInfo.title")}"
|
|
5877
|
+
<button class="concept-info-btn" type="button" tabindex="-1" title="${I18n.t("conceptInfo.title")}"
|
|
5057
5878
|
@click="${this._openInfoDialog}">ℹ</button>
|
|
5058
5879
|
${this.showAddButton ? html`
|
|
5059
|
-
<button class="repeat-btn" type="button" title="Add row"
|
|
5880
|
+
<button class="repeat-btn" type="button" tabindex="-1" title="Add row"
|
|
5060
5881
|
@click="${this._handleAddRepeat}">+</button>
|
|
5061
5882
|
` : ""}
|
|
5062
5883
|
${this.showRemoveButton ? html`
|
|
5063
|
-
<button class="repeat-btn remove" type="button" title="Remove row"
|
|
5884
|
+
<button class="repeat-btn remove" type="button" tabindex="-1" title="Remove row"
|
|
5064
5885
|
@click="${this._handleRemoveRepeat}">−</button>
|
|
5065
5886
|
` : ""}
|
|
5066
5887
|
</div>
|
|
@@ -5078,11 +5899,12 @@ let JupiterConceptTree = class extends LitElement {
|
|
|
5078
5899
|
const storedDecimals = (_d = (_c = this.decimalsData) == null ? void 0 : _c[this.concept.id]) == null ? void 0 : _d[column2.id];
|
|
5079
5900
|
const calcMismatch = this.mode !== "readonly" ? (_e = this.calculationMismatches) == null ? void 0 : _e.get(`${this.concept.id}__${column2.id}`) : void 0;
|
|
5080
5901
|
return html`
|
|
5081
|
-
<td class="field-cell ${!shouldShowField ? "empty" : ""} ${isAbstract ? "abstract-row" : ""} ${this.highlightType && column2.id === this.highlightColumnId ? "highlight-" + this.highlightType : ""} ${calcMismatch ? "calc-warning" : ""} ${this.rowFocused ? "row-focused" : ""}">
|
|
5902
|
+
<td class="field-cell ${!shouldShowField ? "empty" : ""} ${isAbstract ? "abstract-row" : ""} ${isTotal ? "total-row" : ""} ${this.highlightType && column2.id === this.highlightColumnId ? "highlight-" + this.highlightType : ""} ${calcMismatch ? "calc-warning" : ""} ${this.rowFocused ? "row-focused" : ""}">
|
|
5082
5903
|
${calcMismatch ? html`
|
|
5083
5904
|
<button
|
|
5084
5905
|
class="calc-warning-badge"
|
|
5085
5906
|
type="button"
|
|
5907
|
+
tabindex="-1"
|
|
5086
5908
|
title="${calcMismatch.message}"
|
|
5087
5909
|
@click="${(e2) => this._openCalculationWarningDialog(e2, calcMismatch)}"
|
|
5088
5910
|
>!</button>
|
|
@@ -5199,6 +6021,10 @@ JupiterConceptTree.styles = css`
|
|
|
5199
6021
|
min-width: 0; /* Allows flex item to shrink below content size */
|
|
5200
6022
|
}
|
|
5201
6023
|
|
|
6024
|
+
.concept-label.total-concept-label {
|
|
6025
|
+
font-weight: 700;
|
|
6026
|
+
}
|
|
6027
|
+
|
|
5202
6028
|
.concept-balance {
|
|
5203
6029
|
margin-left: 8px;
|
|
5204
6030
|
font-size: 11px;
|
|
@@ -5290,6 +6116,10 @@ JupiterConceptTree.styles = css`
|
|
|
5290
6116
|
color: #fff;
|
|
5291
6117
|
}
|
|
5292
6118
|
|
|
6119
|
+
.field-cell.total-row {
|
|
6120
|
+
background: var(--jupiter-total-cell-background, rgba(0, 0, 0, 0.045));
|
|
6121
|
+
}
|
|
6122
|
+
|
|
5293
6123
|
.field-cell.highlight-total {
|
|
5294
6124
|
background: rgba(25, 118, 210, 0.15);
|
|
5295
6125
|
}
|
|
@@ -5395,90 +6225,90 @@ JupiterConceptTree.styles = css`
|
|
|
5395
6225
|
}
|
|
5396
6226
|
|
|
5397
6227
|
`;
|
|
5398
|
-
__decorateClass$
|
|
6228
|
+
__decorateClass$6([
|
|
5399
6229
|
n2({ type: Object })
|
|
5400
6230
|
], JupiterConceptTree.prototype, "concept", 2);
|
|
5401
|
-
__decorateClass$
|
|
6231
|
+
__decorateClass$6([
|
|
5402
6232
|
n2({ type: Array })
|
|
5403
6233
|
], JupiterConceptTree.prototype, "columns", 2);
|
|
5404
|
-
__decorateClass$
|
|
6234
|
+
__decorateClass$6([
|
|
5405
6235
|
n2({ type: Object })
|
|
5406
6236
|
], JupiterConceptTree.prototype, "formData", 2);
|
|
5407
|
-
__decorateClass$
|
|
6237
|
+
__decorateClass$6([
|
|
5408
6238
|
n2({ type: Object })
|
|
5409
6239
|
], JupiterConceptTree.prototype, "periodData", 2);
|
|
5410
|
-
__decorateClass$
|
|
6240
|
+
__decorateClass$6([
|
|
5411
6241
|
n2({ type: Object })
|
|
5412
6242
|
], JupiterConceptTree.prototype, "unitData", 2);
|
|
5413
|
-
__decorateClass$
|
|
6243
|
+
__decorateClass$6([
|
|
5414
6244
|
n2({ type: Object })
|
|
5415
6245
|
], JupiterConceptTree.prototype, "decimalsData", 2);
|
|
5416
|
-
__decorateClass$
|
|
6246
|
+
__decorateClass$6([
|
|
5417
6247
|
n2({ type: String })
|
|
5418
6248
|
], JupiterConceptTree.prototype, "globalDecimals", 2);
|
|
5419
|
-
__decorateClass$
|
|
6249
|
+
__decorateClass$6([
|
|
5420
6250
|
n2({ type: Array })
|
|
5421
6251
|
], JupiterConceptTree.prototype, "defaultUnits", 2);
|
|
5422
|
-
__decorateClass$
|
|
6252
|
+
__decorateClass$6([
|
|
5423
6253
|
n2({ type: Boolean })
|
|
5424
6254
|
], JupiterConceptTree.prototype, "disabled", 2);
|
|
5425
|
-
__decorateClass$
|
|
6255
|
+
__decorateClass$6([
|
|
5426
6256
|
n2({ type: String })
|
|
5427
6257
|
], JupiterConceptTree.prototype, "locale", 2);
|
|
5428
|
-
__decorateClass$
|
|
6258
|
+
__decorateClass$6([
|
|
5429
6259
|
n2({ type: Set })
|
|
5430
6260
|
], JupiterConceptTree.prototype, "expandedConcepts", 2);
|
|
5431
|
-
__decorateClass$
|
|
6261
|
+
__decorateClass$6([
|
|
5432
6262
|
n2({ type: Array })
|
|
5433
6263
|
], JupiterConceptTree.prototype, "datatypes", 2);
|
|
5434
|
-
__decorateClass$
|
|
6264
|
+
__decorateClass$6([
|
|
5435
6265
|
n2({ type: String })
|
|
5436
6266
|
], JupiterConceptTree.prototype, "mode", 2);
|
|
5437
|
-
__decorateClass$
|
|
6267
|
+
__decorateClass$6([
|
|
5438
6268
|
n2({ type: Object })
|
|
5439
6269
|
], JupiterConceptTree.prototype, "masterData", 2);
|
|
5440
|
-
__decorateClass$
|
|
6270
|
+
__decorateClass$6([
|
|
5441
6271
|
n2({ type: Array })
|
|
5442
6272
|
], JupiterConceptTree.prototype, "facts", 2);
|
|
5443
|
-
__decorateClass$
|
|
6273
|
+
__decorateClass$6([
|
|
5444
6274
|
n2({ type: Object })
|
|
5445
6275
|
], JupiterConceptTree.prototype, "typedMemberData", 2);
|
|
5446
|
-
__decorateClass$
|
|
6276
|
+
__decorateClass$6([
|
|
5447
6277
|
n2({ type: Boolean })
|
|
5448
6278
|
], JupiterConceptTree.prototype, "showAddButton", 2);
|
|
5449
|
-
__decorateClass$
|
|
6279
|
+
__decorateClass$6([
|
|
5450
6280
|
n2({ type: Boolean })
|
|
5451
6281
|
], JupiterConceptTree.prototype, "showRemoveButton", 2);
|
|
5452
|
-
__decorateClass$
|
|
6282
|
+
__decorateClass$6([
|
|
5453
6283
|
n2({ type: String })
|
|
5454
6284
|
], JupiterConceptTree.prototype, "highlightType", 2);
|
|
5455
|
-
__decorateClass$
|
|
6285
|
+
__decorateClass$6([
|
|
5456
6286
|
n2({ type: String })
|
|
5457
6287
|
], JupiterConceptTree.prototype, "highlightColumnId", 2);
|
|
5458
|
-
__decorateClass$
|
|
6288
|
+
__decorateClass$6([
|
|
5459
6289
|
n2({ type: Object })
|
|
5460
6290
|
], JupiterConceptTree.prototype, "calculationMismatches", 2);
|
|
5461
|
-
__decorateClass$
|
|
6291
|
+
__decorateClass$6([
|
|
5462
6292
|
n2({ type: String })
|
|
5463
6293
|
], JupiterConceptTree.prototype, "language", 2);
|
|
5464
|
-
__decorateClass$
|
|
6294
|
+
__decorateClass$6([
|
|
5465
6295
|
n2({ type: Boolean })
|
|
5466
6296
|
], JupiterConceptTree.prototype, "rowFocused", 2);
|
|
5467
|
-
__decorateClass$
|
|
6297
|
+
__decorateClass$6([
|
|
5468
6298
|
r()
|
|
5469
6299
|
], JupiterConceptTree.prototype, "_expanded", 2);
|
|
5470
|
-
JupiterConceptTree = __decorateClass$
|
|
6300
|
+
JupiterConceptTree = __decorateClass$6([
|
|
5471
6301
|
t$1("jupiter-concept-tree")
|
|
5472
6302
|
], JupiterConceptTree);
|
|
5473
|
-
var __defProp$
|
|
5474
|
-
var __getOwnPropDesc$
|
|
5475
|
-
var __decorateClass$
|
|
5476
|
-
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$
|
|
6303
|
+
var __defProp$5 = Object.defineProperty;
|
|
6304
|
+
var __getOwnPropDesc$5 = Object.getOwnPropertyDescriptor;
|
|
6305
|
+
var __decorateClass$5 = (decorators, target, key, kind) => {
|
|
6306
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$5(target, key) : target;
|
|
5477
6307
|
for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
|
|
5478
6308
|
if (decorator = decorators[i2])
|
|
5479
6309
|
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
5480
6310
|
if (kind && result)
|
|
5481
|
-
__defProp$
|
|
6311
|
+
__defProp$5(target, key, result);
|
|
5482
6312
|
return result;
|
|
5483
6313
|
};
|
|
5484
6314
|
let JupiterAddColumnDialog = class extends LitElement {
|
|
@@ -6087,48 +6917,48 @@ JupiterAddColumnDialog.styles = css`
|
|
|
6087
6917
|
line-height: 1.4;
|
|
6088
6918
|
}
|
|
6089
6919
|
`;
|
|
6090
|
-
__decorateClass$
|
|
6920
|
+
__decorateClass$5([
|
|
6091
6921
|
n2({ type: String })
|
|
6092
6922
|
], JupiterAddColumnDialog.prototype, "periodType", 2);
|
|
6093
|
-
__decorateClass$
|
|
6923
|
+
__decorateClass$5([
|
|
6094
6924
|
n2({ type: Boolean })
|
|
6095
6925
|
], JupiterAddColumnDialog.prototype, "open", 2);
|
|
6096
|
-
__decorateClass$
|
|
6926
|
+
__decorateClass$5([
|
|
6097
6927
|
n2({ type: Array })
|
|
6098
6928
|
], JupiterAddColumnDialog.prototype, "availableDimensions", 2);
|
|
6099
|
-
__decorateClass$
|
|
6929
|
+
__decorateClass$5([
|
|
6100
6930
|
n2({ type: String })
|
|
6101
6931
|
], JupiterAddColumnDialog.prototype, "periodStartDate", 2);
|
|
6102
|
-
__decorateClass$
|
|
6932
|
+
__decorateClass$5([
|
|
6103
6933
|
n2({ type: String })
|
|
6104
6934
|
], JupiterAddColumnDialog.prototype, "periodEndDate", 2);
|
|
6105
|
-
__decorateClass$
|
|
6935
|
+
__decorateClass$5([
|
|
6106
6936
|
r()
|
|
6107
6937
|
], JupiterAddColumnDialog.prototype, "_startDate", 2);
|
|
6108
|
-
__decorateClass$
|
|
6938
|
+
__decorateClass$5([
|
|
6109
6939
|
r()
|
|
6110
6940
|
], JupiterAddColumnDialog.prototype, "_endDate", 2);
|
|
6111
|
-
__decorateClass$
|
|
6941
|
+
__decorateClass$5([
|
|
6112
6942
|
r()
|
|
6113
6943
|
], JupiterAddColumnDialog.prototype, "_instantDate", 2);
|
|
6114
|
-
__decorateClass$
|
|
6944
|
+
__decorateClass$5([
|
|
6115
6945
|
r()
|
|
6116
6946
|
], JupiterAddColumnDialog.prototype, "_selectedType", 2);
|
|
6117
|
-
__decorateClass$
|
|
6947
|
+
__decorateClass$5([
|
|
6118
6948
|
r()
|
|
6119
6949
|
], JupiterAddColumnDialog.prototype, "_selectedDimensions", 2);
|
|
6120
|
-
JupiterAddColumnDialog = __decorateClass$
|
|
6950
|
+
JupiterAddColumnDialog = __decorateClass$5([
|
|
6121
6951
|
t$1("jupiter-add-column-dialog")
|
|
6122
6952
|
], JupiterAddColumnDialog);
|
|
6123
|
-
var __defProp$
|
|
6124
|
-
var __getOwnPropDesc$
|
|
6125
|
-
var __decorateClass$
|
|
6126
|
-
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$
|
|
6953
|
+
var __defProp$4 = Object.defineProperty;
|
|
6954
|
+
var __getOwnPropDesc$4 = Object.getOwnPropertyDescriptor;
|
|
6955
|
+
var __decorateClass$4 = (decorators, target, key, kind) => {
|
|
6956
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$4(target, key) : target;
|
|
6127
6957
|
for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
|
|
6128
6958
|
if (decorator = decorators[i2])
|
|
6129
6959
|
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
6130
6960
|
if (kind && result)
|
|
6131
|
-
__defProp$
|
|
6961
|
+
__defProp$4(target, key, result);
|
|
6132
6962
|
return result;
|
|
6133
6963
|
};
|
|
6134
6964
|
let JupiterFormSection = class extends LitElement {
|
|
@@ -6155,6 +6985,7 @@ let JupiterFormSection = class extends LitElement {
|
|
|
6155
6985
|
this.periodEndDate = "";
|
|
6156
6986
|
this.language = "en";
|
|
6157
6987
|
this.calculationEnabled = false;
|
|
6988
|
+
this.totalManuallyEditedData = {};
|
|
6158
6989
|
this._expanded = true;
|
|
6159
6990
|
this._showAddColumnDialog = false;
|
|
6160
6991
|
this._sectionPeriodType = "duration";
|
|
@@ -6179,6 +7010,7 @@ let JupiterFormSection = class extends LitElement {
|
|
|
6179
7010
|
this._memberParentMap = /* @__PURE__ */ new Map();
|
|
6180
7011
|
this._totalConceptMap = /* @__PURE__ */ new Map();
|
|
6181
7012
|
this._totalChildConceptsMap = /* @__PURE__ */ new Map();
|
|
7013
|
+
this._sessionManuallyEditedTotals = /* @__PURE__ */ new Set();
|
|
6182
7014
|
}
|
|
6183
7015
|
connectedCallback() {
|
|
6184
7016
|
super.connectedCallback();
|
|
@@ -6206,6 +7038,9 @@ let JupiterFormSection = class extends LitElement {
|
|
|
6206
7038
|
this._clearCalculationState();
|
|
6207
7039
|
}
|
|
6208
7040
|
}
|
|
7041
|
+
if (changedProperties.has("totalManuallyEditedData")) {
|
|
7042
|
+
this._sessionManuallyEditedTotals.clear();
|
|
7043
|
+
}
|
|
6209
7044
|
}
|
|
6210
7045
|
_checkAndExpandFirstSection() {
|
|
6211
7046
|
if (this.isFirstSection && this.section && this.section.concepts) {
|
|
@@ -6355,6 +7190,15 @@ let JupiterFormSection = class extends LitElement {
|
|
|
6355
7190
|
}
|
|
6356
7191
|
_handleFieldChange(event) {
|
|
6357
7192
|
event.stopPropagation();
|
|
7193
|
+
const { conceptId, columnId } = event.detail || {};
|
|
7194
|
+
if (conceptId && columnId && this._totalConceptMap.has(conceptId)) {
|
|
7195
|
+
this._sessionManuallyEditedTotals.add(`${conceptId}__${columnId}`);
|
|
7196
|
+
this.dispatchEvent(new CustomEvent("total-manually-edited", {
|
|
7197
|
+
detail: { conceptId, columnId },
|
|
7198
|
+
bubbles: true,
|
|
7199
|
+
composed: true
|
|
7200
|
+
}));
|
|
7201
|
+
}
|
|
6358
7202
|
this.dispatchEvent(new CustomEvent("field-change", {
|
|
6359
7203
|
detail: event.detail,
|
|
6360
7204
|
bubbles: true,
|
|
@@ -6383,6 +7227,13 @@ let JupiterFormSection = class extends LitElement {
|
|
|
6383
7227
|
}
|
|
6384
7228
|
return result;
|
|
6385
7229
|
}
|
|
7230
|
+
_isTotalManuallyEdited(totalConceptId, columnId) {
|
|
7231
|
+
var _a, _b;
|
|
7232
|
+
const key = `${totalConceptId}__${columnId}`;
|
|
7233
|
+
if (this._sessionManuallyEditedTotals.has(key))
|
|
7234
|
+
return true;
|
|
7235
|
+
return ((_b = (_a = this.totalManuallyEditedData) == null ? void 0 : _a[totalConceptId]) == null ? void 0 : _b[columnId]) === true;
|
|
7236
|
+
}
|
|
6386
7237
|
/**
|
|
6387
7238
|
* Returns true when every column cell for a concept has no value.
|
|
6388
7239
|
* Used in readonly mode to hide fully-blank rows.
|
|
@@ -6463,7 +7314,7 @@ let JupiterFormSection = class extends LitElement {
|
|
|
6463
7314
|
* matching is the single source of truth for "is this row a total" everywhere in this file.
|
|
6464
7315
|
*/
|
|
6465
7316
|
static _isTotalLabel(preferredLabel) {
|
|
6466
|
-
return
|
|
7317
|
+
return isTotalLabel$1(preferredLabel);
|
|
6467
7318
|
}
|
|
6468
7319
|
/**
|
|
6469
7320
|
* JDF-041: distinguishes a self-contained "deduction block" subtotal (negatedTotalLabel, e.g.
|
|
@@ -6584,10 +7435,29 @@ let JupiterFormSection = class extends LitElement {
|
|
|
6584
7435
|
}
|
|
6585
7436
|
}
|
|
6586
7437
|
_evaluateTotal(totalConceptId, columnId) {
|
|
6587
|
-
var _a;
|
|
7438
|
+
var _a, _b;
|
|
6588
7439
|
const totalConcept = this._totalConceptMap.get(totalConceptId);
|
|
6589
|
-
const totalRaw = (_a = this.formData[totalConceptId]) == null ? void 0 : _a[columnId];
|
|
6590
7440
|
const key = `${totalConceptId}__${columnId}`;
|
|
7441
|
+
const children = this._totalChildConceptsMap.get(totalConceptId) || [];
|
|
7442
|
+
const { calculatedSum, hasAnyValue, breakdown } = this._buildCalculationBreakdown(
|
|
7443
|
+
children,
|
|
7444
|
+
this.formData,
|
|
7445
|
+
columnId,
|
|
7446
|
+
totalConcept.balance
|
|
7447
|
+
);
|
|
7448
|
+
if (!this._isTotalManuallyEdited(totalConceptId, columnId)) {
|
|
7449
|
+
if (hasAnyValue) {
|
|
7450
|
+
const currentRaw = (_a = this.formData[totalConceptId]) == null ? void 0 : _a[columnId];
|
|
7451
|
+
const currentValue = parseFloat(currentRaw);
|
|
7452
|
+
const isBlank = currentRaw === null || currentRaw === void 0 || currentRaw === "";
|
|
7453
|
+
if (isBlank || isNaN(currentValue) || !JupiterFormSection._checkTotal(currentValue, calculatedSum)) {
|
|
7454
|
+
this._dispatchCalculationTotalAutoPopulated(totalConceptId, columnId, calculatedSum);
|
|
7455
|
+
}
|
|
7456
|
+
}
|
|
7457
|
+
this._clearCalculationMismatch(key);
|
|
7458
|
+
return;
|
|
7459
|
+
}
|
|
7460
|
+
const totalRaw = (_b = this.formData[totalConceptId]) == null ? void 0 : _b[columnId];
|
|
6591
7461
|
if (totalRaw === null || totalRaw === void 0 || totalRaw === "") {
|
|
6592
7462
|
this._clearCalculationMismatch(key);
|
|
6593
7463
|
return;
|
|
@@ -6597,13 +7467,6 @@ let JupiterFormSection = class extends LitElement {
|
|
|
6597
7467
|
this._clearCalculationMismatch(key);
|
|
6598
7468
|
return;
|
|
6599
7469
|
}
|
|
6600
|
-
const children = this._totalChildConceptsMap.get(totalConceptId) || [];
|
|
6601
|
-
const { calculatedSum, hasAnyValue, breakdown } = this._buildCalculationBreakdown(
|
|
6602
|
-
children,
|
|
6603
|
-
this.formData,
|
|
6604
|
-
columnId,
|
|
6605
|
-
totalConcept.balance
|
|
6606
|
-
);
|
|
6607
7470
|
if (!hasAnyValue || JupiterFormSection._checkTotal(totalValue, calculatedSum)) {
|
|
6608
7471
|
this._clearCalculationMismatch(key);
|
|
6609
7472
|
return;
|
|
@@ -6626,6 +7489,13 @@ let JupiterFormSection = class extends LitElement {
|
|
|
6626
7489
|
this._calculationMismatches = next;
|
|
6627
7490
|
this._dispatchCalculationMismatchChanged(key, detail);
|
|
6628
7491
|
}
|
|
7492
|
+
_dispatchCalculationTotalAutoPopulated(conceptId, columnId, value) {
|
|
7493
|
+
this.dispatchEvent(new CustomEvent("calculation-total-auto-populated", {
|
|
7494
|
+
detail: { conceptId, columnId, value, sectionId: this.section.id },
|
|
7495
|
+
bubbles: true,
|
|
7496
|
+
composed: true
|
|
7497
|
+
}));
|
|
7498
|
+
}
|
|
6629
7499
|
_clearCalculationMismatch(key) {
|
|
6630
7500
|
if (!this._calculationMismatches.has(key))
|
|
6631
7501
|
return;
|
|
@@ -6689,7 +7559,7 @@ let JupiterFormSection = class extends LitElement {
|
|
|
6689
7559
|
return { calculatedSum, hasAnyValue, breakdown };
|
|
6690
7560
|
}
|
|
6691
7561
|
static _checkTotal(totalValue, calculatedSum) {
|
|
6692
|
-
return Math.abs(calculatedSum - totalValue) <
|
|
7562
|
+
return Math.abs(calculatedSum - totalValue) < CALCULATION_TOLERANCE;
|
|
6693
7563
|
}
|
|
6694
7564
|
static _formatNumber(n3) {
|
|
6695
7565
|
return Number.isInteger(n3) ? String(n3) : n3.toFixed(2);
|
|
@@ -7275,123 +8145,126 @@ JupiterFormSection.styles = css`
|
|
|
7275
8145
|
font-style: italic;
|
|
7276
8146
|
}
|
|
7277
8147
|
`;
|
|
7278
|
-
__decorateClass$
|
|
8148
|
+
__decorateClass$4([
|
|
7279
8149
|
n2({ type: Object })
|
|
7280
8150
|
], JupiterFormSection.prototype, "section", 2);
|
|
7281
|
-
__decorateClass$
|
|
8151
|
+
__decorateClass$4([
|
|
7282
8152
|
n2({ type: Array })
|
|
7283
8153
|
], JupiterFormSection.prototype, "columns", 2);
|
|
7284
|
-
__decorateClass$
|
|
8154
|
+
__decorateClass$4([
|
|
7285
8155
|
n2({ type: Array })
|
|
7286
8156
|
], JupiterFormSection.prototype, "datatypes", 2);
|
|
7287
|
-
__decorateClass$
|
|
8157
|
+
__decorateClass$4([
|
|
7288
8158
|
n2({ type: Object })
|
|
7289
8159
|
], JupiterFormSection.prototype, "formData", 2);
|
|
7290
|
-
__decorateClass$
|
|
8160
|
+
__decorateClass$4([
|
|
7291
8161
|
n2({ type: Object })
|
|
7292
8162
|
], JupiterFormSection.prototype, "periodData", 2);
|
|
7293
|
-
__decorateClass$
|
|
8163
|
+
__decorateClass$4([
|
|
7294
8164
|
n2({ type: Object })
|
|
7295
8165
|
], JupiterFormSection.prototype, "unitData", 2);
|
|
7296
|
-
__decorateClass$
|
|
8166
|
+
__decorateClass$4([
|
|
7297
8167
|
n2({ type: Object })
|
|
7298
8168
|
], JupiterFormSection.prototype, "decimalsData", 2);
|
|
7299
|
-
__decorateClass$
|
|
8169
|
+
__decorateClass$4([
|
|
7300
8170
|
n2({ type: String })
|
|
7301
8171
|
], JupiterFormSection.prototype, "globalDecimals", 2);
|
|
7302
|
-
__decorateClass$
|
|
8172
|
+
__decorateClass$4([
|
|
7303
8173
|
n2({ type: Object })
|
|
7304
8174
|
], JupiterFormSection.prototype, "typedMemberData", 2);
|
|
7305
|
-
__decorateClass$
|
|
8175
|
+
__decorateClass$4([
|
|
7306
8176
|
n2({ type: Object })
|
|
7307
8177
|
], JupiterFormSection.prototype, "repeatCounts", 2);
|
|
7308
|
-
__decorateClass$
|
|
8178
|
+
__decorateClass$4([
|
|
7309
8179
|
n2({ type: Array })
|
|
7310
8180
|
], JupiterFormSection.prototype, "defaultUnits", 2);
|
|
7311
|
-
__decorateClass$
|
|
8181
|
+
__decorateClass$4([
|
|
7312
8182
|
n2({ type: Boolean })
|
|
7313
8183
|
], JupiterFormSection.prototype, "disabled", 2);
|
|
7314
|
-
__decorateClass$
|
|
8184
|
+
__decorateClass$4([
|
|
7315
8185
|
n2({ type: Boolean })
|
|
7316
8186
|
], JupiterFormSection.prototype, "collapsible", 2);
|
|
7317
|
-
__decorateClass$
|
|
8187
|
+
__decorateClass$4([
|
|
7318
8188
|
n2({ type: String })
|
|
7319
8189
|
], JupiterFormSection.prototype, "locale", 2);
|
|
7320
|
-
__decorateClass$
|
|
8190
|
+
__decorateClass$4([
|
|
7321
8191
|
n2({ type: Boolean })
|
|
7322
8192
|
], JupiterFormSection.prototype, "isFirstSection", 2);
|
|
7323
|
-
__decorateClass$
|
|
8193
|
+
__decorateClass$4([
|
|
7324
8194
|
n2({ type: Array })
|
|
7325
8195
|
], JupiterFormSection.prototype, "availableDimensions", 2);
|
|
7326
|
-
__decorateClass$
|
|
8196
|
+
__decorateClass$4([
|
|
7327
8197
|
n2({ type: Boolean })
|
|
7328
8198
|
], JupiterFormSection.prototype, "hideHeader", 2);
|
|
7329
|
-
__decorateClass$
|
|
8199
|
+
__decorateClass$4([
|
|
7330
8200
|
n2({ type: String })
|
|
7331
8201
|
], JupiterFormSection.prototype, "mode", 2);
|
|
7332
|
-
__decorateClass$
|
|
8202
|
+
__decorateClass$4([
|
|
7333
8203
|
n2({ type: Boolean })
|
|
7334
8204
|
], JupiterFormSection.prototype, "showFactsOnly", 2);
|
|
7335
|
-
__decorateClass$
|
|
8205
|
+
__decorateClass$4([
|
|
7336
8206
|
n2({ type: Object })
|
|
7337
8207
|
], JupiterFormSection.prototype, "conceptMatchIds", 2);
|
|
7338
|
-
__decorateClass$
|
|
8208
|
+
__decorateClass$4([
|
|
7339
8209
|
n2({ type: Object })
|
|
7340
8210
|
], JupiterFormSection.prototype, "masterData", 2);
|
|
7341
|
-
__decorateClass$
|
|
8211
|
+
__decorateClass$4([
|
|
7342
8212
|
n2({ type: String })
|
|
7343
8213
|
], JupiterFormSection.prototype, "periodStartDate", 2);
|
|
7344
|
-
__decorateClass$
|
|
8214
|
+
__decorateClass$4([
|
|
7345
8215
|
n2({ type: String })
|
|
7346
8216
|
], JupiterFormSection.prototype, "periodEndDate", 2);
|
|
7347
|
-
__decorateClass$
|
|
8217
|
+
__decorateClass$4([
|
|
7348
8218
|
n2({ type: String })
|
|
7349
8219
|
], JupiterFormSection.prototype, "language", 2);
|
|
7350
|
-
__decorateClass$
|
|
8220
|
+
__decorateClass$4([
|
|
7351
8221
|
n2({ type: Boolean })
|
|
7352
8222
|
], JupiterFormSection.prototype, "calculationEnabled", 2);
|
|
7353
|
-
__decorateClass$
|
|
8223
|
+
__decorateClass$4([
|
|
8224
|
+
n2({ type: Object })
|
|
8225
|
+
], JupiterFormSection.prototype, "totalManuallyEditedData", 2);
|
|
8226
|
+
__decorateClass$4([
|
|
7354
8227
|
r()
|
|
7355
8228
|
], JupiterFormSection.prototype, "_expanded", 2);
|
|
7356
|
-
__decorateClass$
|
|
8229
|
+
__decorateClass$4([
|
|
7357
8230
|
r()
|
|
7358
8231
|
], JupiterFormSection.prototype, "_showAddColumnDialog", 2);
|
|
7359
|
-
__decorateClass$
|
|
8232
|
+
__decorateClass$4([
|
|
7360
8233
|
r()
|
|
7361
8234
|
], JupiterFormSection.prototype, "_sectionPeriodType", 2);
|
|
7362
|
-
__decorateClass$
|
|
8235
|
+
__decorateClass$4([
|
|
7363
8236
|
r()
|
|
7364
8237
|
], JupiterFormSection.prototype, "_openMenuColumnId", 2);
|
|
7365
|
-
__decorateClass$
|
|
8238
|
+
__decorateClass$4([
|
|
7366
8239
|
r()
|
|
7367
8240
|
], JupiterFormSection.prototype, "_insertAfterColumnId", 2);
|
|
7368
|
-
__decorateClass$
|
|
8241
|
+
__decorateClass$4([
|
|
7369
8242
|
r()
|
|
7370
8243
|
], JupiterFormSection.prototype, "_expandedConcepts", 2);
|
|
7371
|
-
__decorateClass$
|
|
8244
|
+
__decorateClass$4([
|
|
7372
8245
|
r()
|
|
7373
8246
|
], JupiterFormSection.prototype, "_allTreeExpanded", 2);
|
|
7374
|
-
__decorateClass$
|
|
8247
|
+
__decorateClass$4([
|
|
7375
8248
|
r()
|
|
7376
8249
|
], JupiterFormSection.prototype, "_highlightMap", 2);
|
|
7377
|
-
__decorateClass$
|
|
8250
|
+
__decorateClass$4([
|
|
7378
8251
|
r()
|
|
7379
8252
|
], JupiterFormSection.prototype, "_focusedConceptId", 2);
|
|
7380
|
-
__decorateClass$
|
|
8253
|
+
__decorateClass$4([
|
|
7381
8254
|
r()
|
|
7382
8255
|
], JupiterFormSection.prototype, "_calculationMismatches", 2);
|
|
7383
|
-
JupiterFormSection = __decorateClass$
|
|
8256
|
+
JupiterFormSection = __decorateClass$4([
|
|
7384
8257
|
t$1("jupiter-form-section")
|
|
7385
8258
|
], JupiterFormSection);
|
|
7386
|
-
var __defProp$
|
|
7387
|
-
var __getOwnPropDesc$
|
|
7388
|
-
var __decorateClass$
|
|
7389
|
-
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$
|
|
8259
|
+
var __defProp$3 = Object.defineProperty;
|
|
8260
|
+
var __getOwnPropDesc$3 = Object.getOwnPropertyDescriptor;
|
|
8261
|
+
var __decorateClass$3 = (decorators, target, key, kind) => {
|
|
8262
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$3(target, key) : target;
|
|
7390
8263
|
for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
|
|
7391
8264
|
if (decorator = decorators[i2])
|
|
7392
8265
|
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
7393
8266
|
if (kind && result)
|
|
7394
|
-
__defProp$
|
|
8267
|
+
__defProp$3(target, key, result);
|
|
7395
8268
|
return result;
|
|
7396
8269
|
};
|
|
7397
8270
|
let JupiterAdvancedFilter = class extends LitElement {
|
|
@@ -7580,27 +8453,27 @@ JupiterAdvancedFilter.styles = css`
|
|
|
7580
8453
|
color: var(--primaryTextColor, var(--jupiter-text-primary, #333));
|
|
7581
8454
|
}
|
|
7582
8455
|
`;
|
|
7583
|
-
__decorateClass$
|
|
8456
|
+
__decorateClass$3([
|
|
7584
8457
|
n2({ type: Boolean })
|
|
7585
8458
|
], JupiterAdvancedFilter.prototype, "showFactsOnly", 2);
|
|
7586
|
-
__decorateClass$
|
|
8459
|
+
__decorateClass$3([
|
|
7587
8460
|
n2({ type: String })
|
|
7588
8461
|
], JupiterAdvancedFilter.prototype, "conceptSearchText", 2);
|
|
7589
|
-
__decorateClass$
|
|
8462
|
+
__decorateClass$3([
|
|
7590
8463
|
r()
|
|
7591
8464
|
], JupiterAdvancedFilter.prototype, "_localConceptSearchText", 2);
|
|
7592
|
-
JupiterAdvancedFilter = __decorateClass$
|
|
8465
|
+
JupiterAdvancedFilter = __decorateClass$3([
|
|
7593
8466
|
t$1("jupiter-advanced-filter")
|
|
7594
8467
|
], JupiterAdvancedFilter);
|
|
7595
|
-
var __defProp$
|
|
7596
|
-
var __getOwnPropDesc$
|
|
7597
|
-
var __decorateClass$
|
|
7598
|
-
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$
|
|
8468
|
+
var __defProp$2 = Object.defineProperty;
|
|
8469
|
+
var __getOwnPropDesc$2 = Object.getOwnPropertyDescriptor;
|
|
8470
|
+
var __decorateClass$2 = (decorators, target, key, kind) => {
|
|
8471
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$2(target, key) : target;
|
|
7599
8472
|
for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
|
|
7600
8473
|
if (decorator = decorators[i2])
|
|
7601
8474
|
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
7602
8475
|
if (kind && result)
|
|
7603
|
-
__defProp$
|
|
8476
|
+
__defProp$2(target, key, result);
|
|
7604
8477
|
return result;
|
|
7605
8478
|
};
|
|
7606
8479
|
let _lastViewWasAdvancedFilter = false;
|
|
@@ -9191,188 +10064,519 @@ JupiterFilterRolesDialog.styles = css`
|
|
|
9191
10064
|
font-size: 14px;
|
|
9192
10065
|
}
|
|
9193
10066
|
|
|
9194
|
-
.picklist-search {
|
|
9195
|
-
padding: 12px;
|
|
9196
|
-
border-bottom: 1px solid var(--jupiter-border-color, #ddd);
|
|
10067
|
+
.picklist-search {
|
|
10068
|
+
padding: 12px;
|
|
10069
|
+
border-bottom: 1px solid var(--jupiter-border-color, #ddd);
|
|
10070
|
+
}
|
|
10071
|
+
|
|
10072
|
+
.picklist-list {
|
|
10073
|
+
flex: 1;
|
|
10074
|
+
overflow-y: auto;
|
|
10075
|
+
padding: 8px;
|
|
10076
|
+
}
|
|
10077
|
+
|
|
10078
|
+
.picklist-item {
|
|
10079
|
+
padding: 10px 12px;
|
|
10080
|
+
margin-bottom: 4px;
|
|
10081
|
+
border: 1px solid var(--jupiter-border-color, #ddd);
|
|
10082
|
+
border-radius: 4px;
|
|
10083
|
+
cursor: pointer;
|
|
10084
|
+
transition: all 0.2s ease;
|
|
10085
|
+
background: var(--jupiter-background, #fff);
|
|
10086
|
+
}
|
|
10087
|
+
|
|
10088
|
+
.picklist-item:hover {
|
|
10089
|
+
background: var(--jupiter-hover-background, #f5f5f5);
|
|
10090
|
+
border-color: var(--jupiter-primary-color, #1976d2);
|
|
10091
|
+
}
|
|
10092
|
+
|
|
10093
|
+
.picklist-item.selected {
|
|
10094
|
+
background: var(--jupiter-primary-color, #1976d2);
|
|
10095
|
+
color: white;
|
|
10096
|
+
border-color: var(--jupiter-primary-color, #1976d2);
|
|
10097
|
+
}
|
|
10098
|
+
|
|
10099
|
+
.picklist-item.dragging {
|
|
10100
|
+
opacity: 0.5;
|
|
10101
|
+
cursor: move;
|
|
10102
|
+
}
|
|
10103
|
+
|
|
10104
|
+
.picklist-item.drag-over {
|
|
10105
|
+
border-top: 3px solid var(--jupiter-primary-color, #1976d2);
|
|
10106
|
+
margin-top: 3px;
|
|
10107
|
+
}
|
|
10108
|
+
|
|
10109
|
+
.picklist-item[draggable="true"] {
|
|
10110
|
+
cursor: move;
|
|
10111
|
+
}
|
|
10112
|
+
|
|
10113
|
+
.picklist-item-label {
|
|
10114
|
+
font-weight: 500;
|
|
10115
|
+
font-size: 14px;
|
|
10116
|
+
margin-bottom: 4px;
|
|
10117
|
+
}
|
|
10118
|
+
|
|
10119
|
+
.picklist-item-value {
|
|
10120
|
+
font-size: 11px;
|
|
10121
|
+
opacity: 0.8;
|
|
10122
|
+
word-break: break-all;
|
|
10123
|
+
}
|
|
10124
|
+
|
|
10125
|
+
.picklist-controls {
|
|
10126
|
+
display: flex;
|
|
10127
|
+
flex-direction: column;
|
|
10128
|
+
justify-content: center;
|
|
10129
|
+
gap: 8px;
|
|
10130
|
+
padding: 0 8px;
|
|
10131
|
+
}
|
|
10132
|
+
|
|
10133
|
+
.picklist-button {
|
|
10134
|
+
background: var(--jupiter-primary-color, #1976d2);
|
|
10135
|
+
color: white;
|
|
10136
|
+
border: none;
|
|
10137
|
+
padding: 8px 16px;
|
|
10138
|
+
border-radius: 4px;
|
|
10139
|
+
cursor: pointer;
|
|
10140
|
+
font-size: 14px;
|
|
10141
|
+
transition: background-color 0.2s ease;
|
|
10142
|
+
}
|
|
10143
|
+
|
|
10144
|
+
.picklist-button:hover:not(:disabled) {
|
|
10145
|
+
background: var(--jupiter-primary-color-dark, #1565c0);
|
|
10146
|
+
}
|
|
10147
|
+
|
|
10148
|
+
.picklist-button:disabled {
|
|
10149
|
+
opacity: 0.4;
|
|
10150
|
+
cursor: not-allowed;
|
|
10151
|
+
}
|
|
10152
|
+
|
|
10153
|
+
.picklist-count {
|
|
10154
|
+
padding: 8px 12px;
|
|
10155
|
+
font-size: 12px;
|
|
10156
|
+
color: var(--jupiter-text-secondary, #666);
|
|
10157
|
+
background: var(--jupiter-background-light, #f8f9fa);
|
|
10158
|
+
border-top: 1px solid var(--jupiter-border-color, #ddd);
|
|
10159
|
+
text-align: center;
|
|
10160
|
+
}
|
|
10161
|
+
|
|
10162
|
+
.btn-text {
|
|
10163
|
+
background: none;
|
|
10164
|
+
border: none;
|
|
10165
|
+
color: var(--buttonBgColor, var(--jupiter-primary-color, #1976d2));
|
|
10166
|
+
padding: 10px 8px;
|
|
10167
|
+
font-size: 14px;
|
|
10168
|
+
font-weight: 500;
|
|
10169
|
+
font-family: inherit;
|
|
10170
|
+
cursor: pointer;
|
|
10171
|
+
margin-right: auto;
|
|
10172
|
+
border-radius: 4px;
|
|
10173
|
+
transition: background-color 0.2s ease;
|
|
10174
|
+
}
|
|
10175
|
+
|
|
10176
|
+
.btn-text:hover {
|
|
10177
|
+
background: var(--menuBgColorLighter, var(--jupiter-hover-background, #f5f5f5));
|
|
10178
|
+
}
|
|
10179
|
+
`;
|
|
10180
|
+
__decorateClass$2([
|
|
10181
|
+
n2({ type: Boolean, reflect: true })
|
|
10182
|
+
], JupiterFilterRolesDialog.prototype, "open", 2);
|
|
10183
|
+
__decorateClass$2([
|
|
10184
|
+
n2({ type: Array })
|
|
10185
|
+
], JupiterFilterRolesDialog.prototype, "availableRoles", 2);
|
|
10186
|
+
__decorateClass$2([
|
|
10187
|
+
n2({ type: Array })
|
|
10188
|
+
], JupiterFilterRolesDialog.prototype, "selectedRoleIds", 2);
|
|
10189
|
+
__decorateClass$2([
|
|
10190
|
+
n2({ type: Object })
|
|
10191
|
+
], JupiterFilterRolesDialog.prototype, "periodPreferences", 2);
|
|
10192
|
+
__decorateClass$2([
|
|
10193
|
+
n2({ type: String })
|
|
10194
|
+
], JupiterFilterRolesDialog.prototype, "mode", 2);
|
|
10195
|
+
__decorateClass$2([
|
|
10196
|
+
n2({ type: Object })
|
|
10197
|
+
], JupiterFilterRolesDialog.prototype, "hypercubeData", 2);
|
|
10198
|
+
__decorateClass$2([
|
|
10199
|
+
n2({ type: Boolean })
|
|
10200
|
+
], JupiterFilterRolesDialog.prototype, "showFactsOnly", 2);
|
|
10201
|
+
__decorateClass$2([
|
|
10202
|
+
n2({ type: String })
|
|
10203
|
+
], JupiterFilterRolesDialog.prototype, "conceptSearchText", 2);
|
|
10204
|
+
__decorateClass$2([
|
|
10205
|
+
r()
|
|
10206
|
+
], JupiterFilterRolesDialog.prototype, "_tempSelectedRoles", 2);
|
|
10207
|
+
__decorateClass$2([
|
|
10208
|
+
r()
|
|
10209
|
+
], JupiterFilterRolesDialog.prototype, "_searchQuery", 2);
|
|
10210
|
+
__decorateClass$2([
|
|
10211
|
+
r()
|
|
10212
|
+
], JupiterFilterRolesDialog.prototype, "_filteredRoles", 2);
|
|
10213
|
+
__decorateClass$2([
|
|
10214
|
+
r()
|
|
10215
|
+
], JupiterFilterRolesDialog.prototype, "_tempPeriodPreferences", 2);
|
|
10216
|
+
__decorateClass$2([
|
|
10217
|
+
r()
|
|
10218
|
+
], JupiterFilterRolesDialog.prototype, "_selectedAvailableRole", 2);
|
|
10219
|
+
__decorateClass$2([
|
|
10220
|
+
r()
|
|
10221
|
+
], JupiterFilterRolesDialog.prototype, "_selectedChosenRole", 2);
|
|
10222
|
+
__decorateClass$2([
|
|
10223
|
+
r()
|
|
10224
|
+
], JupiterFilterRolesDialog.prototype, "_chosenSearchQuery", 2);
|
|
10225
|
+
__decorateClass$2([
|
|
10226
|
+
r()
|
|
10227
|
+
], JupiterFilterRolesDialog.prototype, "_draggedRoleId", 2);
|
|
10228
|
+
__decorateClass$2([
|
|
10229
|
+
r()
|
|
10230
|
+
], JupiterFilterRolesDialog.prototype, "_dragOverRoleId", 2);
|
|
10231
|
+
__decorateClass$2([
|
|
10232
|
+
r()
|
|
10233
|
+
], JupiterFilterRolesDialog.prototype, "_chosenRoleOrder", 2);
|
|
10234
|
+
__decorateClass$2([
|
|
10235
|
+
r()
|
|
10236
|
+
], JupiterFilterRolesDialog.prototype, "_showAdvancedFilter", 2);
|
|
10237
|
+
__decorateClass$2([
|
|
10238
|
+
r()
|
|
10239
|
+
], JupiterFilterRolesDialog.prototype, "_showFactsOnly", 2);
|
|
10240
|
+
__decorateClass$2([
|
|
10241
|
+
r()
|
|
10242
|
+
], JupiterFilterRolesDialog.prototype, "_conceptSearchText", 2);
|
|
10243
|
+
__decorateClass$2([
|
|
10244
|
+
r()
|
|
10245
|
+
], JupiterFilterRolesDialog.prototype, "_collapsedRoles", 2);
|
|
10246
|
+
JupiterFilterRolesDialog = __decorateClass$2([
|
|
10247
|
+
t$1("jupiter-filter-roles-dialog")
|
|
10248
|
+
], JupiterFilterRolesDialog);
|
|
10249
|
+
var __defProp$1 = Object.defineProperty;
|
|
10250
|
+
var __getOwnPropDesc$1 = Object.getOwnPropertyDescriptor;
|
|
10251
|
+
var __decorateClass$1 = (decorators, target, key, kind) => {
|
|
10252
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$1(target, key) : target;
|
|
10253
|
+
for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
|
|
10254
|
+
if (decorator = decorators[i2])
|
|
10255
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
10256
|
+
if (kind && result)
|
|
10257
|
+
__defProp$1(target, key, result);
|
|
10258
|
+
return result;
|
|
10259
|
+
};
|
|
10260
|
+
let JupiterFormulaValidationDialog = class extends LitElement {
|
|
10261
|
+
constructor() {
|
|
10262
|
+
super(...arguments);
|
|
10263
|
+
this.results = [];
|
|
10264
|
+
this.open = false;
|
|
10265
|
+
this._collapsedGroups = /* @__PURE__ */ new Set();
|
|
10266
|
+
this._boundHandleKeydown = this._handleKeydown.bind(this);
|
|
10267
|
+
}
|
|
10268
|
+
connectedCallback() {
|
|
10269
|
+
super.connectedCallback();
|
|
10270
|
+
window.addEventListener("keydown", this._boundHandleKeydown);
|
|
10271
|
+
}
|
|
10272
|
+
disconnectedCallback() {
|
|
10273
|
+
window.removeEventListener("keydown", this._boundHandleKeydown);
|
|
10274
|
+
super.disconnectedCallback();
|
|
10275
|
+
}
|
|
10276
|
+
_handleKeydown(event) {
|
|
10277
|
+
if (this.open && event.key === "Escape") {
|
|
10278
|
+
this._handleClose();
|
|
10279
|
+
}
|
|
10280
|
+
}
|
|
10281
|
+
_handleClose() {
|
|
10282
|
+
this.open = false;
|
|
10283
|
+
this.dispatchEvent(new CustomEvent("dialog-cancel", { bubbles: true }));
|
|
10284
|
+
}
|
|
10285
|
+
_toggleGroup(roleLabel) {
|
|
10286
|
+
if (this._collapsedGroups.has(roleLabel)) {
|
|
10287
|
+
this._collapsedGroups.delete(roleLabel);
|
|
10288
|
+
} else {
|
|
10289
|
+
this._collapsedGroups.add(roleLabel);
|
|
10290
|
+
}
|
|
10291
|
+
this.requestUpdate();
|
|
10292
|
+
}
|
|
10293
|
+
_groupByRole(failures) {
|
|
10294
|
+
const grouped = failures.reduce((groups, result) => {
|
|
10295
|
+
var _a;
|
|
10296
|
+
(groups[_a = result.roleLabel] ?? (groups[_a] = [])).push(result);
|
|
10297
|
+
return groups;
|
|
10298
|
+
}, {});
|
|
10299
|
+
return Object.entries(grouped);
|
|
10300
|
+
}
|
|
10301
|
+
render() {
|
|
10302
|
+
if (!this.open)
|
|
10303
|
+
return html``;
|
|
10304
|
+
const failures = this.results.filter((result) => !result.skipped && !result.satisfied);
|
|
10305
|
+
const groups = this._groupByRole(failures);
|
|
10306
|
+
const summary = this.summary;
|
|
10307
|
+
return html`
|
|
10308
|
+
<div class="dialog" @click="${(e2) => e2.stopPropagation()}">
|
|
10309
|
+
<div class="dialog-header">
|
|
10310
|
+
<h2 class="dialog-title">${I18n.t("formulaValidation.dialogTitle")}</h2>
|
|
10311
|
+
${summary ? html`
|
|
10312
|
+
<p class="dialog-summary">
|
|
10313
|
+
${I18n.t("formulaValidation.summaryCount", { failed: summary.failed, total: summary.totalAssertions })}
|
|
10314
|
+
${summary.failed > 0 ? html`— ${I18n.t("formulaValidation.summaryCountBreakdown", { warnings: summary.failedWarnings, errors: summary.failedErrors })}` : ""}
|
|
10315
|
+
</p>
|
|
10316
|
+
` : ""}
|
|
10317
|
+
</div>
|
|
10318
|
+
|
|
10319
|
+
<div class="dialog-content">
|
|
10320
|
+
${failures.length === 0 ? html`
|
|
10321
|
+
<div class="all-passed">
|
|
10322
|
+
<div class="all-passed-icon">✓</div>
|
|
10323
|
+
<div class="all-passed-text">${I18n.t("formulaValidation.allPassed")}</div>
|
|
10324
|
+
</div>
|
|
10325
|
+
` : groups.map(([roleLabel, rows]) => {
|
|
10326
|
+
const collapsed = this._collapsedGroups.has(roleLabel);
|
|
10327
|
+
return html`
|
|
10328
|
+
<div class="role-group">
|
|
10329
|
+
<div class="role-group-header" @click="${() => this._toggleGroup(roleLabel)}">
|
|
10330
|
+
<span class="role-group-title">${roleLabel}</span>
|
|
10331
|
+
<span class="role-group-count">${rows.length}</span>
|
|
10332
|
+
<button class="role-group-toggle" type="button">${collapsed ? "▸" : "▾"}</button>
|
|
10333
|
+
</div>
|
|
10334
|
+
${collapsed ? "" : html`
|
|
10335
|
+
<div class="role-group-rows">
|
|
10336
|
+
${rows.map((result) => html`
|
|
10337
|
+
<div class="assertion-row">
|
|
10338
|
+
<span class="severity-badge ${result.severity === "ERROR" ? "error" : "warning"}">
|
|
10339
|
+
${result.severity === "ERROR" ? I18n.t("formulaValidation.severityError") : I18n.t("formulaValidation.severityWarning")}
|
|
10340
|
+
</span>
|
|
10341
|
+
<span class="assertion-message">${result.message}</span>
|
|
10342
|
+
</div>
|
|
10343
|
+
`)}
|
|
10344
|
+
</div>
|
|
10345
|
+
`}
|
|
10346
|
+
</div>
|
|
10347
|
+
`;
|
|
10348
|
+
})}
|
|
10349
|
+
</div>
|
|
10350
|
+
|
|
10351
|
+
<div class="dialog-actions">
|
|
10352
|
+
<button class="btn btn-primary" @click="${this._handleClose}">
|
|
10353
|
+
${I18n.t("formulaValidation.close")}
|
|
10354
|
+
</button>
|
|
10355
|
+
</div>
|
|
10356
|
+
</div>
|
|
10357
|
+
`;
|
|
10358
|
+
}
|
|
10359
|
+
};
|
|
10360
|
+
JupiterFormulaValidationDialog.styles = css`
|
|
10361
|
+
:host {
|
|
10362
|
+
position: fixed;
|
|
10363
|
+
top: 0;
|
|
10364
|
+
left: 0;
|
|
10365
|
+
width: 100%;
|
|
10366
|
+
height: 100%;
|
|
10367
|
+
background: rgba(0, 0, 0, 0.5);
|
|
10368
|
+
z-index: 1100;
|
|
10369
|
+
display: flex;
|
|
10370
|
+
align-items: center;
|
|
10371
|
+
justify-content: center;
|
|
10372
|
+
opacity: 0;
|
|
10373
|
+
visibility: hidden;
|
|
10374
|
+
transition: opacity 0.3s ease, visibility 0.3s ease;
|
|
10375
|
+
}
|
|
10376
|
+
|
|
10377
|
+
:host([open]) {
|
|
10378
|
+
opacity: 1;
|
|
10379
|
+
visibility: visible;
|
|
10380
|
+
}
|
|
10381
|
+
|
|
10382
|
+
.dialog {
|
|
10383
|
+
background: var(--bg-color-2, var(--jupiter-card-background, #fff));
|
|
10384
|
+
border-radius: 8px;
|
|
10385
|
+
padding: 24px;
|
|
10386
|
+
min-width: 420px;
|
|
10387
|
+
max-width: 640px;
|
|
10388
|
+
width: 90vw;
|
|
10389
|
+
max-height: 90vh;
|
|
10390
|
+
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
|
|
10391
|
+
transform: scale(0.9);
|
|
10392
|
+
transition: transform 0.3s ease;
|
|
10393
|
+
display: flex;
|
|
10394
|
+
flex-direction: column;
|
|
10395
|
+
}
|
|
10396
|
+
|
|
10397
|
+
:host([open]) .dialog {
|
|
10398
|
+
transform: scale(1);
|
|
10399
|
+
}
|
|
10400
|
+
|
|
10401
|
+
.dialog-header {
|
|
10402
|
+
margin-bottom: 16px;
|
|
10403
|
+
flex-shrink: 0;
|
|
10404
|
+
}
|
|
10405
|
+
|
|
10406
|
+
.dialog-title {
|
|
10407
|
+
font-size: 20px;
|
|
10408
|
+
font-weight: 600;
|
|
10409
|
+
color: var(--primaryTextColor, var(--jupiter-text-primary, #333));
|
|
10410
|
+
margin: 0 0 8px 0;
|
|
10411
|
+
}
|
|
10412
|
+
|
|
10413
|
+
.dialog-summary {
|
|
10414
|
+
font-size: 14px;
|
|
10415
|
+
color: var(--jupiter-text-secondary, #666);
|
|
10416
|
+
margin: 0;
|
|
10417
|
+
}
|
|
10418
|
+
|
|
10419
|
+
/* JDF-035 dialog-overflow fix: min-height: 0 is required on a flex-column scrollable child,
|
|
10420
|
+
otherwise the browser lets it grow past the dialog's max-height instead of scrolling. */
|
|
10421
|
+
.dialog-content {
|
|
10422
|
+
margin-bottom: 20px;
|
|
10423
|
+
flex: 1;
|
|
10424
|
+
overflow-y: auto;
|
|
10425
|
+
min-height: 0;
|
|
10426
|
+
}
|
|
10427
|
+
|
|
10428
|
+
.all-passed {
|
|
10429
|
+
display: flex;
|
|
10430
|
+
flex-direction: column;
|
|
10431
|
+
align-items: center;
|
|
10432
|
+
gap: 12px;
|
|
10433
|
+
padding: 32px 16px;
|
|
10434
|
+
color: var(--jupiter-text-primary, #333);
|
|
10435
|
+
}
|
|
10436
|
+
|
|
10437
|
+
.all-passed-icon {
|
|
10438
|
+
width: 40px;
|
|
10439
|
+
height: 40px;
|
|
10440
|
+
border-radius: 50%;
|
|
10441
|
+
background: var(--jupiter-success-color, #4caf50);
|
|
10442
|
+
color: #fff;
|
|
10443
|
+
display: flex;
|
|
10444
|
+
align-items: center;
|
|
10445
|
+
justify-content: center;
|
|
10446
|
+
font-size: 22px;
|
|
10447
|
+
font-weight: 700;
|
|
10448
|
+
}
|
|
10449
|
+
|
|
10450
|
+
.all-passed-text {
|
|
10451
|
+
font-size: 15px;
|
|
10452
|
+
font-weight: 500;
|
|
9197
10453
|
}
|
|
9198
10454
|
|
|
9199
|
-
.
|
|
9200
|
-
|
|
9201
|
-
|
|
9202
|
-
|
|
10455
|
+
.role-group {
|
|
10456
|
+
border: 1px solid var(--jupiter-border-color, #ddd);
|
|
10457
|
+
border-radius: 4px;
|
|
10458
|
+
margin-bottom: 12px;
|
|
10459
|
+
overflow: hidden;
|
|
9203
10460
|
}
|
|
9204
10461
|
|
|
9205
|
-
.
|
|
10462
|
+
.role-group-header {
|
|
10463
|
+
display: flex;
|
|
10464
|
+
align-items: center;
|
|
10465
|
+
justify-content: space-between;
|
|
10466
|
+
gap: 8px;
|
|
9206
10467
|
padding: 10px 12px;
|
|
9207
|
-
|
|
9208
|
-
border: 1px solid var(--jupiter-border-color, #ddd);
|
|
9209
|
-
border-radius: 4px;
|
|
10468
|
+
background: var(--jupiter-card-background, #fafafa);
|
|
9210
10469
|
cursor: pointer;
|
|
9211
|
-
|
|
9212
|
-
background: var(--jupiter-background, #fff);
|
|
10470
|
+
user-select: none;
|
|
9213
10471
|
}
|
|
9214
10472
|
|
|
9215
|
-
.
|
|
9216
|
-
|
|
9217
|
-
|
|
10473
|
+
.role-group-title {
|
|
10474
|
+
font-weight: 600;
|
|
10475
|
+
font-size: 14px;
|
|
10476
|
+
color: var(--primaryTextColor, var(--jupiter-text-primary, #333));
|
|
9218
10477
|
}
|
|
9219
10478
|
|
|
9220
|
-
.
|
|
9221
|
-
|
|
9222
|
-
color:
|
|
9223
|
-
border-color: var(--jupiter-primary-color, #1976d2);
|
|
10479
|
+
.role-group-count {
|
|
10480
|
+
font-size: 12px;
|
|
10481
|
+
color: var(--jupiter-text-secondary, #666);
|
|
9224
10482
|
}
|
|
9225
10483
|
|
|
9226
|
-
.
|
|
9227
|
-
|
|
9228
|
-
|
|
10484
|
+
.role-group-toggle {
|
|
10485
|
+
background: none;
|
|
10486
|
+
border: none;
|
|
10487
|
+
cursor: pointer;
|
|
10488
|
+
font-size: 12px;
|
|
10489
|
+
color: var(--jupiter-text-secondary, #666);
|
|
10490
|
+
padding: 0 4px;
|
|
9229
10491
|
}
|
|
9230
10492
|
|
|
9231
|
-
.
|
|
9232
|
-
|
|
9233
|
-
margin-top: 3px;
|
|
10493
|
+
.role-group-rows {
|
|
10494
|
+
padding: 4px 12px 8px 12px;
|
|
9234
10495
|
}
|
|
9235
10496
|
|
|
9236
|
-
.
|
|
9237
|
-
|
|
10497
|
+
.assertion-row {
|
|
10498
|
+
display: flex;
|
|
10499
|
+
align-items: flex-start;
|
|
10500
|
+
gap: 8px;
|
|
10501
|
+
padding: 8px 0;
|
|
10502
|
+
border-top: 1px solid var(--jupiter-border-color, #eee);
|
|
9238
10503
|
}
|
|
9239
10504
|
|
|
9240
|
-
.
|
|
9241
|
-
|
|
9242
|
-
font-size: 14px;
|
|
9243
|
-
margin-bottom: 4px;
|
|
10505
|
+
.assertion-row:first-child {
|
|
10506
|
+
border-top: none;
|
|
9244
10507
|
}
|
|
9245
10508
|
|
|
9246
|
-
.
|
|
10509
|
+
.severity-badge {
|
|
10510
|
+
flex-shrink: 0;
|
|
10511
|
+
display: inline-flex;
|
|
10512
|
+
align-items: center;
|
|
10513
|
+
gap: 4px;
|
|
10514
|
+
padding: 2px 8px;
|
|
10515
|
+
border-radius: 10px;
|
|
9247
10516
|
font-size: 11px;
|
|
9248
|
-
|
|
9249
|
-
|
|
9250
|
-
|
|
9251
|
-
|
|
9252
|
-
.picklist-controls {
|
|
9253
|
-
display: flex;
|
|
9254
|
-
flex-direction: column;
|
|
9255
|
-
justify-content: center;
|
|
9256
|
-
gap: 8px;
|
|
9257
|
-
padding: 0 8px;
|
|
10517
|
+
font-weight: 700;
|
|
10518
|
+
color: #fff;
|
|
10519
|
+
white-space: nowrap;
|
|
9258
10520
|
}
|
|
9259
10521
|
|
|
9260
|
-
.
|
|
9261
|
-
background: var(--jupiter-
|
|
9262
|
-
color: white;
|
|
9263
|
-
border: none;
|
|
9264
|
-
padding: 8px 16px;
|
|
9265
|
-
border-radius: 4px;
|
|
9266
|
-
cursor: pointer;
|
|
9267
|
-
font-size: 14px;
|
|
9268
|
-
transition: background-color 0.2s ease;
|
|
10522
|
+
.severity-badge.warning {
|
|
10523
|
+
background: var(--jupiter-warning-color, #ff9800);
|
|
9269
10524
|
}
|
|
9270
10525
|
|
|
9271
|
-
.
|
|
9272
|
-
background: var(--jupiter-
|
|
10526
|
+
.severity-badge.error {
|
|
10527
|
+
background: var(--jupiter-error-color, #d32f2f);
|
|
9273
10528
|
}
|
|
9274
10529
|
|
|
9275
|
-
.
|
|
9276
|
-
|
|
9277
|
-
|
|
10530
|
+
.assertion-message {
|
|
10531
|
+
font-size: 13px;
|
|
10532
|
+
color: var(--primaryTextColor, var(--jupiter-text-primary, #333));
|
|
10533
|
+
line-height: 1.4;
|
|
9278
10534
|
}
|
|
9279
10535
|
|
|
9280
|
-
.
|
|
9281
|
-
|
|
9282
|
-
|
|
9283
|
-
|
|
9284
|
-
|
|
10536
|
+
.dialog-actions {
|
|
10537
|
+
display: flex;
|
|
10538
|
+
gap: 12px;
|
|
10539
|
+
justify-content: flex-end;
|
|
10540
|
+
flex-shrink: 0;
|
|
9285
10541
|
border-top: 1px solid var(--jupiter-border-color, #ddd);
|
|
9286
|
-
|
|
10542
|
+
padding-top: 16px;
|
|
10543
|
+
margin-top: 16px;
|
|
9287
10544
|
}
|
|
9288
10545
|
|
|
9289
|
-
.btn
|
|
9290
|
-
|
|
10546
|
+
.btn {
|
|
10547
|
+
padding: 10px 20px;
|
|
9291
10548
|
border: none;
|
|
9292
|
-
|
|
9293
|
-
padding: 10px 8px;
|
|
10549
|
+
border-radius: 4px;
|
|
9294
10550
|
font-size: 14px;
|
|
9295
10551
|
font-weight: 500;
|
|
9296
|
-
font-family: inherit;
|
|
9297
10552
|
cursor: pointer;
|
|
9298
|
-
margin-right: auto;
|
|
9299
|
-
border-radius: 4px;
|
|
9300
10553
|
transition: background-color 0.2s ease;
|
|
9301
10554
|
}
|
|
9302
10555
|
|
|
9303
|
-
.btn-
|
|
9304
|
-
background: var(--
|
|
10556
|
+
.btn-primary {
|
|
10557
|
+
background: var(--buttonBgColor, var(--jupiter-primary-color, #1976d2));
|
|
10558
|
+
color: var(--buttonTextColor, white);
|
|
10559
|
+
}
|
|
10560
|
+
|
|
10561
|
+
.btn-primary:hover {
|
|
10562
|
+
opacity: 0.9;
|
|
9305
10563
|
}
|
|
9306
10564
|
`;
|
|
9307
|
-
__decorateClass$1([
|
|
9308
|
-
n2({ type: Boolean, reflect: true })
|
|
9309
|
-
], JupiterFilterRolesDialog.prototype, "open", 2);
|
|
9310
|
-
__decorateClass$1([
|
|
9311
|
-
n2({ type: Array })
|
|
9312
|
-
], JupiterFilterRolesDialog.prototype, "availableRoles", 2);
|
|
9313
10565
|
__decorateClass$1([
|
|
9314
10566
|
n2({ type: Array })
|
|
9315
|
-
],
|
|
9316
|
-
__decorateClass$1([
|
|
9317
|
-
n2({ type: Object })
|
|
9318
|
-
], JupiterFilterRolesDialog.prototype, "periodPreferences", 2);
|
|
9319
|
-
__decorateClass$1([
|
|
9320
|
-
n2({ type: String })
|
|
9321
|
-
], JupiterFilterRolesDialog.prototype, "mode", 2);
|
|
10567
|
+
], JupiterFormulaValidationDialog.prototype, "results", 2);
|
|
9322
10568
|
__decorateClass$1([
|
|
9323
10569
|
n2({ type: Object })
|
|
9324
|
-
],
|
|
9325
|
-
__decorateClass$1([
|
|
9326
|
-
n2({ type: Boolean })
|
|
9327
|
-
], JupiterFilterRolesDialog.prototype, "showFactsOnly", 2);
|
|
9328
|
-
__decorateClass$1([
|
|
9329
|
-
n2({ type: String })
|
|
9330
|
-
], JupiterFilterRolesDialog.prototype, "conceptSearchText", 2);
|
|
9331
|
-
__decorateClass$1([
|
|
9332
|
-
r()
|
|
9333
|
-
], JupiterFilterRolesDialog.prototype, "_tempSelectedRoles", 2);
|
|
9334
|
-
__decorateClass$1([
|
|
9335
|
-
r()
|
|
9336
|
-
], JupiterFilterRolesDialog.prototype, "_searchQuery", 2);
|
|
9337
|
-
__decorateClass$1([
|
|
9338
|
-
r()
|
|
9339
|
-
], JupiterFilterRolesDialog.prototype, "_filteredRoles", 2);
|
|
9340
|
-
__decorateClass$1([
|
|
9341
|
-
r()
|
|
9342
|
-
], JupiterFilterRolesDialog.prototype, "_tempPeriodPreferences", 2);
|
|
9343
|
-
__decorateClass$1([
|
|
9344
|
-
r()
|
|
9345
|
-
], JupiterFilterRolesDialog.prototype, "_selectedAvailableRole", 2);
|
|
9346
|
-
__decorateClass$1([
|
|
9347
|
-
r()
|
|
9348
|
-
], JupiterFilterRolesDialog.prototype, "_selectedChosenRole", 2);
|
|
9349
|
-
__decorateClass$1([
|
|
9350
|
-
r()
|
|
9351
|
-
], JupiterFilterRolesDialog.prototype, "_chosenSearchQuery", 2);
|
|
9352
|
-
__decorateClass$1([
|
|
9353
|
-
r()
|
|
9354
|
-
], JupiterFilterRolesDialog.prototype, "_draggedRoleId", 2);
|
|
9355
|
-
__decorateClass$1([
|
|
9356
|
-
r()
|
|
9357
|
-
], JupiterFilterRolesDialog.prototype, "_dragOverRoleId", 2);
|
|
9358
|
-
__decorateClass$1([
|
|
9359
|
-
r()
|
|
9360
|
-
], JupiterFilterRolesDialog.prototype, "_chosenRoleOrder", 2);
|
|
9361
|
-
__decorateClass$1([
|
|
9362
|
-
r()
|
|
9363
|
-
], JupiterFilterRolesDialog.prototype, "_showAdvancedFilter", 2);
|
|
9364
|
-
__decorateClass$1([
|
|
9365
|
-
r()
|
|
9366
|
-
], JupiterFilterRolesDialog.prototype, "_showFactsOnly", 2);
|
|
10570
|
+
], JupiterFormulaValidationDialog.prototype, "summary", 2);
|
|
9367
10571
|
__decorateClass$1([
|
|
9368
|
-
|
|
9369
|
-
],
|
|
10572
|
+
n2({ type: Boolean, reflect: true })
|
|
10573
|
+
], JupiterFormulaValidationDialog.prototype, "open", 2);
|
|
9370
10574
|
__decorateClass$1([
|
|
9371
10575
|
r()
|
|
9372
|
-
],
|
|
9373
|
-
|
|
9374
|
-
t$1("jupiter-
|
|
9375
|
-
],
|
|
10576
|
+
], JupiterFormulaValidationDialog.prototype, "_collapsedGroups", 2);
|
|
10577
|
+
JupiterFormulaValidationDialog = __decorateClass$1([
|
|
10578
|
+
t$1("jupiter-formula-validation-dialog")
|
|
10579
|
+
], JupiterFormulaValidationDialog);
|
|
9376
10580
|
var __defProp = Object.defineProperty;
|
|
9377
10581
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
9378
10582
|
var __decorateClass = (decorators, target, key, kind) => {
|
|
@@ -9392,6 +10596,7 @@ let JupiterDynamicForm = class extends LitElement {
|
|
|
9392
10596
|
this.disabled = false;
|
|
9393
10597
|
this.readonly = false;
|
|
9394
10598
|
this.calculationEnabled = false;
|
|
10599
|
+
this.formulaEnabled = false;
|
|
9395
10600
|
this.periodStartDate = "2025-01-01";
|
|
9396
10601
|
this.periodEndDate = "2025-12-31";
|
|
9397
10602
|
this.language = "en";
|
|
@@ -9411,6 +10616,7 @@ let JupiterDynamicForm = class extends LitElement {
|
|
|
9411
10616
|
this._unitData = {};
|
|
9412
10617
|
this._preservedUnitData = {};
|
|
9413
10618
|
this._decimalsData = {};
|
|
10619
|
+
this._totalManuallyEditedData = {};
|
|
9414
10620
|
this._effectiveMasterData = void 0;
|
|
9415
10621
|
this._typedMemberData = {};
|
|
9416
10622
|
this._preservedTypedMemberData = {};
|
|
@@ -9443,6 +10649,9 @@ let JupiterDynamicForm = class extends LitElement {
|
|
|
9443
10649
|
this._contextMenuY = 0;
|
|
9444
10650
|
this._contextMenuRoleId = null;
|
|
9445
10651
|
this._validationStatus = "idle";
|
|
10652
|
+
this._formulaValidationResults = [];
|
|
10653
|
+
this._showFormulaValidationDialog = false;
|
|
10654
|
+
this._formulaValidationService = new FormulaValidationService();
|
|
9446
10655
|
this._skipDraftLoading = false;
|
|
9447
10656
|
this._skipPeriodPreferencesRestore = false;
|
|
9448
10657
|
this._autoSaveTimer = null;
|
|
@@ -9474,6 +10683,24 @@ let JupiterDynamicForm = class extends LitElement {
|
|
|
9474
10683
|
this.addEventListener("calculation-mismatch-changed", (e2) => {
|
|
9475
10684
|
this._handleCalculationMismatchChanged(e2);
|
|
9476
10685
|
});
|
|
10686
|
+
this.addEventListener("total-manually-edited", (e2) => {
|
|
10687
|
+
const { conceptId, columnId } = e2.detail;
|
|
10688
|
+
const updated = { ...this._totalManuallyEditedData };
|
|
10689
|
+
updated[conceptId] = { ...updated[conceptId], [columnId]: true };
|
|
10690
|
+
this._totalManuallyEditedData = updated;
|
|
10691
|
+
});
|
|
10692
|
+
this.addEventListener("calculation-total-auto-populated", (e2) => {
|
|
10693
|
+
const { conceptId, columnId, value } = e2.detail;
|
|
10694
|
+
const oldValue = this._writeFormDataValue(conceptId, columnId, value);
|
|
10695
|
+
this._touched.add(`${conceptId}-${columnId}`);
|
|
10696
|
+
this._dirty = true;
|
|
10697
|
+
this._validateForm();
|
|
10698
|
+
this.requestUpdate();
|
|
10699
|
+
this.dispatchEvent(new CustomEvent("field-change", {
|
|
10700
|
+
detail: { fieldId: conceptId, conceptId, columnId, value, oldValue, source: "auto-calculated" },
|
|
10701
|
+
bubbles: true
|
|
10702
|
+
}));
|
|
10703
|
+
});
|
|
9477
10704
|
document.addEventListener("click", () => {
|
|
9478
10705
|
if (this._showRoleContextMenu) {
|
|
9479
10706
|
this._showRoleContextMenu = false;
|
|
@@ -10148,6 +11375,12 @@ let JupiterDynamicForm = class extends LitElement {
|
|
|
10148
11375
|
const roleCount = this._getRoleIdsArray().length;
|
|
10149
11376
|
console.log(`🚫 Filter dialog cancelled. Current selection: ${roleCount}/${this._allSections.length}`);
|
|
10150
11377
|
}
|
|
11378
|
+
// JDF-050: closes the formula-validation results dialog opened by JDF-049's pre-flight.
|
|
11379
|
+
// Purely a visibility toggle — submit already proceeded on the click that opened it
|
|
11380
|
+
// (non-blocking, per the corrected JDF-043 Q4 decision), so there is nothing to resume here.
|
|
11381
|
+
_handleFormulaValidationDialogCancel() {
|
|
11382
|
+
this._showFormulaValidationDialog = false;
|
|
11383
|
+
}
|
|
10151
11384
|
_handleRoleFilterApply(event) {
|
|
10152
11385
|
var _a, _b;
|
|
10153
11386
|
const { selectedRoleIds, periodPreferences } = event.detail;
|
|
@@ -10175,7 +11408,8 @@ let JupiterDynamicForm = class extends LitElement {
|
|
|
10175
11408
|
this._repeatCounts,
|
|
10176
11409
|
this._decimalsData,
|
|
10177
11410
|
void 0,
|
|
10178
|
-
this._getHiddenColumnsForMetadata()
|
|
11411
|
+
this._getHiddenColumnsForMetadata(),
|
|
11412
|
+
this._totalManuallyEditedData
|
|
10179
11413
|
);
|
|
10180
11414
|
this._draftStorageService.saveDraft(currentFormData, currentMetadata);
|
|
10181
11415
|
console.log("✅ Current form data saved to draft storage with NEW preferences");
|
|
@@ -10284,9 +11518,13 @@ let JupiterDynamicForm = class extends LitElement {
|
|
|
10284
11518
|
this._calculationWarnings = next;
|
|
10285
11519
|
this._validateForm();
|
|
10286
11520
|
}
|
|
10287
|
-
|
|
10288
|
-
|
|
10289
|
-
|
|
11521
|
+
/**
|
|
11522
|
+
* JDF-058: single source of truth for writing a value into `_formData` with the immutable-update
|
|
11523
|
+
* pattern Lit reactivity needs — shared by a real user keystroke (`_handleFieldChange`) and the
|
|
11524
|
+
* auto-populate-totals `calculation-total-auto-populated` handler, so the update logic isn't
|
|
11525
|
+
* duplicated. Returns the value that was previously stored, for event `oldValue` fields.
|
|
11526
|
+
*/
|
|
11527
|
+
_writeFormDataValue(conceptId, columnId, value) {
|
|
10290
11528
|
const updatedFormData = { ...this._formData };
|
|
10291
11529
|
if (!updatedFormData[conceptId]) {
|
|
10292
11530
|
updatedFormData[conceptId] = {};
|
|
@@ -10294,6 +11532,12 @@ let JupiterDynamicForm = class extends LitElement {
|
|
|
10294
11532
|
const oldValue = updatedFormData[conceptId][columnId];
|
|
10295
11533
|
updatedFormData[conceptId] = { ...updatedFormData[conceptId], [columnId]: value };
|
|
10296
11534
|
this._formData = updatedFormData;
|
|
11535
|
+
return oldValue;
|
|
11536
|
+
}
|
|
11537
|
+
_handleFieldChange(event) {
|
|
11538
|
+
const { fieldId, conceptId, columnId, value } = event.detail;
|
|
11539
|
+
console.log(`📝 Field change: conceptId=${conceptId}, columnId=${columnId}, value=${value}, fieldId=${fieldId}`);
|
|
11540
|
+
const oldValue = this._writeFormDataValue(conceptId, columnId, value);
|
|
10297
11541
|
console.log(`💾 Updated formData[${conceptId}]:`, this._formData[conceptId]);
|
|
10298
11542
|
this._touched.add(`${conceptId}-${columnId}`);
|
|
10299
11543
|
this._dirty = true;
|
|
@@ -11275,6 +12519,7 @@ let JupiterDynamicForm = class extends LitElement {
|
|
|
11275
12519
|
return;
|
|
11276
12520
|
}
|
|
11277
12521
|
this._correctLegacyPeriodStartInstantDates();
|
|
12522
|
+
this._runFormulaValidationPreflight();
|
|
11278
12523
|
const submissionData = this._generateSubmissionData();
|
|
11279
12524
|
console.log("📊 Form Submission Data:", JSON.stringify(submissionData, null, 2));
|
|
11280
12525
|
console.log("📊 Submission Data Summary:");
|
|
@@ -11296,6 +12541,58 @@ let JupiterDynamicForm = class extends LitElement {
|
|
|
11296
12541
|
this._submitDisabled = false;
|
|
11297
12542
|
}, 1e3);
|
|
11298
12543
|
}
|
|
12544
|
+
/**
|
|
12545
|
+
* JDF-049: runs FormulaValidationService against the live form state and stores the results
|
|
12546
|
+
* for the results dialog (JDF-050). Graceful no-op — per JDF-048's gating and this ticket's
|
|
12547
|
+
* "no Validate-formulas affordance/effect when formula data is absent" requirement — when
|
|
12548
|
+
* `formulaEnabled` is off or `xbrlInput.formula` has no roles. Never blocks the caller; always
|
|
12549
|
+
* returns before any resolution work is attempted when gated off (JDF-048's "zero evaluation
|
|
12550
|
+
* cost when off" requirement).
|
|
12551
|
+
*/
|
|
12552
|
+
_runFormulaValidationPreflight() {
|
|
12553
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
12554
|
+
if (!this.formulaEnabled)
|
|
12555
|
+
return;
|
|
12556
|
+
const formulaRoles = (_c = (_b = (_a = this.xbrlInput) == null ? void 0 : _a.formula) == null ? void 0 : _b[0]) == null ? void 0 : _c.roles;
|
|
12557
|
+
if (!formulaRoles || formulaRoles.length === 0)
|
|
12558
|
+
return;
|
|
12559
|
+
const ctx = buildFormulaResolutionContext(
|
|
12560
|
+
this._formData,
|
|
12561
|
+
this._mergeAllSectionColumns(),
|
|
12562
|
+
((_f = (_e = (_d = this.xbrlInput) == null ? void 0 : _d.presentation) == null ? void 0 : _e[0]) == null ? void 0 : _f.roles) || [],
|
|
12563
|
+
(_i = (_h = (_g = this.xbrlInput) == null ? void 0 : _g.hypercubes) == null ? void 0 : _h[0]) == null ? void 0 : _i.roles,
|
|
12564
|
+
this.periodStartDate,
|
|
12565
|
+
this.periodEndDate
|
|
12566
|
+
);
|
|
12567
|
+
const results = this._formulaValidationService.evaluate(this.xbrlInput, ctx, this.language);
|
|
12568
|
+
const summary = this._formulaValidationService.summarize(results);
|
|
12569
|
+
this._formulaValidationResults = results;
|
|
12570
|
+
this._formulaValidationSummary = summary;
|
|
12571
|
+
const hasFailures = results.some((result) => !result.skipped && !result.satisfied);
|
|
12572
|
+
if (hasFailures) {
|
|
12573
|
+
this._showFormulaValidationDialog = true;
|
|
12574
|
+
}
|
|
12575
|
+
this.dispatchEvent(new CustomEvent("formula-validation-complete", {
|
|
12576
|
+
detail: { results, summary },
|
|
12577
|
+
bubbles: true,
|
|
12578
|
+
composed: true
|
|
12579
|
+
}));
|
|
12580
|
+
}
|
|
12581
|
+
/**
|
|
12582
|
+
* Formula assertions can reference concepts/dimensions from any disclosure role, but
|
|
12583
|
+
* `FormColumn`s (especially dimension columns) are tracked per-section (`section.columns`),
|
|
12584
|
+
* with `this._columns` as the shared/default fallback (see the pattern at L1398/L2814/L5284).
|
|
12585
|
+
* `_formData` itself is already global (keyed by conceptId/columnId, no section nesting), so a
|
|
12586
|
+
* single merged, deduplicated-by-id column list is the correct match for it.
|
|
12587
|
+
*/
|
|
12588
|
+
_mergeAllSectionColumns() {
|
|
12589
|
+
const merged = /* @__PURE__ */ new Map();
|
|
12590
|
+
this._columns.forEach((column2) => merged.set(column2.id, column2));
|
|
12591
|
+
this._allSections.forEach((section2) => {
|
|
12592
|
+
(section2.columns || []).forEach((column2) => merged.set(column2.id, column2));
|
|
12593
|
+
});
|
|
12594
|
+
return Array.from(merged.values());
|
|
12595
|
+
}
|
|
11299
12596
|
_handleSaveDraft(source = "manual") {
|
|
11300
12597
|
console.log(`🔵 [Save Draft] Checking for errors...`);
|
|
11301
12598
|
console.log(`🔵 [Save Draft] _xbrlFormErrors.length: ${this._xbrlFormErrors.length}`);
|
|
@@ -11333,7 +12630,8 @@ let JupiterDynamicForm = class extends LitElement {
|
|
|
11333
12630
|
this._repeatCounts,
|
|
11334
12631
|
this._decimalsData,
|
|
11335
12632
|
roleCompletedStates,
|
|
11336
|
-
this._getHiddenColumnsForMetadata()
|
|
12633
|
+
this._getHiddenColumnsForMetadata(),
|
|
12634
|
+
this._totalManuallyEditedData
|
|
11337
12635
|
);
|
|
11338
12636
|
const draftPayloadSnapshot = JSON.stringify({
|
|
11339
12637
|
draftData,
|
|
@@ -11475,6 +12773,10 @@ let JupiterDynamicForm = class extends LitElement {
|
|
|
11475
12773
|
);
|
|
11476
12774
|
console.log("🔄 Restored hidden columns for", this._hiddenColumnIds.size, "sections");
|
|
11477
12775
|
}
|
|
12776
|
+
if (metadata.totalManuallyEditedData) {
|
|
12777
|
+
this._totalManuallyEditedData = metadata.totalManuallyEditedData;
|
|
12778
|
+
console.log("🔄 Restored total manually-edited data:", Object.keys(this._totalManuallyEditedData).length, "concepts");
|
|
12779
|
+
}
|
|
11478
12780
|
if (metadata.periodPreferences) {
|
|
11479
12781
|
if (this._skipPeriodPreferencesRestore) {
|
|
11480
12782
|
console.log("⏭️ Skipping period preferences restoration - using new filter selections");
|
|
@@ -11554,6 +12856,7 @@ let JupiterDynamicForm = class extends LitElement {
|
|
|
11554
12856
|
});
|
|
11555
12857
|
this._formData = { ...this._formData, ...restoredFormData };
|
|
11556
12858
|
console.log(`🔄 Restored ${Object.keys(restoredFormData).length} concepts with data`);
|
|
12859
|
+
this._seedLegacyManuallyEditedTotals(restoredFormData);
|
|
11557
12860
|
this._initializeGlobalDecimalsFromRoundingData();
|
|
11558
12861
|
this._periodData = {
|
|
11559
12862
|
...this._periodData,
|
|
@@ -11687,6 +12990,47 @@ let JupiterDynamicForm = class extends LitElement {
|
|
|
11687
12990
|
});
|
|
11688
12991
|
console.log(`✅ Field population complete: ${populatedCount} populated, ${notFoundCount} not found`);
|
|
11689
12992
|
}
|
|
12993
|
+
/**
|
|
12994
|
+
* JDF-058: seed the manual-edit dirty flag for any total whose value predates this feature, so
|
|
12995
|
+
* upgrading never silently recomputes a customer's pre-existing, already-filed totals. Walks
|
|
12996
|
+
* `_allSections` (the full pool, including currently-hidden/filtered-out sections — a hidden
|
|
12997
|
+
* total's pre-existing value must stay protected the moment its section becomes visible again),
|
|
12998
|
+
* not just the currently-selected roles. Idempotent: only seeds a cell that has no explicit
|
|
12999
|
+
* `totalManuallyEditedData` entry already (i.e. `metadata.totalManuallyEditedData` didn't cover
|
|
13000
|
+
* it), so re-running on an already-seeded draft is a no-op. Does not touch `restoredFormData`.
|
|
13001
|
+
*/
|
|
13002
|
+
_seedLegacyManuallyEditedTotals(restoredFormData) {
|
|
13003
|
+
const seeded = { ...this._totalManuallyEditedData };
|
|
13004
|
+
let changed = false;
|
|
13005
|
+
const walk = (concepts) => {
|
|
13006
|
+
var _a;
|
|
13007
|
+
for (const concept of concepts) {
|
|
13008
|
+
if (isTotalLabel$1(concept.preferredLabel)) {
|
|
13009
|
+
const values = restoredFormData[concept.id];
|
|
13010
|
+
if (values) {
|
|
13011
|
+
for (const columnId of Object.keys(values)) {
|
|
13012
|
+
const value = values[columnId];
|
|
13013
|
+
const isBlank = value === null || value === void 0 || value === "";
|
|
13014
|
+
if (!isBlank && ((_a = seeded[concept.id]) == null ? void 0 : _a[columnId]) === void 0) {
|
|
13015
|
+
seeded[concept.id] = { ...seeded[concept.id] || {}, [columnId]: true };
|
|
13016
|
+
changed = true;
|
|
13017
|
+
}
|
|
13018
|
+
}
|
|
13019
|
+
}
|
|
13020
|
+
}
|
|
13021
|
+
if (concept.children && concept.children.length > 0) {
|
|
13022
|
+
walk(concept.children);
|
|
13023
|
+
}
|
|
13024
|
+
}
|
|
13025
|
+
};
|
|
13026
|
+
for (const section2 of this._allSections) {
|
|
13027
|
+
walk(section2.concepts || []);
|
|
13028
|
+
}
|
|
13029
|
+
if (changed) {
|
|
13030
|
+
this._totalManuallyEditedData = seeded;
|
|
13031
|
+
console.log("🔒 [JDF-058] Seeded manual-edit protection for pre-existing total values in legacy draft");
|
|
13032
|
+
}
|
|
13033
|
+
}
|
|
11690
13034
|
_restoreCustomColumns(customColumns) {
|
|
11691
13035
|
const columnsBySection = /* @__PURE__ */ new Map();
|
|
11692
13036
|
customColumns.forEach((col) => {
|
|
@@ -13136,6 +14480,7 @@ let JupiterDynamicForm = class extends LitElement {
|
|
|
13136
14480
|
.periodStartDate="${this.periodStartDate}"
|
|
13137
14481
|
.periodEndDate="${this.periodEndDate}"
|
|
13138
14482
|
.calculationEnabled="${this.calculationEnabled}"
|
|
14483
|
+
.totalManuallyEditedData="${this._totalManuallyEditedData}"
|
|
13139
14484
|
@field-change="${this._handleFieldChange}"
|
|
13140
14485
|
@period-change="${this._handlePeriodChange}"
|
|
13141
14486
|
@typed-member-change="${this._handleTypedMemberChange}"
|
|
@@ -13284,6 +14629,7 @@ let JupiterDynamicForm = class extends LitElement {
|
|
|
13284
14629
|
.periodStartDate="${this.periodStartDate}"
|
|
13285
14630
|
.periodEndDate="${this.periodEndDate}"
|
|
13286
14631
|
.calculationEnabled="${this.calculationEnabled}"
|
|
14632
|
+
.totalManuallyEditedData="${this._totalManuallyEditedData}"
|
|
13287
14633
|
@field-change="${this._handleFieldChange}"
|
|
13288
14634
|
@typed-member-change="${this._handleTypedMemberChange}"
|
|
13289
14635
|
@add-concept-repeat="${this._handleAddConceptRepeat}"
|
|
@@ -13706,7 +15052,18 @@ let JupiterDynamicForm = class extends LitElement {
|
|
|
13706
15052
|
@click="${this._handleFilterDialogCancel}"
|
|
13707
15053
|
></jupiter-filter-roles-dialog>
|
|
13708
15054
|
` : ""}
|
|
13709
|
-
|
|
15055
|
+
|
|
15056
|
+
<!-- Formula Validation Results Dialog (JDF-050) -->
|
|
15057
|
+
${this._showFormulaValidationDialog ? html`
|
|
15058
|
+
<jupiter-formula-validation-dialog
|
|
15059
|
+
?open="${this._showFormulaValidationDialog}"
|
|
15060
|
+
.results="${this._formulaValidationResults}"
|
|
15061
|
+
.summary="${this._formulaValidationSummary}"
|
|
15062
|
+
@dialog-cancel="${this._handleFormulaValidationDialogCancel}"
|
|
15063
|
+
@click="${this._handleFormulaValidationDialogCancel}"
|
|
15064
|
+
></jupiter-formula-validation-dialog>
|
|
15065
|
+
` : ""}
|
|
15066
|
+
|
|
13710
15067
|
<!-- Validation Error Popup -->
|
|
13711
15068
|
${this._showErrorPopup ? html`
|
|
13712
15069
|
<div class="error-popup-overlay" @click="${() => {
|
|
@@ -14623,6 +15980,9 @@ __decorateClass([
|
|
|
14623
15980
|
__decorateClass([
|
|
14624
15981
|
n2({ type: Boolean, attribute: "calculation-enabled" })
|
|
14625
15982
|
], JupiterDynamicForm.prototype, "calculationEnabled", 2);
|
|
15983
|
+
__decorateClass([
|
|
15984
|
+
n2({ type: Boolean, attribute: "formula-enabled" })
|
|
15985
|
+
], JupiterDynamicForm.prototype, "formulaEnabled", 2);
|
|
14626
15986
|
__decorateClass([
|
|
14627
15987
|
n2({ type: String })
|
|
14628
15988
|
], JupiterDynamicForm.prototype, "periodStartDate", 2);
|
|
@@ -14695,6 +16055,9 @@ __decorateClass([
|
|
|
14695
16055
|
__decorateClass([
|
|
14696
16056
|
r()
|
|
14697
16057
|
], JupiterDynamicForm.prototype, "_decimalsData", 2);
|
|
16058
|
+
__decorateClass([
|
|
16059
|
+
r()
|
|
16060
|
+
], JupiterDynamicForm.prototype, "_totalManuallyEditedData", 2);
|
|
14698
16061
|
__decorateClass([
|
|
14699
16062
|
r()
|
|
14700
16063
|
], JupiterDynamicForm.prototype, "_effectiveMasterData", 2);
|
|
@@ -14794,6 +16157,15 @@ __decorateClass([
|
|
|
14794
16157
|
__decorateClass([
|
|
14795
16158
|
r()
|
|
14796
16159
|
], JupiterDynamicForm.prototype, "_validationStatus", 2);
|
|
16160
|
+
__decorateClass([
|
|
16161
|
+
r()
|
|
16162
|
+
], JupiterDynamicForm.prototype, "_formulaValidationResults", 2);
|
|
16163
|
+
__decorateClass([
|
|
16164
|
+
r()
|
|
16165
|
+
], JupiterDynamicForm.prototype, "_formulaValidationSummary", 2);
|
|
16166
|
+
__decorateClass([
|
|
16167
|
+
r()
|
|
16168
|
+
], JupiterDynamicForm.prototype, "_showFormulaValidationDialog", 2);
|
|
14797
16169
|
JupiterDynamicForm = __decorateClass([
|
|
14798
16170
|
t$1("jupiter-dynamic-form")
|
|
14799
16171
|
], JupiterDynamicForm);
|
|
@@ -14808,6 +16180,7 @@ export {
|
|
|
14808
16180
|
JupiterFilterRolesDialog,
|
|
14809
16181
|
JupiterFormField,
|
|
14810
16182
|
JupiterFormSection,
|
|
16183
|
+
JupiterFormulaValidationDialog,
|
|
14811
16184
|
TYPE_INPUT_MAP,
|
|
14812
16185
|
XBRLValidator,
|
|
14813
16186
|
collectEnumerationsFromChain,
|