jupiter-dynamic-forms 1.17.7 → 1.17.8

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/index.mjs CHANGED
@@ -569,6 +569,14 @@ class XBRLFormBuilder {
569
569
  }
570
570
  return Math.abs(hash).toString(36).substr(0, 6);
571
571
  }
572
+ static _extractDocumentationLabels(labels) {
573
+ const result = {};
574
+ const docRole = "http://www.xbrl.org/2003/role/documentation";
575
+ labels.filter((l2) => l2.role === docRole).forEach((l2) => {
576
+ result[l2.lang] = l2.label;
577
+ });
578
+ return result;
579
+ }
572
580
  /**
573
581
  * Build form schema from XBRL input data
574
582
  * Creates accordion sections for each presentation role
@@ -707,6 +715,14 @@ class XBRLFormBuilder {
707
715
  conceptId = `${conceptId}__occ${count + 1}`;
708
716
  }
709
717
  }
718
+ const conceptMetadata = {
719
+ conceptName: concept.conceptName,
720
+ type: concept.type,
721
+ substitutionGroup: concept.substitutionGroup,
722
+ periodType: concept.periodType,
723
+ balance: concept.balance,
724
+ documentationLabels: this._extractDocumentationLabels(concept.labels)
725
+ };
710
726
  return {
711
727
  id: conceptId,
712
728
  originalConceptId: concept.id,
@@ -719,6 +735,7 @@ class XBRLFormBuilder {
719
735
  level,
720
736
  children,
721
737
  fields,
738
+ conceptMetadata,
722
739
  facts: concept.facts || [],
723
740
  // Pass facts array from presentation concept for pre-population
724
741
  collapsed: level > 0,
@@ -1605,6 +1622,18 @@ class XBRLFormBuilder {
1605
1622
  }];
1606
1623
  }
1607
1624
  }
1625
+ const conceptInfo$1 = {
1626
+ title: "Concept Information",
1627
+ conceptName: "Concept name",
1628
+ type: "Type",
1629
+ substitutionGroup: "Substitution group",
1630
+ periodType: "Period type",
1631
+ balance: "Balance",
1632
+ documentation: "Documentation",
1633
+ instant: "Instant",
1634
+ duration: "Duration",
1635
+ close: "Close"
1636
+ };
1608
1637
  const form$1 = {
1609
1638
  loading: "Loading form...",
1610
1639
  submit: "Validate",
@@ -1749,6 +1778,7 @@ const error$1 = {
1749
1778
  }
1750
1779
  };
1751
1780
  const enTranslations = {
1781
+ conceptInfo: conceptInfo$1,
1752
1782
  form: form$1,
1753
1783
  filter: filter$1,
1754
1784
  column: column$1,
@@ -1759,6 +1789,18 @@ const enTranslations = {
1759
1789
  xbrlValidation: xbrlValidation$1,
1760
1790
  error: error$1
1761
1791
  };
1792
+ const conceptInfo = {
1793
+ title: "Conceptinformatie",
1794
+ conceptName: "Conceptnaam",
1795
+ type: "Type",
1796
+ substitutionGroup: "Substitutiegroep",
1797
+ periodType: "Periodetype",
1798
+ balance: "Saldo",
1799
+ documentation: "Documentatie",
1800
+ instant: "Moment",
1801
+ duration: "Periode",
1802
+ close: "Sluiten"
1803
+ };
1762
1804
  const form = {
1763
1805
  loading: "Formulier laden...",
1764
1806
  submit: "Valideren",
@@ -1903,6 +1945,7 @@ const error = {
1903
1945
  }
1904
1946
  };
1905
1947
  const nlTranslations = {
1948
+ conceptInfo,
1906
1949
  form,
1907
1950
  filter,
1908
1951
  column,
@@ -4304,6 +4347,7 @@ let JupiterConceptTree = class extends LitElement {
4304
4347
  this.typedMemberData = {};
4305
4348
  this.showAddButton = false;
4306
4349
  this.showRemoveButton = false;
4350
+ this.language = "en";
4307
4351
  this._expanded = true;
4308
4352
  }
4309
4353
  connectedCallback() {
@@ -4373,6 +4417,108 @@ let JupiterConceptTree = class extends LitElement {
4373
4417
  }));
4374
4418
  console.log(`🌲 [ConceptTree] Forwarded period-change event to form-section`);
4375
4419
  }
4420
+ _getDocLabel() {
4421
+ const meta = this.concept.conceptMetadata;
4422
+ if (!meta)
4423
+ return "";
4424
+ const lang = this.language || this.locale.split("-")[0];
4425
+ return meta.documentationLabels[lang] || meta.documentationLabels["en"] || meta.documentationLabels["nl"] || "";
4426
+ }
4427
+ _escapeHtml(str) {
4428
+ return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
4429
+ }
4430
+ _ensureDialogStyles() {
4431
+ if (document.getElementById("jdf-concept-info-dialog-styles"))
4432
+ return;
4433
+ const style = document.createElement("style");
4434
+ style.id = "jdf-concept-info-dialog-styles";
4435
+ style.textContent = `
4436
+ dialog.jdf-concept-info-dialog {
4437
+ border: none; border-radius: 8px; padding: 0;
4438
+ max-width: 480px; width: 90vw;
4439
+ box-shadow: 0 8px 32px rgba(0,0,0,0.2); overflow: hidden;
4440
+ }
4441
+ dialog.jdf-concept-info-dialog::backdrop { background: rgba(0,0,0,0.35); }
4442
+ .jdf-dialog-header {
4443
+ background: #f0f2f5; padding: 14px 20px;
4444
+ display: flex; align-items: center; justify-content: space-between;
4445
+ border-bottom: 1px solid #ddd;
4446
+ }
4447
+ .jdf-dialog-title { font-size: 15px; font-weight: 600; color: #333; margin: 0; font-family: inherit; }
4448
+ .jdf-dialog-close-btn {
4449
+ width: 28px; height: 28px; border: none; background: transparent;
4450
+ font-size: 20px; line-height: 1; cursor: pointer; color: #666;
4451
+ border-radius: 4px; display: flex; align-items: center; justify-content: center;
4452
+ padding: 0; font-family: inherit;
4453
+ }
4454
+ .jdf-dialog-close-btn:hover { background: #ddd; color: #333; }
4455
+ .jdf-dialog-body { padding: 20px; }
4456
+ .jdf-info-table { width: 100%; border-collapse: collapse; font-size: 14px; font-family: inherit; }
4457
+ .jdf-info-table tr:not(:last-child) td { border-bottom: 1px solid #f0f0f0; }
4458
+ .jdf-info-table td { padding: 9px 4px; vertical-align: top; }
4459
+ .jdf-info-label { font-weight: 600; color: #666; width: 40%; white-space: nowrap; padding-right: 16px; }
4460
+ .jdf-info-value { color: #333; word-break: break-all; }
4461
+ .jdf-info-value.doc-text { font-style: italic; color: #555; line-height: 1.5; word-break: normal; }
4462
+ .jdf-period-pill { display: inline-block; padding: 2px 8px; border-radius: 10px; font-size: 12px; font-weight: 600; }
4463
+ .jdf-period-pill.instant { background: rgba(25,118,210,0.1); color: #1565c0; border: 1px solid rgba(25,118,210,0.3); }
4464
+ .jdf-period-pill.duration { background: rgba(56,142,60,0.1); color: #2e7d32; border: 1px solid rgba(56,142,60,0.3); }
4465
+ .jdf-balance-pill { display: inline-block; padding: 2px 8px; border-radius: 10px; font-size: 12px; font-weight: 600; text-transform: capitalize; }
4466
+ .jdf-balance-pill.debit { background: rgba(211,47,47,0.1); color: #c62828; border: 1px solid rgba(211,47,47,0.3); }
4467
+ .jdf-balance-pill.credit { background: rgba(56,142,60,0.1); color: #2e7d32; border: 1px solid rgba(56,142,60,0.3); }
4468
+ `;
4469
+ document.head.appendChild(style);
4470
+ }
4471
+ _openInfoDialog(e2) {
4472
+ var _a;
4473
+ e2.stopPropagation();
4474
+ this._ensureDialogStyles();
4475
+ const meta = this.concept.conceptMetadata;
4476
+ const docLabel = this._getDocLabel();
4477
+ const periodType = (meta == null ? void 0 : meta.periodType) || this.concept.periodType;
4478
+ const balance = (meta == null ? void 0 : meta.balance) || this.concept.balance;
4479
+ const periodLabel = periodType === "instant" ? I18n.t("conceptInfo.instant") : I18n.t("conceptInfo.duration");
4480
+ const rows = [
4481
+ { label: I18n.t("conceptInfo.conceptName"), valueHtml: this._escapeHtml((meta == null ? void 0 : meta.conceptName) || this.concept.name) },
4482
+ { label: I18n.t("conceptInfo.type"), valueHtml: this._escapeHtml((meta == null ? void 0 : meta.type) || this.concept.type || "—") }
4483
+ ];
4484
+ if (meta == null ? void 0 : meta.substitutionGroup) {
4485
+ rows.push({ label: I18n.t("conceptInfo.substitutionGroup"), valueHtml: this._escapeHtml(meta.substitutionGroup) });
4486
+ }
4487
+ rows.push({ label: I18n.t("conceptInfo.periodType"), valueHtml: `<span class="jdf-period-pill ${periodType}">${this._escapeHtml(periodLabel)}</span>` });
4488
+ if (balance) {
4489
+ rows.push({ label: I18n.t("conceptInfo.balance"), valueHtml: `<span class="jdf-balance-pill ${balance}">${this._escapeHtml(balance)}</span>` });
4490
+ }
4491
+ if (docLabel) {
4492
+ rows.push({ label: I18n.t("conceptInfo.documentation"), valueHtml: this._escapeHtml(docLabel), isDoc: true });
4493
+ }
4494
+ const rowsHtml = rows.map((r2) => `
4495
+ <tr>
4496
+ <td class="jdf-info-label">${this._escapeHtml(r2.label)}</td>
4497
+ <td class="jdf-info-value${r2.isDoc ? " doc-text" : ""}">${r2.valueHtml}</td>
4498
+ </tr>
4499
+ `).join("");
4500
+ const dialog = document.createElement("dialog");
4501
+ dialog.className = "jdf-concept-info-dialog";
4502
+ dialog.innerHTML = `
4503
+ <div class="jdf-dialog-header">
4504
+ <h3 class="jdf-dialog-title">${this._escapeHtml(I18n.t("conceptInfo.title"))}</h3>
4505
+ <button class="jdf-dialog-close-btn" type="button" aria-label="${this._escapeHtml(I18n.t("conceptInfo.close"))}">×</button>
4506
+ </div>
4507
+ <div class="jdf-dialog-body">
4508
+ <table class="jdf-info-table">${rowsHtml}</table>
4509
+ </div>
4510
+ `;
4511
+ document.body.appendChild(dialog);
4512
+ (_a = dialog.querySelector(".jdf-dialog-close-btn")) == null ? void 0 : _a.addEventListener("click", () => dialog.close());
4513
+ dialog.addEventListener("click", (ev) => {
4514
+ const rect = dialog.getBoundingClientRect();
4515
+ if (ev.clientX < rect.left || ev.clientX > rect.right || ev.clientY < rect.top || ev.clientY > rect.bottom) {
4516
+ dialog.close();
4517
+ }
4518
+ });
4519
+ dialog.addEventListener("close", () => document.body.removeChild(dialog));
4520
+ dialog.showModal();
4521
+ }
4376
4522
  render() {
4377
4523
  const hasChildren = this.concept.children && this.concept.children.length > 0;
4378
4524
  const level = this.concept.level || 0;
@@ -4394,6 +4540,8 @@ let JupiterConceptTree = class extends LitElement {
4394
4540
  ${this.concept.balance ? html`
4395
4541
  <div class="concept-balance ${this.concept.balance}">${this.concept.balance}</div>
4396
4542
  ` : ""}
4543
+ <button class="concept-info-btn" type="button" title="${I18n.t("conceptInfo.title")}"
4544
+ @click="${this._openInfoDialog}">ℹ</button>
4397
4545
  ${this.showAddButton ? html`
4398
4546
  <button class="repeat-btn" type="button" title="Add row"
4399
4547
  @click="${this._handleAddRepeat}">+</button>
@@ -4445,6 +4593,7 @@ let JupiterConceptTree = class extends LitElement {
4445
4593
  </td>
4446
4594
  `;
4447
4595
  })}
4596
+
4448
4597
  `;
4449
4598
  }
4450
4599
  };
@@ -4618,6 +4767,36 @@ JupiterConceptTree.styles = css`
4618
4767
  box-shadow: inset 0 0 0 2px var(--jupiter-error-color, #d32f2f);
4619
4768
  }
4620
4769
 
4770
+ .concept-info-btn {
4771
+ flex-shrink: 0;
4772
+ width: 18px;
4773
+ height: 18px;
4774
+ border-radius: 50%;
4775
+ border: 1px solid transparent;
4776
+ background: transparent;
4777
+ color: var(--jupiter-text-secondary, #888);
4778
+ font-size: 12px;
4779
+ cursor: pointer;
4780
+ display: flex;
4781
+ align-items: center;
4782
+ justify-content: center;
4783
+ opacity: 0;
4784
+ transition: opacity 0.15s, background 0.15s, color 0.15s;
4785
+ padding: 0;
4786
+ margin-left: 4px;
4787
+ line-height: 1;
4788
+ }
4789
+
4790
+ .concept-content:hover .concept-info-btn {
4791
+ opacity: 1;
4792
+ }
4793
+
4794
+ .concept-info-btn:hover {
4795
+ background: var(--jupiter-primary-color, #1976d2);
4796
+ color: #fff;
4797
+ border-color: var(--jupiter-primary-color, #1976d2);
4798
+ }
4799
+
4621
4800
  `;
4622
4801
  __decorateClass$5([
4623
4802
  n2({ type: Object })
@@ -4682,6 +4861,9 @@ __decorateClass$5([
4682
4861
  __decorateClass$5([
4683
4862
  n2({ type: Object })
4684
4863
  ], JupiterConceptTree.prototype, "calculationErrorKeys", 2);
4864
+ __decorateClass$5([
4865
+ n2({ type: String })
4866
+ ], JupiterConceptTree.prototype, "language", 2);
4685
4867
  __decorateClass$5([
4686
4868
  r()
4687
4869
  ], JupiterConceptTree.prototype, "_expanded", 2);
@@ -5351,6 +5533,7 @@ let JupiterFormSection = class extends LitElement {
5351
5533
  this.showFactsOnly = false;
5352
5534
  this.periodStartDate = "";
5353
5535
  this.periodEndDate = "";
5536
+ this.language = "en";
5354
5537
  this._expanded = true;
5355
5538
  this._showAddColumnDialog = false;
5356
5539
  this._sectionPeriodType = "duration";
@@ -5778,6 +5961,7 @@ let JupiterFormSection = class extends LitElement {
5778
5961
  .defaultUnits="${this.defaultUnits}"
5779
5962
  .disabled="${this.disabled}"
5780
5963
  .locale="${this.locale}"
5964
+ .language="${this.language}"
5781
5965
  .expandedConcepts="${this._expandedConcepts}"
5782
5966
  .mode="${this.mode}"
5783
5967
  .masterData="${this.masterData}"
@@ -6295,6 +6479,9 @@ __decorateClass$3([
6295
6479
  __decorateClass$3([
6296
6480
  n2({ type: String })
6297
6481
  ], JupiterFormSection.prototype, "periodEndDate", 2);
6482
+ __decorateClass$3([
6483
+ n2({ type: String })
6484
+ ], JupiterFormSection.prototype, "language", 2);
6298
6485
  __decorateClass$3([
6299
6486
  r()
6300
6487
  ], JupiterFormSection.prototype, "_expanded", 2);
@@ -11721,6 +11908,7 @@ let JupiterDynamicForm = class extends LitElement {
11721
11908
  .disabled="${this.disabled || this.readonly}"
11722
11909
  .collapsible="${config.collapsibleSections !== false}"
11723
11910
  .locale="${config.locale || "en-US"}"
11911
+ .language="${this.language}"
11724
11912
  .isFirstSection="${index === 0}"
11725
11913
  .availableDimensions="${this._getAvailableDimensionsForSection(section2.id)}"
11726
11914
  .mode="${this.mode}"
@@ -11865,6 +12053,7 @@ let JupiterDynamicForm = class extends LitElement {
11865
12053
  .collapsible="${false}"
11866
12054
  .hideHeader="${true}"
11867
12055
  .locale="${config.locale || "en-US"}"
12056
+ .language="${this.language}"
11868
12057
  .isFirstSection="${true}"
11869
12058
  .availableDimensions="${this._getAvailableDimensionsForSection(activeSection.id)}"
11870
12059
  .mode="${this.mode}"