jupiter-dynamic-forms 1.18.4 → 1.18.6

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
@@ -1711,7 +1711,9 @@ const filter$1 = {
1711
1711
  showFactsOnlyDescription: "Hide all blank rows and sections. Only roles and rows with at least one filled value will be shown.",
1712
1712
  searchByConcept: "Search by concept",
1713
1713
  searchByConceptDescription: "Type concept name or label to filter roles and rows. Press Apply Filter to apply.",
1714
- searchByConceptPlaceholder: "Type concept name or label and press Apply Filter..."
1714
+ searchByConceptPlaceholder: "Type concept name or label and press Apply Filter...",
1715
+ clearFilters: "Clear Filters",
1716
+ resetFilter: "Reset"
1715
1717
  };
1716
1718
  const column$1 = {
1717
1719
  addColumn: "Add Column",
@@ -1884,7 +1886,9 @@ const filter = {
1884
1886
  showFactsOnlyDescription: "Verberg alle lege rijen en secties. Alleen rollen en rijen met minimaal één ingevulde waarde worden weergegeven.",
1885
1887
  searchByConcept: "Zoeken op concept",
1886
1888
  searchByConceptDescription: "Typ een conceptnaam of label om rollen en rijen te filteren. Druk op Filter toepassen om te activeren.",
1887
- searchByConceptPlaceholder: "Typ conceptnaam of label en druk op Filter toepassen..."
1889
+ searchByConceptPlaceholder: "Typ conceptnaam of label en druk op Filter toepassen...",
1890
+ clearFilters: "Filters wissen",
1891
+ resetFilter: "Resetten"
1888
1892
  };
1889
1893
  const column = {
1890
1894
  addColumn: "Kolom toevoegen",
@@ -4560,7 +4564,7 @@ JupiterFormField.styles = css`
4560
4564
  100% { box-shadow: 0 0 0 0px transparent; background-color: transparent; }
4561
4565
  }
4562
4566
  :host(.concept-highlight) {
4563
- animation: concept-highlight-pulse 1.5s ease-out forwards;
4567
+ animation: concept-highlight-pulse 5s ease-out forwards;
4564
4568
  }
4565
4569
  `;
4566
4570
  __decorateClass$6([
@@ -6886,8 +6890,11 @@ let JupiterAdvancedFilter = class extends LitElement {
6886
6890
  composed: true
6887
6891
  }));
6888
6892
  }
6893
+ _sanitizeSearchText(text) {
6894
+ return text.replace(/[''‚‛′‵]/g, "'").replace(/[""„‟″‶]/g, '"').replace(/[​‌‍­]/g, "").replace(/\s+/g, " ").trim();
6895
+ }
6889
6896
  _handleConceptSearchInput(e2) {
6890
- this._localConceptSearchText = e2.target.value;
6897
+ this._localConceptSearchText = this._sanitizeSearchText(e2.target.value);
6891
6898
  this.dispatchEvent(new CustomEvent("filter-change", {
6892
6899
  detail: { showFactsOnly: this.showFactsOnly, conceptSearchText: this._localConceptSearchText },
6893
6900
  bubbles: true,
@@ -7632,6 +7639,14 @@ let JupiterFilterRolesDialog = class extends LitElement {
7632
7639
  bubbles: true
7633
7640
  }));
7634
7641
  }
7642
+ _handleAdvancedFilterReset() {
7643
+ this._showFactsOnly = false;
7644
+ this._conceptSearchText = "";
7645
+ this.dispatchEvent(new CustomEvent("advanced-filter-apply", {
7646
+ detail: { showFactsOnly: false, conceptSearchText: "" },
7647
+ bubbles: true
7648
+ }));
7649
+ }
7635
7650
  _handleBackdropClick(event) {
7636
7651
  if (event.target === this) {
7637
7652
  this._handleCancel();
@@ -8113,6 +8128,11 @@ let JupiterFilterRolesDialog = class extends LitElement {
8113
8128
  <button class="btn-text" @click="${this._switchToFilterRoles}">
8114
8129
  ${I18n.t("filter.backToFilterRoles")}
8115
8130
  </button>
8131
+ ${this._showFactsOnly || this._conceptSearchText.trim().length > 0 ? html`
8132
+ <button class="btn-text" @click="${this._handleAdvancedFilterReset}">
8133
+ ${I18n.t("filter.resetFilter")}
8134
+ </button>
8135
+ ` : ""}
8116
8136
  ` : html`
8117
8137
  <button class="btn-text" @click="${this._switchToAdvancedFilter}">
8118
8138
  ${I18n.t("filter.advancedFilter")}
@@ -9516,6 +9536,13 @@ let JupiterDynamicForm = class extends LitElement {
9516
9536
  _shouldShowFilterButton() {
9517
9537
  return true;
9518
9538
  }
9539
+ get _hasActiveAdvancedFilters() {
9540
+ return this._showFactsOnly || this._conceptSearchText.trim().length > 0;
9541
+ }
9542
+ _handleClearAdvancedFilters() {
9543
+ this._showFactsOnly = false;
9544
+ this._conceptSearchText = "";
9545
+ }
9519
9546
  _handleFilterRolesClick() {
9520
9547
  this._showFilterDialog = true;
9521
9548
  }
@@ -12557,9 +12584,13 @@ let JupiterDynamicForm = class extends LitElement {
12557
12584
  }
12558
12585
  _findConceptByName(concepts, name) {
12559
12586
  var _a;
12587
+ const localName = name.includes(":") ? name.split(":").pop() : name;
12560
12588
  for (const c2 of concepts) {
12561
12589
  if (c2.name === name)
12562
12590
  return c2;
12591
+ const cLocal = c2.name.includes(":") ? c2.name.split(":").pop() : c2.name;
12592
+ if (cLocal === localName)
12593
+ return c2;
12563
12594
  if ((_a = c2.children) == null ? void 0 : _a.length) {
12564
12595
  const hit = this._findConceptByName(c2.children, name);
12565
12596
  if (hit)
@@ -12584,8 +12615,8 @@ let JupiterDynamicForm = class extends LitElement {
12584
12615
  return dims.length === 1 && this._normalizeAxisId(col.dimensionData.axisId ?? "") === this._normalizeAxisId(dims[0].axis) && this._normalizeMemberId(col.dimensionData.memberId ?? "") === this._normalizeMemberId(dims[0].member);
12585
12616
  })) == null ? void 0 : _a.id;
12586
12617
  }
12587
- async scrollToConcept(conceptName, dimensions) {
12588
- var _a, _b, _c, _d;
12618
+ async scrollToConcept(conceptName, dimensions, match) {
12619
+ var _a, _b, _c, _d, _e, _f;
12589
12620
  let targetSection = null;
12590
12621
  let targetConcept = null;
12591
12622
  const sectionsToSearch = [
@@ -12613,10 +12644,11 @@ let JupiterDynamicForm = class extends LitElement {
12613
12644
  }
12614
12645
  const columns = targetSection.columns ?? this._columns;
12615
12646
  let targetColumnId = null;
12647
+ const hasValueMatch = (match == null ? void 0 : match.value) !== void 0 && (match == null ? void 0 : match.value) !== null;
12648
+ const targetValue = hasValueMatch ? String(match.value) : null;
12616
12649
  if (dimensions == null ? void 0 : dimensions.length) {
12617
12650
  targetColumnId = this._findColumnByDimensions(columns, dimensions) ?? null;
12618
- }
12619
- if (!targetColumnId) {
12651
+ } else if (!hasValueMatch) {
12620
12652
  targetColumnId = ((_b = columns[0]) == null ? void 0 : _b.id) ?? null;
12621
12653
  }
12622
12654
  this.requestUpdate();
@@ -12646,17 +12678,36 @@ let JupiterDynamicForm = class extends LitElement {
12646
12678
  if (targetFieldEl)
12647
12679
  return;
12648
12680
  const columnMatch = targetColumnId ? fieldEl.conceptId === conceptId && fieldEl.columnId === targetColumnId : fieldEl.conceptId === conceptId;
12649
- if (columnMatch)
12681
+ const valueMatch = !hasValueMatch || String(fieldEl.value ?? "") === targetValue;
12682
+ if (columnMatch && valueMatch)
12650
12683
  targetFieldEl = fieldEl;
12651
12684
  });
12652
12685
  });
12686
+ if (!targetFieldEl && hasValueMatch && !targetColumnId) {
12687
+ for (const ct of Array.from(conceptTrees ?? [])) {
12688
+ if (targetFieldEl)
12689
+ break;
12690
+ const fields = (_e = ct.shadowRoot) == null ? void 0 : _e.querySelectorAll("jupiter-form-field");
12691
+ fields == null ? void 0 : fields.forEach((fieldEl) => {
12692
+ if (targetFieldEl)
12693
+ return;
12694
+ const columnMatch = targetColumnId ? fieldEl.conceptId === conceptId && fieldEl.columnId === targetColumnId : fieldEl.conceptId === conceptId;
12695
+ if (columnMatch)
12696
+ targetFieldEl = fieldEl;
12697
+ });
12698
+ }
12699
+ }
12653
12700
  if (!targetFieldEl) {
12654
12701
  console.warn(`[scrollToConcept] Field element not found for concept: ${conceptName}`);
12655
12702
  return;
12656
12703
  }
12657
12704
  targetFieldEl.scrollIntoView({ behavior: "smooth", block: "center" });
12658
12705
  targetFieldEl.classList.add("concept-highlight");
12659
- setTimeout(() => targetFieldEl.classList.remove("concept-highlight"), 1500);
12706
+ const focusTarget = (_f = targetFieldEl.shadowRoot) == null ? void 0 : _f.querySelector(
12707
+ 'input:not([type="hidden"]), select, textarea, button, [tabindex]:not([tabindex="-1"])'
12708
+ );
12709
+ focusTarget == null ? void 0 : focusTarget.focus({ preventScroll: true });
12710
+ setTimeout(() => targetFieldEl.classList.remove("concept-highlight"), 5e3);
12660
12711
  }
12661
12712
  render() {
12662
12713
  var _a;
@@ -12687,8 +12738,8 @@ let JupiterDynamicForm = class extends LitElement {
12687
12738
  <div class="form-actions">
12688
12739
  <!-- Filter Roles Button (shown when more than 10 roles) -->
12689
12740
  ${this._shouldShowFilterButton() ? html`
12690
- <button
12691
- class="filter-roles-button"
12741
+ <button
12742
+ class="filter-roles-button ${this._hasActiveAdvancedFilters ? "has-active-filters" : ""}"
12692
12743
  @click="${this._handleFilterRolesClick}"
12693
12744
  ?disabled="${this.disabled || this.readonly}"
12694
12745
  >
@@ -12698,6 +12749,15 @@ let JupiterDynamicForm = class extends LitElement {
12698
12749
  ${this._selectedRoleIds.length === 0 ? I18n.t("filter.selectRoles") : I18n.t("filter.filterRoles")}
12699
12750
  <span class="roles-count">${this._selectedRoleIds.length}/${this._allSections.length}</span>
12700
12751
  </button>
12752
+ ${this._hasActiveAdvancedFilters ? html`
12753
+ <button
12754
+ class="clear-filters-button"
12755
+ @click="${this._handleClearAdvancedFilters}"
12756
+ ?disabled="${this.disabled || this.readonly}"
12757
+ >
12758
+ × ${I18n.t("filter.clearFilters")}
12759
+ </button>
12760
+ ` : ""}
12701
12761
  ` : ""}
12702
12762
 
12703
12763
  ${this.mode !== "admin" ? html`
@@ -13028,12 +13088,37 @@ JupiterDynamicForm.styles = css`
13028
13088
  opacity: 0.9;
13029
13089
  }
13030
13090
 
13091
+ .filter-roles-button.has-active-filters {
13092
+ background: var(--buttonBgColor, var(--jupiter-primary-color, #1976d2));
13093
+ color: var(--buttonTextColor, white);
13094
+ }
13095
+
13031
13096
  .filter-roles-button .filter-icon {
13032
13097
  width: 16px;
13033
13098
  height: 16px;
13034
13099
  fill: currentColor;
13035
13100
  }
13036
13101
 
13102
+ .clear-filters-button {
13103
+ display: flex;
13104
+ align-items: center;
13105
+ gap: 6px;
13106
+ padding: 8px 14px;
13107
+ background: transparent;
13108
+ border: 1px solid var(--jupiter-border-color, #ddd);
13109
+ color: var(--primaryTextColor, var(--jupiter-text-secondary, #666));
13110
+ border-radius: 4px;
13111
+ font-size: 13px;
13112
+ font-weight: 500;
13113
+ cursor: pointer;
13114
+ transition: all 0.2s ease;
13115
+ }
13116
+
13117
+ .clear-filters-button:hover {
13118
+ border-color: var(--primaryTextColor, var(--jupiter-primary-color, #1976d2));
13119
+ color: var(--primaryTextColor, var(--jupiter-primary-color, #1976d2));
13120
+ }
13121
+
13037
13122
  .roles-count {
13038
13123
  display: inline-flex;
13039
13124
  align-items: center;