jupiter-dynamic-forms 1.14.2 → 1.14.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/index.mjs CHANGED
@@ -619,8 +619,12 @@ class XBRLFormBuilder {
619
619
  const periodTypes = new Set(
620
620
  nonAbstractConcepts.filter((concept) => concept.periodType).map((concept) => concept.periodType)
621
621
  );
622
- const hypercubeRole = hypercubeData == null ? void 0 : hypercubeData.roles.find((hr) => hr.roleId === role.id);
622
+ let hypercubeRole = hypercubeData == null ? void 0 : hypercubeData.roles.find((hr) => hr.roleId === role.id);
623
623
  const rolePreferences = periodPreferences == null ? void 0 : periodPreferences[role.id];
624
+ if (hypercubeRole && (rolePreferences == null ? void 0 : rolePreferences.dimensionSelections) && rolePreferences.dimensionSelections.length > 0) {
625
+ console.log(`🔍 Filtering dimensions for role ${role.id} based on user selections`);
626
+ hypercubeRole = this.filterHypercubeDimensionsBySelection(hypercubeRole, rolePreferences.dimensionSelections);
627
+ }
624
628
  const columns = this.generateDefaultColumnsForRole(role, periodStartDate || "2025-01-01", periodEndDate || "2025-12-31", hypercubeRole, nonAbstractConcepts, periodTypes, rolePreferences);
625
629
  const availableColumnIds = columns.map((col) => col.id);
626
630
  const roleInfo = { periodTypes, availableColumnIds };
@@ -840,6 +844,53 @@ class XBRLFormBuilder {
840
844
  });
841
845
  }
842
846
  }
847
+ /**
848
+ * Filter hypercube dimensions to only include selected members
849
+ */
850
+ static filterHypercubeDimensionsBySelection(hypercubeRole, dimensionSelections) {
851
+ const filteredRole = JSON.parse(JSON.stringify(hypercubeRole));
852
+ if (!filteredRole.items || filteredRole.items.length === 0) {
853
+ return filteredRole;
854
+ }
855
+ filteredRole.items.forEach((item) => {
856
+ if (!item.dimensions)
857
+ return;
858
+ item.dimensions = item.dimensions.map((dimension) => {
859
+ var _a, _b;
860
+ const selection = dimensionSelections.find((s2) => s2.dimensionId === dimension.id);
861
+ if (!selection || !selection.selectedMemberIds || selection.selectedMemberIds.length === 0) {
862
+ return dimension;
863
+ }
864
+ const filteredDimension = { ...dimension };
865
+ filteredDimension.members = this.filterMembersBySelection(dimension.members, selection.selectedMemberIds);
866
+ console.log(` ✅ Filtered dimension ${dimension.id}: ${((_a = dimension.members) == null ? void 0 : _a.length) || 0} → ${((_b = filteredDimension.members) == null ? void 0 : _b.length) || 0} members`);
867
+ return filteredDimension;
868
+ });
869
+ });
870
+ return filteredRole;
871
+ }
872
+ /**
873
+ * Recursively filter dimension members to only include selected IDs
874
+ */
875
+ static filterMembersBySelection(members, selectedIds) {
876
+ if (!members || !Array.isArray(members))
877
+ return [];
878
+ const filtered = [];
879
+ members.forEach((member) => {
880
+ if (selectedIds.includes(member.id)) {
881
+ filtered.push({
882
+ ...member,
883
+ children: []
884
+ // Reset children as we're doing flat selection
885
+ });
886
+ }
887
+ if (member.children && member.children.length > 0) {
888
+ const filteredChildren = this.filterMembersBySelection(member.children, selectedIds);
889
+ filtered.push(...filteredChildren);
890
+ }
891
+ });
892
+ return filtered;
893
+ }
843
894
  /**
844
895
  * Generate default columns based on period types of non-abstract concepts in a role
845
896
  */
@@ -1483,7 +1534,10 @@ const filter$1 = {
1483
1534
  showPreviousYear: "Show previous year",
1484
1535
  duration: "Duration",
1485
1536
  instant: "Instant",
1486
- uri: "URI"
1537
+ uri: "URI",
1538
+ dimensionMemberSelection: "Dimension Member Selection",
1539
+ selectAllMembers: "Select All",
1540
+ clearMembers: "Clear"
1487
1541
  };
1488
1542
  const column$1 = {
1489
1543
  addColumn: "Add Column",
@@ -1596,7 +1650,10 @@ const filter = {
1596
1650
  showPreviousYear: "Vorig jaar weergeven",
1597
1651
  duration: "Duur",
1598
1652
  instant: "Moment",
1599
- uri: "URI"
1653
+ uri: "URI",
1654
+ dimensionMemberSelection: "Dimensieleden selectie",
1655
+ selectAllMembers: "Alles selecteren",
1656
+ clearMembers: "Wissen"
1600
1657
  };
1601
1658
  const column = {
1602
1659
  addColumn: "Kolom toevoegen",
@@ -2637,6 +2694,60 @@ let JupiterFormField = class extends LitElement {
2637
2694
  }));
2638
2695
  console.log(`🟦 [FormField] Dispatched field-blur event with ${this._xbrlErrors.length} errors`);
2639
2696
  }
2697
+ /**
2698
+ * Checks if the concept type or its baseType chain contains monetary type
2699
+ */
2700
+ _isMonetaryType() {
2701
+ if (!this.conceptType || !this.datatypes) {
2702
+ return false;
2703
+ }
2704
+ if (this.conceptType.includes("monetary") || this.conceptType.includes("Monetary")) {
2705
+ return true;
2706
+ }
2707
+ const baseTypeChain = resolveBaseTypeChain(this.conceptType, this.datatypes);
2708
+ return baseTypeChain.some(
2709
+ (type) => type.includes("monetary") || type.includes("Monetary")
2710
+ );
2711
+ }
2712
+ /**
2713
+ * Prevents non-numeric input in number fields for Firefox compatibility
2714
+ * Firefox allows typing any character in type="number" inputs
2715
+ */
2716
+ _handleKeyDown(event) {
2717
+ const target = event.target;
2718
+ if (target.type !== "number") {
2719
+ return;
2720
+ }
2721
+ const allowedKeys = [
2722
+ "Backspace",
2723
+ "Delete",
2724
+ "Tab",
2725
+ "Escape",
2726
+ "Enter",
2727
+ "ArrowLeft",
2728
+ "ArrowRight",
2729
+ "ArrowUp",
2730
+ "ArrowDown",
2731
+ "Home",
2732
+ "End"
2733
+ ];
2734
+ if (allowedKeys.includes(event.key)) {
2735
+ return;
2736
+ }
2737
+ if (event.ctrlKey || event.metaKey) {
2738
+ return;
2739
+ }
2740
+ if (event.key === "-" && target.selectionStart === 0 && !target.value.includes("-")) {
2741
+ return;
2742
+ }
2743
+ if (event.key === "." && !target.value.includes(".")) {
2744
+ return;
2745
+ }
2746
+ if (event.key >= "0" && event.key <= "9") {
2747
+ return;
2748
+ }
2749
+ event.preventDefault();
2750
+ }
2640
2751
  /**
2641
2752
  * Validates the current value against XBRL datatype validation rules
2642
2753
  * Called on blur event when user loses focus on the input field
@@ -2793,7 +2904,8 @@ let JupiterFormField = class extends LitElement {
2793
2904
  _renderInput() {
2794
2905
  const hasErrors = this._errors.some((e2) => e2.severity === "error");
2795
2906
  const hasWarnings = this._errors.some((e2) => e2.severity === "warning");
2796
- const cssClass = `field-input ${hasErrors ? "error" : hasWarnings ? "warning" : ""}`;
2907
+ const isMonetary = this._isMonetaryType();
2908
+ const cssClass = `field-input ${hasErrors ? "error" : hasWarnings ? "warning" : ""} ${isMonetary ? "monetary" : ""}`;
2797
2909
  const fieldId = `${this.conceptId}__${this.columnId}`;
2798
2910
  const fieldName = `data[${this.conceptId}][${this.columnId}]`;
2799
2911
  const typeConfig = getInputTypeForConceptType(this.conceptType, this.datatypes);
@@ -2883,6 +2995,7 @@ let JupiterFormField = class extends LitElement {
2883
2995
  @input="${this._handleInput}"
2884
2996
  @focus="${this._handleFocus}"
2885
2997
  @blur="${this._handleBlur}"
2998
+ @keydown="${this._handleKeyDown}"
2886
2999
  />
2887
3000
  `;
2888
3001
  }
@@ -3259,6 +3372,10 @@ JupiterFormField.styles = css`
3259
3372
  border-color: var(--jupiter-warning-color, #ff9800);
3260
3373
  }
3261
3374
 
3375
+ .field-input.monetary {
3376
+ text-align: right;
3377
+ }
3378
+
3262
3379
  .field-errors {
3263
3380
  margin-top: 4px;
3264
3381
  }
@@ -4985,6 +5102,7 @@ let JupiterFilterRolesDialog = class extends LitElement {
4985
5102
  this.selectedRoleIds = [];
4986
5103
  this.periodPreferences = {};
4987
5104
  this.mode = "user";
5105
+ this.hypercubeData = null;
4988
5106
  this._tempSelectedRoles = /* @__PURE__ */ new Set();
4989
5107
  this._searchQuery = "";
4990
5108
  this._filteredRoles = [];
@@ -5116,6 +5234,27 @@ let JupiterFilterRolesDialog = class extends LitElement {
5116
5234
  // Read from role data in presentation.json
5117
5235
  };
5118
5236
  }
5237
+ const dimensions = this._getDimensionsForRole(role.id);
5238
+ if (dimensions.length > 0 && !(existingPrefs == null ? void 0 : existingPrefs.dimensionSelections)) {
5239
+ if (!preferences[role.id].dimensionSelections) {
5240
+ preferences[role.id].dimensionSelections = [];
5241
+ }
5242
+ dimensions.forEach((dimension) => {
5243
+ var _a, _b;
5244
+ const allMembers = this._getAllDimensionMembers(dimension.members);
5245
+ if (allMembers.length > 0) {
5246
+ const dimensionLabel = ((_b = (_a = dimension.labels) == null ? void 0 : _a.find((l2) => l2.role === "http://www.xbrl.org/2003/role/label")) == null ? void 0 : _b.label) || dimension.conceptName;
5247
+ const allMemberIds = allMembers.map((m) => m.id);
5248
+ const dimensionSelection = {
5249
+ dimensionId: dimension.id,
5250
+ dimensionLabel,
5251
+ selectedMemberIds: allMemberIds
5252
+ };
5253
+ preferences[role.id].dimensionSelections.push(dimensionSelection);
5254
+ console.log(`✅ Auto-selected all ${allMemberIds.length} members for dimension: ${dimensionLabel}`);
5255
+ }
5256
+ });
5257
+ }
5119
5258
  });
5120
5259
  this._tempPeriodPreferences = preferences;
5121
5260
  }
@@ -5203,6 +5342,7 @@ let JupiterFilterRolesDialog = class extends LitElement {
5203
5342
  });
5204
5343
  console.log("✅ Apply Filter - Enhanced structure being emitted:", orderedRolesWithMetadata);
5205
5344
  console.log("📋 Order array:", this._chosenRoleOrder);
5345
+ console.log("📊 Dimension preferences being emitted:", this._tempPeriodPreferences);
5206
5346
  this.dispatchEvent(new CustomEvent("roles-filter-apply", {
5207
5347
  detail: {
5208
5348
  selectedRoleIds: orderedRolesWithMetadata,
@@ -5211,6 +5351,200 @@ let JupiterFilterRolesDialog = class extends LitElement {
5211
5351
  bubbles: true
5212
5352
  }));
5213
5353
  }
5354
+ /**
5355
+ * Get dimensions for a specific role from hypercube data
5356
+ */
5357
+ _getDimensionsForRole(roleId) {
5358
+ var _a, _b;
5359
+ console.log("🔍 [getDimensionsForRole] Called with roleId:", roleId);
5360
+ console.log("🔍 [getDimensionsForRole] hypercubeData exists:", !!this.hypercubeData);
5361
+ console.log("🔍 [getDimensionsForRole] hypercubeData type:", typeof this.hypercubeData);
5362
+ console.log("🔍 [getDimensionsForRole] hypercubeData value:", this.hypercubeData);
5363
+ if (!this.hypercubeData) {
5364
+ console.error("❌ [getDimensionsForRole] CRITICAL: hypercubeData is null/undefined/false");
5365
+ console.error("❌ Parent component must pass hypercubeData property to filter dialog!");
5366
+ console.error('❌ Example: <jupiter-filter-roles-dialog .hypercubeData="${hypercubeData}">');
5367
+ return [];
5368
+ }
5369
+ let hypercubeDataObj = this.hypercubeData;
5370
+ if (Array.isArray(this.hypercubeData) && this.hypercubeData.length > 0) {
5371
+ console.log("📦 [getDimensionsForRole] Detected array-wrapped format, unwrapping...");
5372
+ hypercubeDataObj = this.hypercubeData[0];
5373
+ }
5374
+ console.log("🔍 [getDimensionsForRole] hypercubeDataObj.roles exists:", !!(hypercubeDataObj == null ? void 0 : hypercubeDataObj.roles));
5375
+ if (!(hypercubeDataObj == null ? void 0 : hypercubeDataObj.roles)) {
5376
+ console.warn("⚠️ [getDimensionsForRole] No roles found in hypercube data structure");
5377
+ console.warn("⚠️ Expected structure: { roles: [...] } or [{ roles: [...] }]");
5378
+ return [];
5379
+ }
5380
+ console.log(
5381
+ "🔍 [getDimensionsForRole] Available hypercube roles:",
5382
+ hypercubeDataObj.roles.map((r2) => r2.roleId)
5383
+ );
5384
+ const hypercubeRole = hypercubeDataObj.roles.find((r2) => r2.roleId === roleId);
5385
+ console.log("🔍 [getDimensionsForRole] Found hypercube role:", !!hypercubeRole);
5386
+ if (!((_a = hypercubeRole == null ? void 0 : hypercubeRole.items) == null ? void 0 : _a.length)) {
5387
+ console.warn("⚠️ [getDimensionsForRole] No items found in hypercube role for:", roleId);
5388
+ return [];
5389
+ }
5390
+ console.log("🔍 [getDimensionsForRole] Items count:", hypercubeRole.items.length);
5391
+ const dimensions = ((_b = hypercubeRole.items[0]) == null ? void 0 : _b.dimensions) || [];
5392
+ console.log("🔍 [getDimensionsForRole] Total dimensions found:", dimensions.length);
5393
+ console.log("🔍 [getDimensionsForRole] Dimension details:", dimensions.map((d2) => {
5394
+ var _a2;
5395
+ return {
5396
+ id: d2.id,
5397
+ type: d2.dimensionType,
5398
+ hasMembers: !!(d2.members && d2.members.length > 0),
5399
+ membersCount: ((_a2 = d2.members) == null ? void 0 : _a2.length) || 0
5400
+ };
5401
+ }));
5402
+ const filtered = dimensions.filter(
5403
+ (dim) => dim.dimensionType === "explicit" && dim.members && Array.isArray(dim.members) && dim.members.length > 0
5404
+ );
5405
+ console.log("✅ [getDimensionsForRole] Filtered dimensions count:", filtered.length);
5406
+ console.log("✅ [getDimensionsForRole] Filtered dimension IDs:", filtered.map((d2) => d2.id));
5407
+ return filtered;
5408
+ }
5409
+ /**
5410
+ * Get all members for a dimension (including nested children)
5411
+ */
5412
+ _getAllDimensionMembers(members) {
5413
+ if (!members || !Array.isArray(members)) {
5414
+ return [];
5415
+ }
5416
+ const allMembers = [];
5417
+ members.forEach((member) => {
5418
+ allMembers.push(member);
5419
+ if (member.children && member.children.length > 0) {
5420
+ allMembers.push(...this._getAllDimensionMembers(member.children));
5421
+ }
5422
+ });
5423
+ return allMembers;
5424
+ }
5425
+ /**
5426
+ * Check if dimension has only one member (should be auto-selected and disabled)
5427
+ */
5428
+ _isSingleMemberDimension(dimension) {
5429
+ const allMembers = this._getAllDimensionMembers(dimension.members);
5430
+ return allMembers.length === 1;
5431
+ }
5432
+ /**
5433
+ * Handle dimension member selection change
5434
+ */
5435
+ _handleDimensionMemberChange(event, roleId, dimensionId, memberId) {
5436
+ var _a, _b;
5437
+ event.stopPropagation();
5438
+ const checkbox = event.target;
5439
+ const newPreferences = { ...this._tempPeriodPreferences };
5440
+ if (!newPreferences[roleId]) {
5441
+ newPreferences[roleId] = {
5442
+ showDuration: true,
5443
+ showInstant: true,
5444
+ showPreviousYear: false,
5445
+ dimensionSelections: []
5446
+ };
5447
+ }
5448
+ if (!newPreferences[roleId].dimensionSelections) {
5449
+ newPreferences[roleId].dimensionSelections = [];
5450
+ }
5451
+ let dimensionSelection = newPreferences[roleId].dimensionSelections.find(
5452
+ (ds) => ds.dimensionId === dimensionId
5453
+ );
5454
+ if (!dimensionSelection) {
5455
+ const dimensions = this._getDimensionsForRole(roleId);
5456
+ const dimension = dimensions.find((d2) => d2.id === dimensionId);
5457
+ const dimensionLabel = ((_b = (_a = dimension == null ? void 0 : dimension.labels) == null ? void 0 : _a.find((l2) => l2.role === "http://www.xbrl.org/2003/role/label")) == null ? void 0 : _b.label) || dimensionId;
5458
+ dimensionSelection = {
5459
+ dimensionId,
5460
+ dimensionLabel,
5461
+ selectedMemberIds: []
5462
+ };
5463
+ newPreferences[roleId].dimensionSelections.push(dimensionSelection);
5464
+ }
5465
+ if (checkbox.checked) {
5466
+ if (!dimensionSelection.selectedMemberIds.includes(memberId)) {
5467
+ dimensionSelection.selectedMemberIds.push(memberId);
5468
+ }
5469
+ } else {
5470
+ dimensionSelection.selectedMemberIds = dimensionSelection.selectedMemberIds.filter(
5471
+ (id) => id !== memberId
5472
+ );
5473
+ }
5474
+ this._tempPeriodPreferences = newPreferences;
5475
+ console.log("📊 Updated dimension selections:", newPreferences[roleId].dimensionSelections);
5476
+ this.requestUpdate();
5477
+ }
5478
+ /**
5479
+ * Check if a dimension member is selected
5480
+ */
5481
+ _isDimensionMemberSelected(roleId, dimensionId, memberId) {
5482
+ const preferences = this._tempPeriodPreferences[roleId];
5483
+ if (!(preferences == null ? void 0 : preferences.dimensionSelections)) {
5484
+ return false;
5485
+ }
5486
+ const dimensionSelection = preferences.dimensionSelections.find(
5487
+ (ds) => ds.dimensionId === dimensionId
5488
+ );
5489
+ return (dimensionSelection == null ? void 0 : dimensionSelection.selectedMemberIds.includes(memberId)) || false;
5490
+ }
5491
+ /**
5492
+ * Select all members for a dimension
5493
+ */
5494
+ _selectAllDimensionMembers(roleId, dimensionId) {
5495
+ var _a, _b;
5496
+ const dimensions = this._getDimensionsForRole(roleId);
5497
+ const dimension = dimensions.find((d2) => d2.id === dimensionId);
5498
+ if (!dimension)
5499
+ return;
5500
+ const allMembers = this._getAllDimensionMembers(dimension.members);
5501
+ const allMemberIds = allMembers.map((m) => m.id);
5502
+ const newPreferences = { ...this._tempPeriodPreferences };
5503
+ if (!newPreferences[roleId]) {
5504
+ newPreferences[roleId] = {
5505
+ showDuration: true,
5506
+ showInstant: true,
5507
+ showPreviousYear: false,
5508
+ dimensionSelections: []
5509
+ };
5510
+ }
5511
+ if (!newPreferences[roleId].dimensionSelections) {
5512
+ newPreferences[roleId].dimensionSelections = [];
5513
+ }
5514
+ let dimensionSelection = newPreferences[roleId].dimensionSelections.find(
5515
+ (ds) => ds.dimensionId === dimensionId
5516
+ );
5517
+ if (!dimensionSelection) {
5518
+ const dimensionLabel = ((_b = (_a = dimension.labels) == null ? void 0 : _a.find((l2) => l2.role === "http://www.xbrl.org/2003/role/label")) == null ? void 0 : _b.label) || dimensionId;
5519
+ dimensionSelection = {
5520
+ dimensionId,
5521
+ dimensionLabel,
5522
+ selectedMemberIds: []
5523
+ };
5524
+ newPreferences[roleId].dimensionSelections.push(dimensionSelection);
5525
+ }
5526
+ dimensionSelection.selectedMemberIds = allMemberIds;
5527
+ this._tempPeriodPreferences = newPreferences;
5528
+ this.requestUpdate();
5529
+ }
5530
+ /**
5531
+ * Deselect all members for a dimension
5532
+ */
5533
+ _deselectAllDimensionMembers(roleId, dimensionId) {
5534
+ var _a;
5535
+ const newPreferences = { ...this._tempPeriodPreferences };
5536
+ if (!((_a = newPreferences[roleId]) == null ? void 0 : _a.dimensionSelections)) {
5537
+ return;
5538
+ }
5539
+ const dimensionSelection = newPreferences[roleId].dimensionSelections.find(
5540
+ (ds) => ds.dimensionId === dimensionId
5541
+ );
5542
+ if (dimensionSelection) {
5543
+ dimensionSelection.selectedMemberIds = [];
5544
+ }
5545
+ this._tempPeriodPreferences = newPreferences;
5546
+ this.requestUpdate();
5547
+ }
5214
5548
  _handleBackdropClick(event) {
5215
5549
  if (event.target === this) {
5216
5550
  this._handleCancel();
@@ -5579,6 +5913,10 @@ let JupiterFilterRolesDialog = class extends LitElement {
5579
5913
  const isSelected = this._tempSelectedRoles.has(role.id);
5580
5914
  role.showPeriodControl === true;
5581
5915
  const preferences = this._tempPeriodPreferences[role.id] || { showDuration: true, showInstant: true };
5916
+ console.log("🎨 [Render] Processing role:", role.title, "ID:", role.id);
5917
+ const dimensions = this._getDimensionsForRole(role.id);
5918
+ const hasDimensions = dimensions.length > 0;
5919
+ console.log("🎨 [Render] Role:", role.title, "- Has dimensions:", hasDimensions, "- Count:", dimensions.length);
5582
5920
  return html`
5583
5921
  <div class="role-item">
5584
5922
  <input
@@ -5607,6 +5945,58 @@ let JupiterFilterRolesDialog = class extends LitElement {
5607
5945
  </label>
5608
5946
  </div>
5609
5947
  </div>
5948
+
5949
+ ${hasDimensions ? html`
5950
+ <div class="dimension-section">
5951
+ <div class="dimension-header">📊 ${I18n.t("filter.dimensionMemberSelection")}</div>
5952
+ ${dimensions.map((dimension) => {
5953
+ var _a2, _b;
5954
+ const allMembers = this._getAllDimensionMembers(dimension.members);
5955
+ const dimensionLabel = ((_b = (_a2 = dimension.labels) == null ? void 0 : _a2.find((l2) => l2.role === "http://www.xbrl.org/2003/role/label")) == null ? void 0 : _b.label) || dimension.conceptName;
5956
+ const isSingleMember = this._isSingleMemberDimension(dimension);
5957
+ return html`
5958
+ <div class="dimension-group">
5959
+ <div class="dimension-label">${dimensionLabel}</div>
5960
+ <div class="dimension-members">
5961
+ ${allMembers.map((member) => {
5962
+ var _a3, _b2;
5963
+ const memberLabel = ((_b2 = (_a3 = member.labels) == null ? void 0 : _a3.find((l2) => l2.role === "http://www.xbrl.org/2003/role/label")) == null ? void 0 : _b2.label) || member.conceptName;
5964
+ const isChecked = this._isDimensionMemberSelected(role.id, dimension.id, member.id);
5965
+ return html`
5966
+ <label class="member-checkbox-item">
5967
+ <input
5968
+ type="checkbox"
5969
+ class="member-checkbox"
5970
+ .checked="${isChecked}"
5971
+ ?disabled="${isSingleMember}"
5972
+ @change="${(e2) => this._handleDimensionMemberChange(e2, role.id, dimension.id, member.id)}"
5973
+ />
5974
+ <span class="member-checkbox-label">${memberLabel}</span>
5975
+ </label>
5976
+ `;
5977
+ })}
5978
+ </div>
5979
+ ${!isSingleMember ? html`
5980
+ <div class="member-select-controls">
5981
+ <button
5982
+ class="member-select-btn"
5983
+ @click="${() => this._selectAllDimensionMembers(role.id, dimension.id)}"
5984
+ >
5985
+ ${I18n.t("filter.selectAllMembers")}
5986
+ </button>
5987
+ <button
5988
+ class="member-select-btn"
5989
+ @click="${() => this._deselectAllDimensionMembers(role.id, dimension.id)}"
5990
+ >
5991
+ ${I18n.t("filter.clearMembers")}
5992
+ </button>
5993
+ </div>
5994
+ ` : ""}
5995
+ </div>
5996
+ `;
5997
+ })}
5998
+ </div>
5999
+ ` : ""}
5610
6000
  </div>
5611
6001
  </div>
5612
6002
  `;
@@ -5909,6 +6299,98 @@ JupiterFilterRolesDialog.styles = css`
5909
6299
  user-select: none;
5910
6300
  }
5911
6301
 
6302
+ .dimension-section {
6303
+ margin-top: 12px;
6304
+ padding: 8px;
6305
+ background: var(--jupiter-background, #fff);
6306
+ border-radius: 4px;
6307
+ border: 1px solid var(--jupiter-border-color, #e0e0e0);
6308
+ }
6309
+
6310
+ .dimension-header {
6311
+ font-size: 12px;
6312
+ font-weight: 600;
6313
+ color: var(--jupiter-primary-color, #1976d2);
6314
+ margin: 0 0 8px 0;
6315
+ padding-bottom: 4px;
6316
+ border-bottom: 1px solid var(--jupiter-border-color, #e0e0e0);
6317
+ }
6318
+
6319
+ .dimension-group {
6320
+ margin-bottom: 12px;
6321
+ }
6322
+
6323
+ .dimension-group:last-child {
6324
+ margin-bottom: 0;
6325
+ }
6326
+
6327
+ .dimension-label {
6328
+ font-size: 11px;
6329
+ font-weight: 600;
6330
+ color: var(--jupiter-text-secondary, #666);
6331
+ margin: 0 0 6px 0;
6332
+ text-transform: uppercase;
6333
+ letter-spacing: 0.5px;
6334
+ }
6335
+
6336
+ .dimension-members {
6337
+ display: flex;
6338
+ flex-direction: column;
6339
+ gap: 4px;
6340
+ padding-left: 8px;
6341
+ }
6342
+
6343
+ .member-checkbox-item {
6344
+ display: flex;
6345
+ align-items: center;
6346
+ gap: 6px;
6347
+ padding: 2px 0;
6348
+ }
6349
+
6350
+ .member-checkbox {
6351
+ cursor: pointer;
6352
+ flex-shrink: 0;
6353
+ }
6354
+
6355
+ .member-checkbox-label {
6356
+ font-size: 12px;
6357
+ color: var(--jupiter-text-primary, #333);
6358
+ cursor: pointer;
6359
+ user-select: none;
6360
+ line-height: 1.3;
6361
+ }
6362
+
6363
+ .member-select-controls {
6364
+ display: flex;
6365
+ gap: 8px;
6366
+ margin-top: 6px;
6367
+ padding-left: 8px;
6368
+ }
6369
+
6370
+ .member-select-btn {
6371
+ background: none;
6372
+ border: 1px solid var(--jupiter-border-color, #ddd);
6373
+ color: var(--jupiter-text-secondary, #666);
6374
+ padding: 2px 8px;
6375
+ border-radius: 3px;
6376
+ font-size: 10px;
6377
+ cursor: pointer;
6378
+ transition: all 0.2s ease;
6379
+ }
6380
+
6381
+ .member-select-btn:hover {
6382
+ background: var(--jupiter-hover-background, #f5f5f5);
6383
+ border-color: var(--jupiter-primary-color, #1976d2);
6384
+ color: var(--jupiter-primary-color, #1976d2);
6385
+ }
6386
+
6387
+ .no-dimensions-message {
6388
+ font-size: 11px;
6389
+ color: var(--jupiter-text-secondary, #999);
6390
+ font-style: italic;
6391
+ padding: 4px 8px;
6392
+ }
6393
+
5912
6394
  .selected-count {
5913
6395
  font-size: 13px;
5914
6396
  color: var(--jupiter-text-secondary, #666);
@@ -6094,6 +6576,9 @@ __decorateClass$1([
6094
6576
  __decorateClass$1([
6095
6577
  n2({ type: String })
6096
6578
  ], JupiterFilterRolesDialog.prototype, "mode", 2);
6579
+ __decorateClass$1([
6580
+ n2({ type: Object })
6581
+ ], JupiterFilterRolesDialog.prototype, "hypercubeData", 2);
6097
6582
  __decorateClass$1([
6098
6583
  r()
6099
6584
  ], JupiterFilterRolesDialog.prototype, "_tempSelectedRoles", 2);
@@ -6178,6 +6663,7 @@ let JupiterDynamicForm = class extends LitElement {
6178
6663
  this._sidePanelCollapsed = false;
6179
6664
  this._adminRoleConfigs = {};
6180
6665
  this._skipDraftLoading = false;
6666
+ this._skipPeriodPreferencesRestore = false;
6181
6667
  }
6182
6668
  connectedCallback() {
6183
6669
  super.connectedCallback();
@@ -6567,38 +7053,37 @@ let JupiterDynamicForm = class extends LitElement {
6567
7053
  _handleRoleFilterApply(event) {
6568
7054
  const { selectedRoleIds, periodPreferences } = event.detail;
6569
7055
  this._selectedRoleIds = selectedRoleIds;
6570
- const preferencesChanged = JSON.stringify(this._periodPreferences) !== JSON.stringify(periodPreferences);
6571
- if (preferencesChanged) {
6572
- this._periodPreferences = periodPreferences;
6573
- console.log("📊 Period preferences updated:", this._periodPreferences);
6574
- console.log("💾 Capturing current form data before reinitialization...");
6575
- const currentFormData = this._generateSubmissionData();
6576
- const currentMetadata = this._draftStorageService.createMetadataSnapshot(
6577
- this.periodStartDate,
6578
- this.periodEndDate,
6579
- this.language,
6580
- this._selectedRoleIds,
6581
- // Enhanced structure with roleURI and order
6582
- this._allSections,
6583
- this._typedMemberData,
6584
- this._periodPreferences,
6585
- this._periodData,
6586
- this._unitData
6587
- );
6588
- this._draftStorageService.saveDraft(currentFormData, currentMetadata);
6589
- console.log("✅ Current form data saved to draft storage");
6590
- this._skipDraftLoading = true;
6591
- this._initializeForm();
6592
- this._skipDraftLoading = false;
6593
- console.log("📥 Restoring form data from draft after reinitialization...");
6594
- this._loadDraftIfExists().then(() => {
6595
- console.log(" Form data restored successfully after reinitialization");
6596
- }).catch((error2) => {
6597
- console.error(" Error restoring form data after reinitialization:", error2);
6598
- });
6599
- } else {
6600
- this._applyRoleFilter();
6601
- }
7056
+ this._periodPreferences = periodPreferences;
7057
+ console.log("🎯 Filter apply triggered - always reinitializing form");
7058
+ console.log("📊 New period preferences (including dimension selections):", this._periodPreferences);
7059
+ console.log("💾 Capturing current form data before reinitialization...");
7060
+ const currentFormData = this._generateSubmissionData();
7061
+ const currentMetadata = this._draftStorageService.createMetadataSnapshot(
7062
+ this.periodStartDate,
7063
+ this.periodEndDate,
7064
+ this.language,
7065
+ this._selectedRoleIds,
7066
+ // Enhanced structure with roleURI and order
7067
+ this._allSections,
7068
+ this._typedMemberData,
7069
+ this._periodPreferences,
7070
+ this._periodData,
7071
+ this._unitData
7072
+ );
7073
+ this._draftStorageService.saveDraft(currentFormData, currentMetadata);
7074
+ console.log("✅ Current form data saved to draft storage with NEW preferences");
7075
+ this._skipPeriodPreferencesRestore = true;
7076
+ this._skipDraftLoading = true;
7077
+ console.log("🔄 Reinitializing form with new filter settings...");
7078
+ this._initializeForm();
7079
+ this._skipDraftLoading = false;
7080
+ this._skipPeriodPreferencesRestore = false;
7081
+ console.log("📥 Restoring form data from draft after reinitialization...");
7082
+ this._loadDraftIfExists().then(() => {
7083
+ console.log(" Form data restored successfully after reinitialization");
7084
+ }).catch((error2) => {
7085
+ console.error("❌ Error restoring form data after reinitialization:", error2);
7086
+ });
6602
7087
  this._showFilterDialog = false;
6603
7088
  const roleCount = Array.isArray(this._selectedRoleIds) && this._selectedRoleIds.length > 0 ? typeof this._selectedRoleIds[0] === "string" ? this._selectedRoleIds.length : this._selectedRoleIds.length : 0;
6604
7089
  console.log(`🎯 Applied role filter: ${roleCount}/${this._allSections.length} roles selected`);
@@ -6614,6 +7099,35 @@ let JupiterDynamicForm = class extends LitElement {
6614
7099
  bubbles: true
6615
7100
  }));
6616
7101
  }
7102
+ /**
7103
+ * Check if dimension selections have changed for any role
7104
+ */
7105
+ _haveDimensionSelectionsChanged(newPeriodPreferences) {
7106
+ var _a;
7107
+ const allRoleIds = /* @__PURE__ */ new Set([
7108
+ ...Object.keys(this._periodPreferences || {}),
7109
+ ...Object.keys(newPeriodPreferences || {})
7110
+ ]);
7111
+ for (const roleId of allRoleIds) {
7112
+ const oldPrefs = (_a = this._periodPreferences) == null ? void 0 : _a[roleId];
7113
+ const newPrefs = newPeriodPreferences == null ? void 0 : newPeriodPreferences[roleId];
7114
+ const oldDimensions = (oldPrefs == null ? void 0 : oldPrefs.dimensionSelections) || [];
7115
+ const newDimensions = (newPrefs == null ? void 0 : newPrefs.dimensionSelections) || [];
7116
+ const oldDimensionsStr = JSON.stringify(
7117
+ oldDimensions.sort((a2, b2) => a2.dimensionId.localeCompare(b2.dimensionId))
7118
+ );
7119
+ const newDimensionsStr = JSON.stringify(
7120
+ newDimensions.sort((a2, b2) => a2.dimensionId.localeCompare(b2.dimensionId))
7121
+ );
7122
+ if (oldDimensionsStr !== newDimensionsStr) {
7123
+ console.log(`🔍 Dimension selection changed for role: ${roleId}`);
7124
+ console.log(" Old:", oldDimensions);
7125
+ console.log(" New:", newDimensions);
7126
+ return true;
7127
+ }
7128
+ }
7129
+ return false;
7130
+ }
6617
7131
  _validateForm() {
6618
7132
  var _a;
6619
7133
  const errors = [];
@@ -7442,27 +7956,31 @@ let JupiterDynamicForm = class extends LitElement {
7442
7956
  console.log("🔄 Restored custom field-level unit data:", Object.keys(this._unitData).length, "concepts");
7443
7957
  }
7444
7958
  if (metadata.periodPreferences) {
7445
- this._periodPreferences = metadata.periodPreferences;
7446
- console.log("🔄 Restored period preferences (including previous year settings):", this._periodPreferences);
7447
- if (this.xbrlInput) {
7448
- console.log("🔄 Rebuilding schema with restored period preferences...");
7449
- this._currentSchema = XBRLFormBuilder.buildFormSchema(
7450
- this.xbrlInput,
7451
- this.periodStartDate,
7452
- this.periodEndDate,
7453
- this.language,
7454
- this._periodPreferences
7455
- );
7456
- this._allSections = [...this._currentSchema.sections];
7457
- if (this.financialStatementsTypeAxis && this.financialStatementsTypeAxis.length > 0) {
7458
- this._allSections = this._filterRolesByFinancialStatementsType(this._allSections);
7459
- }
7460
- console.log("✅ Schema rebuilt with restored period preferences");
7461
- console.log("🔄 Applying custom period data to schema fields...");
7462
- this._applyCustomPeriodDataToFields();
7463
- if (metadata.customColumns && metadata.customColumns.length > 0) {
7464
- this._mergeAdditionalCustomColumns(metadata.customColumns);
7465
- console.log(`🔄 Merged ${metadata.customColumns.length} additional custom columns`);
7959
+ if (this._skipPeriodPreferencesRestore) {
7960
+ console.log("⏭️ Skipping period preferences restoration - using new filter selections");
7961
+ } else {
7962
+ this._periodPreferences = metadata.periodPreferences;
7963
+ console.log("🔄 Restored period preferences (including previous year settings):", this._periodPreferences);
7964
+ if (this.xbrlInput) {
7965
+ console.log("🔄 Rebuilding schema with restored period preferences...");
7966
+ this._currentSchema = XBRLFormBuilder.buildFormSchema(
7967
+ this.xbrlInput,
7968
+ this.periodStartDate,
7969
+ this.periodEndDate,
7970
+ this.language,
7971
+ this._periodPreferences
7972
+ );
7973
+ this._allSections = [...this._currentSchema.sections];
7974
+ if (this.financialStatementsTypeAxis && this.financialStatementsTypeAxis.length > 0) {
7975
+ this._allSections = this._filterRolesByFinancialStatementsType(this._allSections);
7976
+ }
7977
+ console.log("✅ Schema rebuilt with restored period preferences");
7978
+ console.log("🔄 Applying custom period data to schema fields...");
7979
+ this._applyCustomPeriodDataToFields();
7980
+ if (metadata.customColumns && metadata.customColumns.length > 0) {
7981
+ this._mergeAdditionalCustomColumns(metadata.customColumns);
7982
+ console.log(`🔄 Merged ${metadata.customColumns.length} additional custom columns`);
7983
+ }
7466
7984
  }
7467
7985
  }
7468
7986
  } else {
@@ -8587,6 +9105,7 @@ let JupiterDynamicForm = class extends LitElement {
8587
9105
  return this._getFormState();
8588
9106
  }
8589
9107
  render() {
9108
+ var _a;
8590
9109
  const errorCount = this._errors.filter((e2) => e2.severity === "error").length;
8591
9110
  const config = this.config || {};
8592
9111
  const showValidationSummary = config.showValidationSummary !== false && errorCount > 0 && this._submitted;
@@ -8654,6 +9173,7 @@ let JupiterDynamicForm = class extends LitElement {
8654
9173
  .availableRoles="${this._allSections}"
8655
9174
  .selectedRoleIds="${this._getRoleIdsArray()}"
8656
9175
  .periodPreferences="${this._periodPreferences}"
9176
+ .hypercubeData="${(_a = this.xbrlInput) == null ? void 0 : _a.hypercubes}"
8657
9177
  .mode="${this.mode}"
8658
9178
  @dialog-cancel="${this._handleFilterDialogCancel}"
8659
9179
  @roles-filter-apply="${this._handleRoleFilterApply}"