jupiter-dynamic-forms 1.16.9 → 1.17.0

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
@@ -1658,7 +1658,10 @@ const filter$1 = {
1658
1658
  advancedFilter: "Advanced Filter",
1659
1659
  backToFilterRoles: "← Back",
1660
1660
  showFactsOnly: "Show facts only",
1661
- showFactsOnlyDescription: "Hide all blank rows and sections. Only roles and rows with at least one filled value will be shown."
1661
+ showFactsOnlyDescription: "Hide all blank rows and sections. Only roles and rows with at least one filled value will be shown.",
1662
+ searchByConcept: "Search by concept",
1663
+ searchByConceptDescription: "Type concept name or label to filter roles and rows. Press Apply Filter to apply.",
1664
+ searchByConceptPlaceholder: "Type concept name or label and press Apply Filter..."
1662
1665
  };
1663
1666
  const column$1 = {
1664
1667
  addColumn: "Add Column",
@@ -1808,7 +1811,10 @@ const filter = {
1808
1811
  advancedFilter: "Geavanceerd filter",
1809
1812
  backToFilterRoles: "← Terug",
1810
1813
  showFactsOnly: "Alleen feiten weergeven",
1811
- showFactsOnlyDescription: "Verberg alle lege rijen en secties. Alleen rollen en rijen met minimaal één ingevulde waarde worden weergegeven."
1814
+ showFactsOnlyDescription: "Verberg alle lege rijen en secties. Alleen rollen en rijen met minimaal één ingevulde waarde worden weergegeven.",
1815
+ searchByConcept: "Zoeken op concept",
1816
+ searchByConceptDescription: "Typ een conceptnaam of label om rollen en rijen te filteren. Druk op Filter toepassen om te activeren.",
1817
+ searchByConceptPlaceholder: "Typ conceptnaam of label en druk op Filter toepassen..."
1812
1818
  };
1813
1819
  const column = {
1814
1820
  addColumn: "Kolom toevoegen",
@@ -5727,7 +5733,14 @@ let JupiterFormSection = class extends LitElement {
5727
5733
  </tr>
5728
5734
  </thead>
5729
5735
  <tbody class="table-body">
5730
- ${this._flattenConcepts(this.section.concepts, this._expandedConcepts).filter((concept) => this.mode !== "readonly" && !this.showFactsOnly || !this._isConceptRowBlank(concept)).flatMap((concept) => this._renderConceptRows(concept))}
5736
+ ${this._flattenConcepts(this.section.concepts, this._expandedConcepts).filter((concept) => {
5737
+ var _a;
5738
+ if (((_a = this.conceptMatchIds) == null ? void 0 : _a.size) && !this.conceptMatchIds.has(concept.originalConceptId))
5739
+ return false;
5740
+ if (this.mode === "readonly" || this.showFactsOnly)
5741
+ return !this._isConceptRowBlank(concept);
5742
+ return true;
5743
+ }).flatMap((concept) => this._renderConceptRows(concept))}
5731
5744
  </tbody>
5732
5745
  </table>
5733
5746
  </div>
@@ -6063,6 +6076,9 @@ __decorateClass$3([
6063
6076
  __decorateClass$3([
6064
6077
  n2({ type: Boolean })
6065
6078
  ], JupiterFormSection.prototype, "showFactsOnly", 2);
6079
+ __decorateClass$3([
6080
+ n2({ type: Object })
6081
+ ], JupiterFormSection.prototype, "conceptMatchIds", 2);
6066
6082
  __decorateClass$3([
6067
6083
  n2({ type: Object })
6068
6084
  ], JupiterFormSection.prototype, "masterData", 2);
@@ -6117,11 +6133,40 @@ let JupiterAdvancedFilter = class extends LitElement {
6117
6133
  constructor() {
6118
6134
  super(...arguments);
6119
6135
  this.showFactsOnly = false;
6136
+ this.conceptSearchText = "";
6137
+ this._localConceptSearchText = "";
6138
+ }
6139
+ updated(changedProperties) {
6140
+ if (changedProperties.has("conceptSearchText") && this.conceptSearchText !== this._localConceptSearchText) {
6141
+ this._localConceptSearchText = this.conceptSearchText;
6142
+ }
6120
6143
  }
6121
6144
  _handleShowFactsOnlyChange(e2) {
6122
6145
  const checked = e2.target.checked;
6123
- this.dispatchEvent(new CustomEvent("facts-filter-change", {
6124
- detail: { showFactsOnly: checked },
6146
+ this.dispatchEvent(new CustomEvent("filter-change", {
6147
+ detail: { showFactsOnly: checked, conceptSearchText: this._localConceptSearchText },
6148
+ bubbles: true,
6149
+ composed: true
6150
+ }));
6151
+ }
6152
+ _handleConceptSearchInput(e2) {
6153
+ this._localConceptSearchText = e2.target.value;
6154
+ this.dispatchEvent(new CustomEvent("filter-change", {
6155
+ detail: { showFactsOnly: this.showFactsOnly, conceptSearchText: this._localConceptSearchText },
6156
+ bubbles: true,
6157
+ composed: true
6158
+ }));
6159
+ }
6160
+ _clearConceptSearch() {
6161
+ var _a;
6162
+ this._localConceptSearchText = "";
6163
+ const input = (_a = this.shadowRoot) == null ? void 0 : _a.querySelector(".concept-search-input");
6164
+ if (input) {
6165
+ input.value = "";
6166
+ input.focus();
6167
+ }
6168
+ this.dispatchEvent(new CustomEvent("filter-change", {
6169
+ detail: { showFactsOnly: this.showFactsOnly, conceptSearchText: "" },
6125
6170
  bubbles: true,
6126
6171
  composed: true
6127
6172
  }));
@@ -6129,7 +6174,7 @@ let JupiterAdvancedFilter = class extends LitElement {
6129
6174
  render() {
6130
6175
  return html`
6131
6176
  <div class="filter-options">
6132
- <label class="filter-option">
6177
+ <label class="filter-option clickable">
6133
6178
  <input
6134
6179
  type="checkbox"
6135
6180
  .checked="${this.showFactsOnly}"
@@ -6140,6 +6185,29 @@ let JupiterAdvancedFilter = class extends LitElement {
6140
6185
  <p class="filter-option-description">${I18n.t("filter.showFactsOnlyDescription")}</p>
6141
6186
  </div>
6142
6187
  </label>
6188
+
6189
+ <div class="filter-option">
6190
+ <div class="filter-option-body">
6191
+ <div class="filter-option-label">${I18n.t("filter.searchByConcept")}</div>
6192
+ <p class="filter-option-description">${I18n.t("filter.searchByConceptDescription")}</p>
6193
+ <div class="concept-search-input-wrapper">
6194
+ <input
6195
+ type="text"
6196
+ class="concept-search-input"
6197
+ placeholder="${I18n.t("filter.searchByConceptPlaceholder")}"
6198
+ .value="${this._localConceptSearchText}"
6199
+ @input="${this._handleConceptSearchInput}"
6200
+ />
6201
+ ${this._localConceptSearchText ? html`
6202
+ <button
6203
+ class="concept-search-clear"
6204
+ @click="${this._clearConceptSearch}"
6205
+ title="${I18n.t("filter.clearSearch")}"
6206
+ >×</button>
6207
+ ` : ""}
6208
+ </div>
6209
+ </div>
6210
+ </div>
6143
6211
  </div>
6144
6212
  `;
6145
6213
  }
@@ -6152,6 +6220,9 @@ JupiterAdvancedFilter.styles = css`
6152
6220
 
6153
6221
  .filter-options {
6154
6222
  padding: 24px;
6223
+ display: flex;
6224
+ flex-direction: column;
6225
+ gap: 12px;
6155
6226
  }
6156
6227
 
6157
6228
  .filter-option {
@@ -6161,11 +6232,14 @@ JupiterAdvancedFilter.styles = css`
6161
6232
  padding: 16px;
6162
6233
  border: 1px solid var(--primaryTextColor, var(--jupiter-border-color, #ddd));
6163
6234
  border-radius: 6px;
6164
- cursor: pointer;
6165
6235
  transition: background-color 0.2s ease;
6166
6236
  }
6167
6237
 
6168
- .filter-option:hover {
6238
+ .filter-option.clickable {
6239
+ cursor: pointer;
6240
+ }
6241
+
6242
+ .filter-option.clickable:hover {
6169
6243
  background: var(--menuBgColorLighter, var(--jupiter-hover-background, #f5f5f5));
6170
6244
  }
6171
6245
 
@@ -6195,10 +6269,58 @@ JupiterAdvancedFilter.styles = css`
6195
6269
  margin: 4px 0 0 0;
6196
6270
  line-height: 1.5;
6197
6271
  }
6272
+
6273
+ .concept-search-input-wrapper {
6274
+ position: relative;
6275
+ margin-top: 10px;
6276
+ }
6277
+
6278
+ .concept-search-input {
6279
+ width: 100%;
6280
+ box-sizing: border-box;
6281
+ padding: 8px 36px 8px 10px;
6282
+ border: 1px solid var(--primaryTextColor, var(--jupiter-border-color, #ddd));
6283
+ border-radius: 4px;
6284
+ font-size: 13px;
6285
+ font-family: inherit;
6286
+ background: transparent;
6287
+ color: var(--primaryTextColor, var(--jupiter-text-primary, #333));
6288
+ transition: border-color 0.2s ease;
6289
+ }
6290
+
6291
+ .concept-search-input::placeholder {
6292
+ color: var(--primaryTextColor, var(--jupiter-text-secondary, #999));
6293
+ }
6294
+
6295
+ .concept-search-clear {
6296
+ position: absolute;
6297
+ right: 8px;
6298
+ top: 50%;
6299
+ transform: translateY(-50%);
6300
+ background: none;
6301
+ border: none;
6302
+ cursor: pointer;
6303
+ padding: 2px 4px;
6304
+ border-radius: 2px;
6305
+ color: var(--jupiter-text-secondary, #666);
6306
+ font-size: 16px;
6307
+ line-height: 1;
6308
+ transition: color 0.2s ease;
6309
+ }
6310
+
6311
+ .concept-search-clear:hover {
6312
+ color: var(--primaryTextColor, var(--jupiter-text-primary, #333));
6313
+ }
6198
6314
  `;
6199
6315
  __decorateClass$2([
6200
6316
  n2({ type: Boolean })
6201
6317
  ], JupiterAdvancedFilter.prototype, "showFactsOnly", 2);
6318
+ __decorateClass$2([
6319
+ n2({ type: String })
6320
+ ], JupiterAdvancedFilter.prototype, "conceptSearchText", 2);
6321
+ __decorateClass$2([
6322
+ r()
6323
+ ], JupiterAdvancedFilter.prototype, "_localConceptSearchText", 2);
6202
6324
  JupiterAdvancedFilter = __decorateClass$2([
6203
6325
  t$1("jupiter-advanced-filter")
6204
6326
  ], JupiterAdvancedFilter);
@@ -6223,6 +6345,7 @@ let JupiterFilterRolesDialog = class extends LitElement {
6223
6345
  this.mode = "inputForm";
6224
6346
  this.hypercubeData = null;
6225
6347
  this.showFactsOnly = false;
6348
+ this.conceptSearchText = "";
6226
6349
  this._tempSelectedRoles = /* @__PURE__ */ new Set();
6227
6350
  this._searchQuery = "";
6228
6351
  this._filteredRoles = [];
@@ -6235,6 +6358,7 @@ let JupiterFilterRolesDialog = class extends LitElement {
6235
6358
  this._chosenRoleOrder = [];
6236
6359
  this._showAdvancedFilter = false;
6237
6360
  this._showFactsOnly = false;
6361
+ this._conceptSearchText = "";
6238
6362
  }
6239
6363
  connectedCallback() {
6240
6364
  super.connectedCallback();
@@ -6256,6 +6380,7 @@ let JupiterFilterRolesDialog = class extends LitElement {
6256
6380
  this._showAdvancedFilter = false;
6257
6381
  } else {
6258
6382
  this._showFactsOnly = this.showFactsOnly;
6383
+ this._conceptSearchText = this.conceptSearchText;
6259
6384
  }
6260
6385
  }
6261
6386
  }
@@ -6680,12 +6805,13 @@ let JupiterFilterRolesDialog = class extends LitElement {
6680
6805
  _switchToFilterRoles() {
6681
6806
  this._showAdvancedFilter = false;
6682
6807
  }
6683
- _handleFactsFilterChange(e2) {
6808
+ _handleFilterChange(e2) {
6684
6809
  this._showFactsOnly = e2.detail.showFactsOnly;
6810
+ this._conceptSearchText = e2.detail.conceptSearchText ?? "";
6685
6811
  }
6686
6812
  _handleAdvancedFilterApply() {
6687
6813
  this.dispatchEvent(new CustomEvent("advanced-filter-apply", {
6688
- detail: { showFactsOnly: this._showFactsOnly },
6814
+ detail: { showFactsOnly: this._showFactsOnly, conceptSearchText: this._conceptSearchText },
6689
6815
  bubbles: true
6690
6816
  }));
6691
6817
  }
@@ -6982,7 +7108,8 @@ let JupiterFilterRolesDialog = class extends LitElement {
6982
7108
  ` : this._showAdvancedFilter ? html`
6983
7109
  <jupiter-advanced-filter
6984
7110
  .showFactsOnly="${this._showFactsOnly}"
6985
- @facts-filter-change="${this._handleFactsFilterChange}"
7111
+ .conceptSearchText="${this._conceptSearchText}"
7112
+ @filter-change="${this._handleFilterChange}"
6986
7113
  ></jupiter-advanced-filter>
6987
7114
  ` : html`
6988
7115
  <p class="description">
@@ -7775,6 +7902,9 @@ __decorateClass$1([
7775
7902
  __decorateClass$1([
7776
7903
  n2({ type: Boolean })
7777
7904
  ], JupiterFilterRolesDialog.prototype, "showFactsOnly", 2);
7905
+ __decorateClass$1([
7906
+ n2({ type: String })
7907
+ ], JupiterFilterRolesDialog.prototype, "conceptSearchText", 2);
7778
7908
  __decorateClass$1([
7779
7909
  r()
7780
7910
  ], JupiterFilterRolesDialog.prototype, "_tempSelectedRoles", 2);
@@ -7811,6 +7941,9 @@ __decorateClass$1([
7811
7941
  __decorateClass$1([
7812
7942
  r()
7813
7943
  ], JupiterFilterRolesDialog.prototype, "_showFactsOnly", 2);
7944
+ __decorateClass$1([
7945
+ r()
7946
+ ], JupiterFilterRolesDialog.prototype, "_conceptSearchText", 2);
7814
7947
  JupiterFilterRolesDialog = __decorateClass$1([
7815
7948
  t$1("jupiter-filter-roles-dialog")
7816
7949
  ], JupiterFilterRolesDialog);
@@ -7865,6 +7998,7 @@ let JupiterDynamicForm = class extends LitElement {
7865
7998
  this._selectedRoleIds = [];
7866
7999
  this._showFilterDialog = false;
7867
8000
  this._showFactsOnly = false;
8001
+ this._conceptSearchText = "";
7868
8002
  this._periodPreferences = {};
7869
8003
  this._activeSidePanelRoleId = null;
7870
8004
  this._sidePanelSearchQuery = "";
@@ -8556,6 +8690,7 @@ let JupiterDynamicForm = class extends LitElement {
8556
8690
  }
8557
8691
  _handleAdvancedFilterApply(event) {
8558
8692
  this._showFactsOnly = event.detail.showFactsOnly;
8693
+ this._conceptSearchText = event.detail.conceptSearchText ?? "";
8559
8694
  this._showFilterDialog = false;
8560
8695
  }
8561
8696
  _handleFilterDialogCancel() {
@@ -10722,6 +10857,53 @@ let JupiterDynamicForm = class extends LitElement {
10722
10857
  };
10723
10858
  return !hasValue(section2.concepts);
10724
10859
  }
10860
+ _getConceptSearchMatchIds(searchText) {
10861
+ var _a, _b, _c;
10862
+ const result = /* @__PURE__ */ new Set();
10863
+ if (!searchText.trim() || !((_b = (_a = this.xbrlInput) == null ? void 0 : _a.presentation) == null ? void 0 : _b.length)) {
10864
+ return result;
10865
+ }
10866
+ const query = searchText.toLowerCase().trim();
10867
+ const walkConcepts = (concepts) => {
10868
+ var _a2, _b2, _c2;
10869
+ for (const concept of concepts) {
10870
+ let matches = ((_a2 = concept.conceptName) == null ? void 0 : _a2.toLowerCase().includes(query)) || ((_b2 = concept.id) == null ? void 0 : _b2.toLowerCase().includes(query));
10871
+ if (!matches && Array.isArray(concept.labels)) {
10872
+ matches = concept.labels.some((l2) => {
10873
+ var _a3;
10874
+ return (_a3 = l2.label) == null ? void 0 : _a3.toLowerCase().includes(query);
10875
+ });
10876
+ }
10877
+ if (matches) {
10878
+ result.add(concept.id);
10879
+ }
10880
+ if ((_c2 = concept.children) == null ? void 0 : _c2.length) {
10881
+ walkConcepts(concept.children);
10882
+ }
10883
+ }
10884
+ };
10885
+ for (const presentationData of this.xbrlInput.presentation) {
10886
+ for (const role of presentationData.roles || []) {
10887
+ walkConcepts(((_c = role.presentationLinkbase) == null ? void 0 : _c.concepts) || []);
10888
+ }
10889
+ }
10890
+ return result;
10891
+ }
10892
+ _isSectionConceptSearchMatch(section2, matchIds) {
10893
+ if (matchIds.size === 0)
10894
+ return false;
10895
+ const checkConcepts = (concepts) => {
10896
+ var _a;
10897
+ for (const concept of concepts) {
10898
+ if (matchIds.has(concept.originalConceptId))
10899
+ return true;
10900
+ if (((_a = concept.children) == null ? void 0 : _a.length) && checkConcepts(concept.children))
10901
+ return true;
10902
+ }
10903
+ return false;
10904
+ };
10905
+ return checkConcepts(section2.concepts);
10906
+ }
10725
10907
  _filterSidePanelSections(sections) {
10726
10908
  if (!this._sidePanelSearchQuery.trim()) {
10727
10909
  return sections;
@@ -11114,9 +11296,19 @@ let JupiterDynamicForm = class extends LitElement {
11114
11296
  <p>${I18n.t("filter.selectRoles")}</p>
11115
11297
  <p>${I18n.t("filter.roles")}: ${this._allSections.length}</p>
11116
11298
  </div>
11117
- ` : (this.mode === "readonly" || this._showFactsOnly ? schema.sections.filter((s2) => !this._isSectionBlank(s2)) : schema.sections).map((section2, index) => {
11118
- var _a;
11119
- return html`
11299
+ ` : (() => {
11300
+ const conceptMatchIds = this._getConceptSearchMatchIds(this._conceptSearchText);
11301
+ const hasConceptSearch = this._conceptSearchText.trim().length > 0;
11302
+ let sections = schema.sections;
11303
+ if (this.mode === "readonly" || this._showFactsOnly) {
11304
+ sections = sections.filter((s2) => !this._isSectionBlank(s2));
11305
+ }
11306
+ if (hasConceptSearch) {
11307
+ sections = sections.filter((s2) => this._isSectionConceptSearchMatch(s2, conceptMatchIds));
11308
+ }
11309
+ return sections.map((section2, index) => {
11310
+ var _a;
11311
+ return html`
11120
11312
  <jupiter-form-section
11121
11313
  section-id="${section2.id}"
11122
11314
  .section="${section2}"
@@ -11135,6 +11327,7 @@ let JupiterDynamicForm = class extends LitElement {
11135
11327
  .availableDimensions="${this._getAvailableDimensionsForSection(section2.id)}"
11136
11328
  .mode="${this.mode}"
11137
11329
  .showFactsOnly="${this._showFactsOnly}"
11330
+ .conceptMatchIds="${hasConceptSearch ? conceptMatchIds : void 0}"
11138
11331
  .masterData="${this.masterData}"
11139
11332
  .periodStartDate="${this.periodStartDate}"
11140
11333
  .periodEndDate="${this.periodEndDate}"
@@ -11149,13 +11342,19 @@ let JupiterDynamicForm = class extends LitElement {
11149
11342
  @column-add-request="${this._handleColumnAddRequest}"
11150
11343
  ></jupiter-form-section>
11151
11344
  `;
11152
- })}
11345
+ });
11346
+ })()}
11153
11347
  </div>
11154
11348
  `;
11155
11349
  }
11156
11350
  _renderSidePanelLayout(schema, config, showValidationSummary, errorCount) {
11157
11351
  var _a;
11158
- const visibleSections = this.mode === "readonly" || this._showFactsOnly ? schema.sections.filter((s2) => !this._isSectionBlank(s2)) : schema.sections;
11352
+ const conceptMatchIds = this._getConceptSearchMatchIds(this._conceptSearchText);
11353
+ const hasConceptSearch = this._conceptSearchText.trim().length > 0;
11354
+ let visibleSections = this.mode === "readonly" || this._showFactsOnly ? schema.sections.filter((s2) => !this._isSectionBlank(s2)) : schema.sections;
11355
+ if (hasConceptSearch) {
11356
+ visibleSections = visibleSections.filter((s2) => this._isSectionConceptSearchMatch(s2, conceptMatchIds));
11357
+ }
11159
11358
  const filteredSections = this._filterSidePanelSections(visibleSections);
11160
11359
  if (!this._activeSidePanelRoleId || !filteredSections.find((s2) => s2.id === this._activeSidePanelRoleId)) {
11161
11360
  this._activeSidePanelRoleId = filteredSections.length > 0 ? filteredSections[0].id : null;
@@ -11269,6 +11468,7 @@ let JupiterDynamicForm = class extends LitElement {
11269
11468
  .availableDimensions="${this._getAvailableDimensionsForSection(activeSection.id)}"
11270
11469
  .mode="${this.mode}"
11271
11470
  .showFactsOnly="${this._showFactsOnly}"
11471
+ .conceptMatchIds="${hasConceptSearch ? conceptMatchIds : void 0}"
11272
11472
  .masterData="${this.masterData}"
11273
11473
  .periodStartDate="${this.periodStartDate}"
11274
11474
  .periodEndDate="${this.periodEndDate}"
@@ -11422,6 +11622,7 @@ let JupiterDynamicForm = class extends LitElement {
11422
11622
  .hypercubeData="${(_a = this.xbrlInput) == null ? void 0 : _a.hypercubes}"
11423
11623
  .mode="${this.mode}"
11424
11624
  .showFactsOnly="${this._showFactsOnly}"
11625
+ .conceptSearchText="${this._conceptSearchText}"
11425
11626
  @dialog-cancel="${this._handleFilterDialogCancel}"
11426
11627
  @roles-filter-apply="${this._handleRoleFilterApply}"
11427
11628
  @advanced-filter-apply="${this._handleAdvancedFilterApply}"
@@ -12387,6 +12588,9 @@ __decorateClass([
12387
12588
  __decorateClass([
12388
12589
  r()
12389
12590
  ], JupiterDynamicForm.prototype, "_showFactsOnly", 2);
12591
+ __decorateClass([
12592
+ r()
12593
+ ], JupiterDynamicForm.prototype, "_conceptSearchText", 2);
12390
12594
  __decorateClass([
12391
12595
  r()
12392
12596
  ], JupiterDynamicForm.prototype, "_periodPreferences", 2);