jupiter-dynamic-forms 1.6.0 → 1.7.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
@@ -527,13 +527,30 @@ class XBRLFormBuilder {
527
527
  * Create unique concept ID by combining original ID with preferred label suffix
528
528
  * This handles cases where the same concept appears multiple times with different labels
529
529
  */
530
- static createUniqueConceptId(concept) {
530
+ static createUniqueConceptId(concept, sectionId) {
531
+ let baseId = concept.id;
531
532
  if (concept.preferredLabel && concept.preferredLabel.trim() !== "") {
532
533
  const roleMatch = concept.preferredLabel.match(/\/([^\/]+)$/);
533
534
  const roleSuffix = roleMatch ? roleMatch[1] : concept.preferredLabel.replace(/[^a-zA-Z0-9]/g, "_");
534
- return `${concept.id}_${roleSuffix}`;
535
+ baseId = `${concept.id}_${roleSuffix}`;
535
536
  }
536
- return concept.id;
537
+ if (sectionId) {
538
+ const sectionHash = this.createSectionHash(sectionId);
539
+ return `${baseId}__${sectionHash}`;
540
+ }
541
+ return baseId;
542
+ }
543
+ /**
544
+ * Create a short hash from section ID for concept uniqueness
545
+ */
546
+ static createSectionHash(sectionId) {
547
+ let hash = 0;
548
+ for (let i2 = 0; i2 < sectionId.length; i2++) {
549
+ const char = sectionId.charCodeAt(i2);
550
+ hash = (hash << 5) - hash + char;
551
+ hash = hash & hash;
552
+ }
553
+ return Math.abs(hash).toString(36).substr(0, 6);
537
554
  }
538
555
  /**
539
556
  * Build form schema from XBRL input data
@@ -579,11 +596,17 @@ class XBRLFormBuilder {
579
596
  const columns = this.generateDefaultColumnsForRole(role, periodStartDate || "2025-01-01", periodEndDate || "2025-12-31", hypercubeRole, nonAbstractConcepts, periodTypes);
580
597
  const availableColumnIds = columns.map((col) => col.id);
581
598
  console.log(`📋 Available column IDs for role "${role.id}":`, availableColumnIds);
599
+ if (availableColumnIds.some((id) => id.includes("multi_"))) {
600
+ console.log(`🔍 [DEBUG] Multi-dimensional role "${role.role}" - Total columns generated: ${columns.length}`);
601
+ columns.forEach((col, index) => {
602
+ console.log(` Column ${index}: id=${col.id}, title=${col.title}, type=${col.type}`);
603
+ });
604
+ }
582
605
  const roleInfo = { periodTypes, availableColumnIds };
583
606
  const conceptTrees = [];
584
607
  if ((_a = role.presentationLinkbase) == null ? void 0 : _a.concepts) {
585
608
  role.presentationLinkbase.concepts.forEach((concept) => {
586
- const conceptTree = this.buildConceptTree(concept, 0, periodStartDate, periodEndDate, roleInfo);
609
+ const conceptTree = this.buildConceptTree(concept, 0, periodStartDate, periodEndDate, roleInfo, role.id);
587
610
  if (conceptTree) {
588
611
  conceptTrees.push(conceptTree);
589
612
  }
@@ -592,16 +615,20 @@ class XBRLFormBuilder {
592
615
  return {
593
616
  id: role.id,
594
617
  title,
595
- description: ``,
618
+ description: role.description || `Section for ${title}`,
596
619
  concepts: conceptTrees,
597
620
  columns,
598
- expanded: false
621
+ expanded: false,
622
+ metadata: {
623
+ roleURI: role.roleURI,
624
+ originalRole: role.role
625
+ }
599
626
  };
600
627
  }
601
628
  /**
602
629
  * Build concept tree from XBRL presentation concept
603
630
  */
604
- static buildConceptTree(concept, level, periodStartDate, periodEndDate, roleInfo) {
631
+ static buildConceptTree(concept, level, periodStartDate, periodEndDate, roleInfo, sectionId) {
605
632
  const label = this.getPreferredLabel(concept.labels);
606
633
  const fields = [];
607
634
  if (!concept.elementAbstract) {
@@ -645,7 +672,7 @@ class XBRLFormBuilder {
645
672
  const children = [];
646
673
  if (concept.children && concept.children.length > 0) {
647
674
  concept.children.forEach((child) => {
648
- const childTree = this.buildConceptTree(child, level + 1, periodStartDate, periodEndDate, roleInfo);
675
+ const childTree = this.buildConceptTree(child, level + 1, periodStartDate, periodEndDate, roleInfo, sectionId);
649
676
  if (childTree) {
650
677
  children.push(childTree);
651
678
  }
@@ -656,7 +683,7 @@ class XBRLFormBuilder {
656
683
  return null;
657
684
  }
658
685
  return {
659
- id: this.createUniqueConceptId(concept),
686
+ id: this.createUniqueConceptId(concept, sectionId),
660
687
  // Use unique ID for form management
661
688
  originalConceptId: concept.id,
662
689
  // Store original for submission data
@@ -861,7 +888,7 @@ class XBRLFormBuilder {
861
888
  console.log("📅 All concepts are instant type, creating single column");
862
889
  columns.push({
863
890
  id: "instant",
864
- title: `As of ${this.formatDateForDisplay(periodStartDate)}`,
891
+ title: `Current`,
865
892
  description: `Values as of ${periodStartDate}`,
866
893
  type: "base",
867
894
  order: 0,
@@ -871,7 +898,7 @@ class XBRLFormBuilder {
871
898
  console.log("📅 All concepts are duration type, creating single column with period range");
872
899
  columns.push({
873
900
  id: "duration",
874
- title: `${this.formatDateForDisplay(periodStartDate)} / ${this.formatDateForDisplay(periodEndDate)}`,
901
+ title: `Current Period`,
875
902
  description: `Period: ${periodStartDate} to ${periodEndDate}`,
876
903
  type: "base",
877
904
  order: 0,
@@ -881,7 +908,7 @@ class XBRLFormBuilder {
881
908
  console.log("📅 Mixed period types found, creating both duration and instant columns");
882
909
  columns.push({
883
910
  id: "duration",
884
- title: `${this.formatDateForDisplay(periodStartDate)} / ${this.formatDateForDisplay(periodEndDate)}`,
911
+ title: `Current Period`,
885
912
  description: `Period: ${periodStartDate} to ${periodEndDate}`,
886
913
  type: "base",
887
914
  order: 0,
@@ -889,7 +916,7 @@ class XBRLFormBuilder {
889
916
  });
890
917
  columns.push({
891
918
  id: "instant",
892
- title: `As of ${this.formatDateForDisplay(periodStartDate)}`,
919
+ title: `Current`,
893
920
  description: `Values as of ${periodStartDate}`,
894
921
  type: "base",
895
922
  order: 1,
@@ -904,92 +931,172 @@ class XBRLFormBuilder {
904
931
  * Generate columns for single dimension scenarios
905
932
  */
906
933
  static generateSingleDimensionColumns(dimension, periodStartDate, periodEndDate, periodTypes) {
907
- var _a, _b, _c;
908
- if (dimension.typedMember) {
909
- console.log(`📊 Found typed member dimension:`, {
910
- id: dimension.id,
911
- conceptName: dimension.conceptName,
912
- typedMemberId: dimension.typedMember.id
913
- });
914
- const axisLabel2 = ((_a = dimension.labels.find((l2) => l2.role === "http://www.xbrl.org/2003/role/label")) == null ? void 0 : _a.label) || dimension.conceptName;
915
- const typedMemberLabel = dimension.typedMember.id.split("_").pop() || "TypedMember";
934
+ var _a, _b, _c, _d, _e;
935
+ console.log(`📊 Processing single dimension:`, {
936
+ id: dimension.id,
937
+ conceptName: dimension.conceptName,
938
+ hasMembers: !!(dimension.members && Array.isArray(dimension.members)),
939
+ membersCount: ((_a = dimension.members) == null ? void 0 : _a.length) || 0,
940
+ hasTypedMember: !!dimension.typedMember,
941
+ typedMemberId: (_b = dimension.typedMember) == null ? void 0 : _b.id
942
+ });
943
+ if (dimension.typedMember && (!dimension.members || dimension.members.length === 0)) {
944
+ console.log(`🔤 Processing typed dimension: ${dimension.id} with typed member: ${dimension.typedMember.id}`);
945
+ const axisLabel2 = ((_c = dimension.labels.find((l2) => l2.role === "http://www.xbrl.org/2003/role/label")) == null ? void 0 : _c.label) || dimension.conceptName;
916
946
  const dimensionInfo2 = {
917
947
  axisId: dimension.id,
918
948
  axisLabel: axisLabel2,
919
- memberId: dimension.typedMember.id,
920
- memberLabel: typedMemberLabel,
921
- dimensionKey: `${axisLabel2} | ${typedMemberLabel}`,
922
- dimensionIdKey: `${dimension.id} | ${dimension.typedMember.id}`
949
+ typedMemberId: dimension.typedMember.id,
950
+ dimensionKey: `${axisLabel2} | [Typed Input]`,
951
+ dimensionIdKey: `${dimension.id}|[typed]`
923
952
  };
924
- console.log(`📊 Generated typed dimension info:`, dimensionInfo2);
953
+ console.log(`🔤 Generated typed dimension info:`, dimensionInfo2);
925
954
  const columns2 = [];
926
955
  if (periodTypes.size === 0) {
927
- const column = {
928
- id: "default",
929
- title: dimensionInfo2.memberLabel,
930
- description: "Default typed dimension column",
956
+ columns2.push({
957
+ id: "typed-default",
958
+ title: axisLabel2,
959
+ description: "Typed dimension input column",
931
960
  type: "dimension",
932
961
  dimensionData: {
933
- dimensionId: "default",
962
+ dimensionId: "typed-default",
934
963
  axisId: dimensionInfo2.axisId,
935
- memberId: dimensionInfo2.memberId,
936
- memberValue: dimensionInfo2.memberLabel,
964
+ memberId: "[typed]",
965
+ memberValue: "Typed Input",
966
+ memberLabel: "Typed Input",
967
+ axis: dimensionInfo2.axisLabel,
937
968
  axisLabel: dimensionInfo2.axisLabel,
938
- memberLabel: dimensionInfo2.memberLabel,
939
- isTypedMember: true,
940
- dimensionIdKey: dimensionInfo2.dimensionIdKey
969
+ memberKey: dimensionInfo2.dimensionKey,
970
+ dimensionIdKey: dimensionInfo2.dimensionIdKey,
971
+ hasTypedMembers: true,
972
+ typedMemberId: dimensionInfo2.typedMemberId,
973
+ typedMembers: [{
974
+ axisId: dimensionInfo2.axisId,
975
+ axisLabel: dimensionInfo2.axisLabel,
976
+ typedMemberId: dimensionInfo2.typedMemberId,
977
+ memberLabel: dimensionInfo2.axisLabel
978
+ }]
941
979
  },
942
980
  order: 0,
943
981
  removable: false
944
- };
945
- console.log(`📊 Generated typed member column:`, column);
946
- columns2.push(column);
982
+ });
983
+ } else if (periodTypes.size === 1 && periodTypes.has("instant")) {
984
+ columns2.push({
985
+ id: "typed-instant",
986
+ title: `${axisLabel2} [Typed Input Available]`,
987
+ description: `Typed values as of ${periodStartDate}`,
988
+ type: "dimension",
989
+ dimensionData: {
990
+ dimensionId: "typed-instant",
991
+ axisId: dimensionInfo2.axisId,
992
+ memberId: "[typed]",
993
+ memberValue: "Typed Input",
994
+ memberLabel: "Typed Input",
995
+ axis: dimensionInfo2.axisLabel,
996
+ axisLabel: dimensionInfo2.axisLabel,
997
+ memberKey: dimensionInfo2.dimensionKey,
998
+ dimensionIdKey: dimensionInfo2.dimensionIdKey,
999
+ hasTypedMembers: true,
1000
+ typedMemberId: dimensionInfo2.typedMemberId,
1001
+ typedMembers: [{
1002
+ axisId: dimensionInfo2.axisId,
1003
+ axisLabel: dimensionInfo2.axisLabel,
1004
+ typedMemberId: dimensionInfo2.typedMemberId,
1005
+ memberLabel: dimensionInfo2.axisLabel
1006
+ }]
1007
+ },
1008
+ order: 0,
1009
+ removable: false
1010
+ });
1011
+ } else if (periodTypes.size === 1 && periodTypes.has("duration")) {
1012
+ columns2.push({
1013
+ id: "typed-duration",
1014
+ title: `${axisLabel2} [Typed Input Available]`,
1015
+ description: `Typed values for period ${periodStartDate} to ${periodEndDate}`,
1016
+ type: "dimension",
1017
+ dimensionData: {
1018
+ dimensionId: "typed-duration",
1019
+ axisId: dimensionInfo2.axisId,
1020
+ memberId: "[typed]",
1021
+ memberValue: "Typed Input",
1022
+ memberLabel: "Typed Input",
1023
+ axis: dimensionInfo2.axisLabel,
1024
+ axisLabel: dimensionInfo2.axisLabel,
1025
+ memberKey: dimensionInfo2.dimensionKey,
1026
+ dimensionIdKey: dimensionInfo2.dimensionIdKey,
1027
+ hasTypedMembers: true,
1028
+ typedMemberId: dimensionInfo2.typedMemberId,
1029
+ typedMembers: [{
1030
+ axisId: dimensionInfo2.axisId,
1031
+ axisLabel: dimensionInfo2.axisLabel,
1032
+ typedMemberId: dimensionInfo2.typedMemberId,
1033
+ memberLabel: dimensionInfo2.axisLabel
1034
+ }]
1035
+ },
1036
+ order: 0,
1037
+ removable: false
1038
+ });
947
1039
  } else {
948
- if (periodTypes.has("instant")) {
949
- columns2.push({
950
- id: `instant_${dimensionInfo2.axisId}_${dimensionInfo2.memberId}`,
951
- title: `${dimensionInfo2.memberLabel} (Instant)`,
952
- description: `${periodStartDate}`,
953
- type: "dimension",
954
- dimensionData: {
955
- dimensionId: `instant_${dimensionInfo2.axisId}_${dimensionInfo2.memberId}`,
1040
+ columns2.push({
1041
+ id: "typed-duration",
1042
+ title: `${axisLabel2} [Typed Input Available]`,
1043
+ description: `Typed values for period ${periodStartDate} to ${periodEndDate}`,
1044
+ type: "dimension",
1045
+ dimensionData: {
1046
+ dimensionId: "typed-duration",
1047
+ axisId: dimensionInfo2.axisId,
1048
+ memberId: "[typed]",
1049
+ memberValue: "Typed Input",
1050
+ memberLabel: "Typed Input",
1051
+ axis: dimensionInfo2.axisLabel,
1052
+ axisLabel: dimensionInfo2.axisLabel,
1053
+ memberKey: dimensionInfo2.dimensionKey,
1054
+ dimensionIdKey: dimensionInfo2.dimensionIdKey,
1055
+ hasTypedMembers: true,
1056
+ typedMemberId: dimensionInfo2.typedMemberId,
1057
+ typedMembers: [{
956
1058
  axisId: dimensionInfo2.axisId,
957
- memberId: dimensionInfo2.memberId,
958
- memberValue: dimensionInfo2.memberLabel,
959
1059
  axisLabel: dimensionInfo2.axisLabel,
960
- memberLabel: dimensionInfo2.memberLabel,
961
- isTypedMember: true,
962
- dimensionIdKey: dimensionInfo2.dimensionIdKey
963
- },
964
- order: 0,
965
- removable: false
966
- });
967
- }
968
- if (periodTypes.has("duration")) {
969
- columns2.push({
970
- id: `duration_${dimensionInfo2.axisId}_${dimensionInfo2.memberId}`,
971
- title: `${dimensionInfo2.memberLabel} (Duration)`,
972
- description: `${periodStartDate} / ${periodEndDate}`,
973
- type: "dimension",
974
- dimensionData: {
975
- dimensionId: `duration_${dimensionInfo2.axisId}_${dimensionInfo2.memberId}`,
1060
+ typedMemberId: dimensionInfo2.typedMemberId,
1061
+ memberLabel: dimensionInfo2.axisLabel
1062
+ }]
1063
+ },
1064
+ order: 0,
1065
+ removable: false
1066
+ });
1067
+ columns2.push({
1068
+ id: "typed-instant",
1069
+ title: `${axisLabel2} [Typed Input Available]`,
1070
+ description: `Typed values as of ${periodStartDate}`,
1071
+ type: "dimension",
1072
+ dimensionData: {
1073
+ dimensionId: "typed-instant",
1074
+ axisId: dimensionInfo2.axisId,
1075
+ memberId: "[typed]",
1076
+ memberValue: "Typed Input",
1077
+ memberLabel: "Typed Input",
1078
+ axis: dimensionInfo2.axisLabel,
1079
+ axisLabel: dimensionInfo2.axisLabel,
1080
+ memberKey: dimensionInfo2.dimensionKey,
1081
+ dimensionIdKey: dimensionInfo2.dimensionIdKey,
1082
+ hasTypedMembers: true,
1083
+ typedMemberId: dimensionInfo2.typedMemberId,
1084
+ typedMembers: [{
976
1085
  axisId: dimensionInfo2.axisId,
977
- memberId: dimensionInfo2.memberId,
978
- memberValue: dimensionInfo2.memberLabel,
979
1086
  axisLabel: dimensionInfo2.axisLabel,
980
- memberLabel: dimensionInfo2.memberLabel,
981
- isTypedMember: true,
982
- dimensionIdKey: dimensionInfo2.dimensionIdKey
983
- },
984
- order: 1,
985
- removable: false
986
- });
987
- }
1087
+ typedMemberId: dimensionInfo2.typedMemberId,
1088
+ memberLabel: dimensionInfo2.axisLabel
1089
+ }]
1090
+ },
1091
+ order: 1,
1092
+ removable: false
1093
+ });
988
1094
  }
1095
+ console.log(`🔤 Generated ${columns2.length} typed dimension columns`);
989
1096
  return columns2;
990
1097
  }
991
1098
  if (!dimension.members || !Array.isArray(dimension.members)) {
992
- console.log(`⚠️ Dimension ${dimension.id} has no members defined, skipping column generation`);
1099
+ console.log(`⚠️ Dimension ${dimension.id} has no members defined and no typed member, skipping column generation`);
993
1100
  return [];
994
1101
  }
995
1102
  console.log(`📊 Found single dimension:`, {
@@ -1000,9 +1107,9 @@ class XBRLFormBuilder {
1000
1107
  if (dimension.members.length === 0) {
1001
1108
  return [];
1002
1109
  }
1003
- const axisLabel = ((_b = dimension.labels.find((l2) => l2.role === "http://www.xbrl.org/2003/role/label")) == null ? void 0 : _b.label) || dimension.conceptName;
1110
+ const axisLabel = ((_d = dimension.labels.find((l2) => l2.role === "http://www.xbrl.org/2003/role/label")) == null ? void 0 : _d.label) || dimension.conceptName;
1004
1111
  const firstMember = dimension.members[0];
1005
- const memberLabel = ((_c = firstMember.labels.find((l2) => l2.role === "http://www.xbrl.org/2003/role/label")) == null ? void 0 : _c.label) || firstMember.conceptName;
1112
+ const memberLabel = ((_e = firstMember.labels.find((l2) => l2.role === "http://www.xbrl.org/2003/role/label")) == null ? void 0 : _e.label) || firstMember.conceptName;
1006
1113
  const dimensionInfo = {
1007
1114
  axisId: dimension.id,
1008
1115
  axisLabel,
@@ -1036,7 +1143,7 @@ class XBRLFormBuilder {
1036
1143
  } else if (periodTypes.size === 1 && periodTypes.has("instant")) {
1037
1144
  columns.push({
1038
1145
  id: "instant",
1039
- title: `${dimensionInfo.memberLabel} (${this.formatDateForDisplay(periodStartDate)})`,
1146
+ title: `${dimensionInfo.memberLabel}`,
1040
1147
  description: `Values as of ${periodStartDate}`,
1041
1148
  type: "dimension",
1042
1149
  dimensionData: {
@@ -1056,7 +1163,7 @@ class XBRLFormBuilder {
1056
1163
  } else if (periodTypes.size === 1 && periodTypes.has("duration")) {
1057
1164
  columns.push({
1058
1165
  id: "duration",
1059
- title: `${dimensionInfo.memberLabel} (${this.formatDateForDisplay(periodStartDate)} / ${this.formatDateForDisplay(periodEndDate)})`,
1166
+ title: `${dimensionInfo.memberLabel}`,
1060
1167
  description: `Period: ${periodStartDate} to ${periodEndDate}`,
1061
1168
  type: "dimension",
1062
1169
  dimensionData: {
@@ -1076,7 +1183,7 @@ class XBRLFormBuilder {
1076
1183
  } else {
1077
1184
  columns.push({
1078
1185
  id: "duration",
1079
- title: `${dimensionInfo.memberLabel} (${this.formatDateForDisplay(periodStartDate)} / ${this.formatDateForDisplay(periodEndDate)})`,
1186
+ title: `${dimensionInfo.memberLabel}`,
1080
1187
  description: `Period: ${periodStartDate} to ${periodEndDate}`,
1081
1188
  type: "dimension",
1082
1189
  dimensionData: {
@@ -1095,7 +1202,7 @@ class XBRLFormBuilder {
1095
1202
  });
1096
1203
  columns.push({
1097
1204
  id: "instant",
1098
- title: `${dimensionInfo.memberLabel} (${this.formatDateForDisplay(periodStartDate)})`,
1205
+ title: `${dimensionInfo.memberLabel}`,
1099
1206
  description: `Values as of ${periodStartDate}`,
1100
1207
  type: "dimension",
1101
1208
  dimensionData: {
@@ -1120,15 +1227,30 @@ class XBRLFormBuilder {
1120
1227
  */
1121
1228
  static generateMultiDimensionColumns(dimensions, periodStartDate, periodEndDate, periodTypes) {
1122
1229
  console.log(`📊 Processing ${dimensions.length} dimensions for multi-dimensional columns`);
1230
+ console.log(`🔍 [DEBUG] Input dimensions:`, dimensions.map((d2) => {
1231
+ var _a, _b, _c;
1232
+ return {
1233
+ id: d2.id,
1234
+ label: (_b = (_a = d2.labels) == null ? void 0 : _a.find((l2) => l2.role === "http://www.xbrl.org/2003/role/label")) == null ? void 0 : _b.label,
1235
+ membersCount: ((_c = d2.members) == null ? void 0 : _c.length) || 0,
1236
+ hasTypedMember: !!d2.typedMember
1237
+ };
1238
+ }));
1239
+ const hasTypedMembers = dimensions.some((dimension) => dimension.typedMember);
1240
+ if (hasTypedMembers) {
1241
+ console.log(`🔤 Found typed members in dimensions - will indicate in column headers`);
1242
+ }
1123
1243
  const validDimensions = dimensions.filter((dimension) => {
1124
1244
  if (dimension.typedMember) {
1245
+ console.log(`🔤 Keeping typed dimension: ${dimension.id} with typed member: ${dimension.typedMember.id}`);
1125
1246
  return true;
1126
1247
  }
1127
- if (!dimension.members || !Array.isArray(dimension.members) || dimension.members.length === 0) {
1128
- console.log(`⚠️ Skipping dimension ${dimension.id} - no members defined`);
1129
- return false;
1248
+ if (dimension.members && Array.isArray(dimension.members) && dimension.members.length > 0) {
1249
+ console.log(`📂 Keeping domain dimension: ${dimension.id} with ${dimension.members.length} members`);
1250
+ return true;
1130
1251
  }
1131
- return true;
1252
+ console.log(`⚠️ Skipping dimension ${dimension.id} - no members or typed member defined`);
1253
+ return false;
1132
1254
  });
1133
1255
  if (validDimensions.length === 0) {
1134
1256
  console.log(`⚠️ No valid dimensions with members found, skipping multi-dimensional column generation`);
@@ -1138,17 +1260,14 @@ class XBRLFormBuilder {
1138
1260
  var _a;
1139
1261
  const axisLabel = ((_a = dimension.labels.find((l2) => l2.role === "http://www.xbrl.org/2003/role/label")) == null ? void 0 : _a.label) || dimension.conceptName;
1140
1262
  if (dimension.typedMember) {
1141
- const typedMemberLabel = dimension.typedMember.id.split("_").pop() || "TypedMember";
1142
1263
  return {
1143
1264
  id: dimension.id,
1144
1265
  axisLabel,
1145
- isTypedDimension: true,
1146
- // Flag to track typed dimensions
1266
+ isTyped: true,
1267
+ typedMemberId: dimension.typedMember.id,
1147
1268
  members: [{
1148
- id: dimension.typedMember.id,
1149
- label: typedMemberLabel,
1150
- isTypedMember: true
1151
- // Flag for the member itself
1269
+ id: "[typed]",
1270
+ label: `${axisLabel} [Typed Input Available]`
1152
1271
  }]
1153
1272
  };
1154
1273
  }
@@ -1156,6 +1275,7 @@ class XBRLFormBuilder {
1156
1275
  return {
1157
1276
  id: dimension.id,
1158
1277
  axisLabel,
1278
+ isTyped: false,
1159
1279
  members: allMembers.map((member) => {
1160
1280
  var _a2;
1161
1281
  return {
@@ -1167,32 +1287,63 @@ class XBRLFormBuilder {
1167
1287
  });
1168
1288
  const combinations = this.generateDimensionCombinations(dimensionInfos);
1169
1289
  console.log(`📊 Generated ${combinations.length} dimension combinations`);
1290
+ console.log(`🔍 [DEBUG] Generated combinations:`, combinations.map((combo) => ({
1291
+ memberLabels: combo.map((c2) => c2.memberLabel),
1292
+ axisIds: combo.map((c2) => c2.axisId),
1293
+ memberIds: combo.map((c2) => c2.memberId)
1294
+ })));
1170
1295
  const columns = [];
1171
1296
  combinations.forEach((combination, index) => {
1297
+ var _a, _b;
1172
1298
  const columnTitle = combination.map((c2) => c2.memberLabel).join(" | ");
1173
- const hasTypedMembers = combination.some((c2) => c2.isTypedMember);
1299
+ const typedMembers = combination.filter((c2) => c2.isTyped);
1300
+ const domainMembers = combination.filter((c2) => !c2.isTyped);
1301
+ console.log(`🔍 [Column ${index}] Combination analysis:`, {
1302
+ totalMembers: combination.length,
1303
+ typedMembers: typedMembers.length,
1304
+ domainMembers: domainMembers.length,
1305
+ hasTypedMembers: typedMembers.length > 0,
1306
+ columnTitle,
1307
+ memberLabels: combination.map((c2) => c2.memberLabel),
1308
+ memberIds: combination.map((c2) => c2.memberId)
1309
+ });
1174
1310
  const dimensionData = {
1175
1311
  dimensionId: `multi_${index}`,
1176
1312
  memberValue: columnTitle,
1177
1313
  // Required field
1178
1314
  memberLabel: columnTitle,
1179
1315
  // Required field
1180
- isTypedMember: hasTypedMembers,
1181
- // Flag if any dimension in combination is typed
1182
- combinations: combination.map((c2) => ({
1316
+ combinations: domainMembers.map((c2) => ({
1183
1317
  axisId: c2.axisId,
1184
1318
  axisLabel: c2.axisLabel,
1185
1319
  memberId: c2.memberId,
1186
- memberLabel: c2.memberLabel,
1187
- isTypedMember: c2.isTypedMember || false
1320
+ memberLabel: c2.memberLabel
1188
1321
  })),
1322
+ // Add typed member information for form fields
1323
+ typedMembers: typedMembers.map((c2) => ({
1324
+ axisId: c2.axisId,
1325
+ axisLabel: c2.axisLabel,
1326
+ typedMemberId: c2.typedMemberId,
1327
+ memberLabel: c2.memberLabel
1328
+ })),
1329
+ hasTypedMembers: typedMembers.length > 0,
1189
1330
  memberKey: columnTitle,
1190
- dimensionIdKey: combination.map((c2) => `${c2.axisId}|${c2.memberId}`).join("::")
1331
+ dimensionIdKey: [
1332
+ ...domainMembers.map((c2) => `${c2.axisId}|${c2.memberId}`),
1333
+ ...typedMembers.map((c2) => `${c2.axisId}|[typed]`)
1334
+ ].join("::")
1191
1335
  };
1336
+ console.log(`🔍 [Column ${index}] Final dimension data:`, {
1337
+ dimensionId: dimensionData.dimensionId,
1338
+ memberLabel: dimensionData.memberLabel,
1339
+ dimensionIdKey: dimensionData.dimensionIdKey,
1340
+ combinationsCount: (_a = dimensionData.combinations) == null ? void 0 : _a.length,
1341
+ typedMembersCount: (_b = dimensionData.typedMembers) == null ? void 0 : _b.length
1342
+ });
1192
1343
  if (periodTypes.size === 0 || periodTypes.size === 1 && periodTypes.has("duration")) {
1193
1344
  columns.push({
1194
1345
  id: `duration_${index}`,
1195
- title: `${columnTitle} (${this.formatDateForDisplay(periodStartDate)} / ${this.formatDateForDisplay(periodEndDate)})`,
1346
+ title: `${columnTitle}`,
1196
1347
  description: `Period: ${periodStartDate} to ${periodEndDate}`,
1197
1348
  type: "dimension",
1198
1349
  dimensionData: {
@@ -1205,7 +1356,7 @@ class XBRLFormBuilder {
1205
1356
  } else if (periodTypes.size === 1 && periodTypes.has("instant")) {
1206
1357
  columns.push({
1207
1358
  id: `instant_${index}`,
1208
- title: `${columnTitle} (${this.formatDateForDisplay(periodStartDate)})`,
1359
+ title: `${columnTitle}`,
1209
1360
  description: `Values as of ${periodStartDate}`,
1210
1361
  type: "dimension",
1211
1362
  dimensionData: {
@@ -1218,7 +1369,7 @@ class XBRLFormBuilder {
1218
1369
  } else {
1219
1370
  columns.push({
1220
1371
  id: `duration_${index}`,
1221
- title: `${columnTitle} (${this.formatDateForDisplay(periodStartDate)} / ${this.formatDateForDisplay(periodEndDate)})`,
1372
+ title: `${columnTitle}`,
1222
1373
  description: `Period: ${periodStartDate} to ${periodEndDate}`,
1223
1374
  type: "dimension",
1224
1375
  dimensionData: {
@@ -1230,7 +1381,7 @@ class XBRLFormBuilder {
1230
1381
  });
1231
1382
  columns.push({
1232
1383
  id: `instant_${index}`,
1233
- title: `${columnTitle} (${this.formatDateForDisplay(periodStartDate)})`,
1384
+ title: `${columnTitle}`,
1234
1385
  description: `Values as of ${periodStartDate}`,
1235
1386
  type: "dimension",
1236
1387
  dimensionData: {
@@ -1272,7 +1423,9 @@ class XBRLFormBuilder {
1272
1423
  axisId: dimensionInfos[0].id,
1273
1424
  axisLabel: dimensionInfos[0].axisLabel,
1274
1425
  memberId: member.id,
1275
- memberLabel: member.label
1426
+ memberLabel: member.label,
1427
+ isTyped: dimensionInfos[0].isTyped || false,
1428
+ typedMemberId: dimensionInfos[0].typedMemberId
1276
1429
  }]);
1277
1430
  }
1278
1431
  const [firstDimension, ...restDimensions] = dimensionInfos;
@@ -1284,7 +1437,9 @@ class XBRLFormBuilder {
1284
1437
  axisId: firstDimension.id,
1285
1438
  axisLabel: firstDimension.axisLabel,
1286
1439
  memberId: member.id,
1287
- memberLabel: member.label
1440
+ memberLabel: member.label,
1441
+ isTyped: firstDimension.isTyped || false,
1442
+ typedMemberId: firstDimension.typedMemberId
1288
1443
  }]);
1289
1444
  } else {
1290
1445
  restCombinations.forEach((restCombination) => {
@@ -1293,7 +1448,9 @@ class XBRLFormBuilder {
1293
1448
  axisId: firstDimension.id,
1294
1449
  axisLabel: firstDimension.axisLabel,
1295
1450
  memberId: member.id,
1296
- memberLabel: member.label
1451
+ memberLabel: member.label,
1452
+ isTyped: firstDimension.isTyped || false,
1453
+ typedMemberId: firstDimension.typedMemberId
1297
1454
  },
1298
1455
  ...restCombination
1299
1456
  ]);
@@ -1355,15 +1512,15 @@ class XBRLFormBuilder {
1355
1512
  }];
1356
1513
  }
1357
1514
  }
1358
- var __defProp$4 = Object.defineProperty;
1359
- var __getOwnPropDesc$4 = Object.getOwnPropertyDescriptor;
1360
- var __decorateClass$4 = (decorators, target, key, kind) => {
1361
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$4(target, key) : target;
1515
+ var __defProp$5 = Object.defineProperty;
1516
+ var __getOwnPropDesc$5 = Object.getOwnPropertyDescriptor;
1517
+ var __decorateClass$5 = (decorators, target, key, kind) => {
1518
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$5(target, key) : target;
1362
1519
  for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
1363
1520
  if (decorator = decorators[i2])
1364
1521
  result = (kind ? decorator(target, key, result) : decorator(result)) || result;
1365
1522
  if (kind && result)
1366
- __defProp$4(target, key, result);
1523
+ __defProp$5(target, key, result);
1367
1524
  return result;
1368
1525
  };
1369
1526
  let JupiterFormField = class extends LitElement {
@@ -1668,45 +1825,45 @@ JupiterFormField.styles = css`
1668
1825
  width: auto;
1669
1826
  }
1670
1827
  `;
1671
- __decorateClass$4([
1828
+ __decorateClass$5([
1672
1829
  n2({ type: Object })
1673
1830
  ], JupiterFormField.prototype, "field", 2);
1674
- __decorateClass$4([
1831
+ __decorateClass$5([
1675
1832
  n2({ type: String })
1676
1833
  ], JupiterFormField.prototype, "conceptId", 2);
1677
- __decorateClass$4([
1834
+ __decorateClass$5([
1678
1835
  n2({ type: String })
1679
1836
  ], JupiterFormField.prototype, "columnId", 2);
1680
- __decorateClass$4([
1837
+ __decorateClass$5([
1681
1838
  n2()
1682
1839
  ], JupiterFormField.prototype, "value", 2);
1683
- __decorateClass$4([
1840
+ __decorateClass$5([
1684
1841
  n2({ type: Boolean })
1685
1842
  ], JupiterFormField.prototype, "disabled", 2);
1686
- __decorateClass$4([
1843
+ __decorateClass$5([
1687
1844
  n2({ type: String })
1688
1845
  ], JupiterFormField.prototype, "locale", 2);
1689
- __decorateClass$4([
1846
+ __decorateClass$5([
1690
1847
  n2({ type: Boolean })
1691
1848
  ], JupiterFormField.prototype, "hideLabel", 2);
1692
- __decorateClass$4([
1849
+ __decorateClass$5([
1693
1850
  r()
1694
1851
  ], JupiterFormField.prototype, "_errors", 2);
1695
- __decorateClass$4([
1852
+ __decorateClass$5([
1696
1853
  r()
1697
1854
  ], JupiterFormField.prototype, "_touched", 2);
1698
- JupiterFormField = __decorateClass$4([
1855
+ JupiterFormField = __decorateClass$5([
1699
1856
  t$1("jupiter-form-field")
1700
1857
  ], JupiterFormField);
1701
- var __defProp$3 = Object.defineProperty;
1702
- var __getOwnPropDesc$3 = Object.getOwnPropertyDescriptor;
1703
- var __decorateClass$3 = (decorators, target, key, kind) => {
1704
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$3(target, key) : target;
1858
+ var __defProp$4 = Object.defineProperty;
1859
+ var __getOwnPropDesc$4 = Object.getOwnPropertyDescriptor;
1860
+ var __decorateClass$4 = (decorators, target, key, kind) => {
1861
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$4(target, key) : target;
1705
1862
  for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
1706
1863
  if (decorator = decorators[i2])
1707
1864
  result = (kind ? decorator(target, key, result) : decorator(result)) || result;
1708
1865
  if (kind && result)
1709
- __defProp$3(target, key, result);
1866
+ __defProp$4(target, key, result);
1710
1867
  return result;
1711
1868
  };
1712
1869
  let JupiterConceptTree = class extends LitElement {
@@ -1899,40 +2056,42 @@ JupiterConceptTree.styles = css`
1899
2056
  .children-wrapper {
1900
2057
  display: none;
1901
2058
  }
2059
+
2060
+
1902
2061
  `;
1903
- __decorateClass$3([
2062
+ __decorateClass$4([
1904
2063
  n2({ type: Object })
1905
2064
  ], JupiterConceptTree.prototype, "concept", 2);
1906
- __decorateClass$3([
2065
+ __decorateClass$4([
1907
2066
  n2({ type: Array })
1908
2067
  ], JupiterConceptTree.prototype, "columns", 2);
1909
- __decorateClass$3([
2068
+ __decorateClass$4([
1910
2069
  n2({ type: Object })
1911
2070
  ], JupiterConceptTree.prototype, "formData", 2);
1912
- __decorateClass$3([
2071
+ __decorateClass$4([
1913
2072
  n2({ type: Boolean })
1914
2073
  ], JupiterConceptTree.prototype, "disabled", 2);
1915
- __decorateClass$3([
2074
+ __decorateClass$4([
1916
2075
  n2({ type: String })
1917
2076
  ], JupiterConceptTree.prototype, "locale", 2);
1918
- __decorateClass$3([
2077
+ __decorateClass$4([
1919
2078
  n2({ type: Set })
1920
2079
  ], JupiterConceptTree.prototype, "expandedConcepts", 2);
1921
- __decorateClass$3([
2080
+ __decorateClass$4([
1922
2081
  r()
1923
2082
  ], JupiterConceptTree.prototype, "_expanded", 2);
1924
- JupiterConceptTree = __decorateClass$3([
2083
+ JupiterConceptTree = __decorateClass$4([
1925
2084
  t$1("jupiter-concept-tree")
1926
2085
  ], JupiterConceptTree);
1927
- var __defProp$2 = Object.defineProperty;
1928
- var __getOwnPropDesc$2 = Object.getOwnPropertyDescriptor;
1929
- var __decorateClass$2 = (decorators, target, key, kind) => {
1930
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$2(target, key) : target;
2086
+ var __defProp$3 = Object.defineProperty;
2087
+ var __getOwnPropDesc$3 = Object.getOwnPropertyDescriptor;
2088
+ var __decorateClass$3 = (decorators, target, key, kind) => {
2089
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$3(target, key) : target;
1931
2090
  for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
1932
2091
  if (decorator = decorators[i2])
1933
2092
  result = (kind ? decorator(target, key, result) : decorator(result)) || result;
1934
2093
  if (kind && result)
1935
- __defProp$2(target, key, result);
2094
+ __defProp$3(target, key, result);
1936
2095
  return result;
1937
2096
  };
1938
2097
  let JupiterAddColumnDialog = class extends LitElement {
@@ -1940,15 +2099,20 @@ let JupiterAddColumnDialog = class extends LitElement {
1940
2099
  super(...arguments);
1941
2100
  this.periodType = "duration";
1942
2101
  this.open = false;
2102
+ this.availableDimensions = [];
1943
2103
  this._startDate = "";
1944
2104
  this._endDate = "";
1945
2105
  this._instantDate = "";
1946
2106
  this._selectedType = "duration";
2107
+ this._selectedDimensions = /* @__PURE__ */ new Map();
1947
2108
  }
1948
2109
  updated(changedProperties) {
1949
2110
  if (changedProperties.has("open") && this.open) {
1950
2111
  this._resetForm();
1951
2112
  }
2113
+ if (changedProperties.has("availableDimensions")) {
2114
+ console.log(`🎯 Add Column Dialog received ${this.availableDimensions.length} dimensions:`, this.availableDimensions.map((d2) => d2.axisLabel));
2115
+ }
1952
2116
  }
1953
2117
  connectedCallback() {
1954
2118
  super.connectedCallback();
@@ -1960,13 +2124,6 @@ let JupiterAddColumnDialog = class extends LitElement {
1960
2124
  this._resetForm();
1961
2125
  }
1962
2126
  }
1963
- _resetForm() {
1964
- const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
1965
- this._startDate = today;
1966
- this._endDate = today;
1967
- this._instantDate = today;
1968
- this._selectedType = "duration";
1969
- }
1970
2127
  _handleCancel() {
1971
2128
  this.open = false;
1972
2129
  this.dispatchEvent(new CustomEvent("dialog-cancel", { bubbles: true }));
@@ -1983,6 +2140,9 @@ let JupiterAddColumnDialog = class extends LitElement {
1983
2140
  request.startDate = this._startDate;
1984
2141
  request.endDate = this._endDate;
1985
2142
  }
2143
+ if (this._selectedDimensions.size > 0) {
2144
+ request.selectedDimensions = Array.from(this._selectedDimensions.values());
2145
+ }
1986
2146
  this.dispatchEvent(new CustomEvent("column-add", {
1987
2147
  detail: request,
1988
2148
  bubbles: true
@@ -2014,6 +2174,49 @@ let JupiterAddColumnDialog = class extends LitElement {
2014
2174
  _handleInstantDateChange(e2) {
2015
2175
  this._instantDate = e2.target.value;
2016
2176
  }
2177
+ _handleDimensionToggle(dimensionId, event) {
2178
+ const checkbox = event.target;
2179
+ if (checkbox.checked) {
2180
+ const dimension = this.availableDimensions.find((d2) => d2.id === dimensionId);
2181
+ if (dimension) {
2182
+ const selection = {
2183
+ axisId: dimension.id,
2184
+ axisLabel: dimension.axisLabel,
2185
+ isTyped: !!(dimension.typedMember && (!dimension.members || dimension.members.length === 0))
2186
+ };
2187
+ this._selectedDimensions.set(dimensionId, selection);
2188
+ }
2189
+ } else {
2190
+ this._selectedDimensions.delete(dimensionId);
2191
+ }
2192
+ this.requestUpdate();
2193
+ }
2194
+ _handleMemberSelection(dimensionId, memberId, memberLabel) {
2195
+ const existing = this._selectedDimensions.get(dimensionId);
2196
+ if (existing) {
2197
+ existing.memberId = memberId;
2198
+ existing.memberLabel = memberLabel;
2199
+ this._selectedDimensions.set(dimensionId, existing);
2200
+ this.requestUpdate();
2201
+ }
2202
+ }
2203
+ _handleTypedValueChange(dimensionId, event) {
2204
+ const input = event.target;
2205
+ const existing = this._selectedDimensions.get(dimensionId);
2206
+ if (existing) {
2207
+ existing.typedValue = input.value;
2208
+ this._selectedDimensions.set(dimensionId, existing);
2209
+ }
2210
+ }
2211
+ _resetForm() {
2212
+ const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
2213
+ this._startDate = today;
2214
+ this._endDate = today;
2215
+ this._instantDate = today;
2216
+ this._selectedType = this.periodType === "instant" ? "instant" : "duration";
2217
+ this._selectedDimensions.clear();
2218
+ this.requestUpdate();
2219
+ }
2017
2220
  render() {
2018
2221
  if (!this.open)
2019
2222
  return html``;
@@ -2076,6 +2279,79 @@ let JupiterAddColumnDialog = class extends LitElement {
2076
2279
  />
2077
2280
  </div>
2078
2281
  `}
2282
+
2283
+ <!-- Dimensions Section -->
2284
+ ${this.availableDimensions.length > 0 ? html`
2285
+ <div class="dimensions-section">
2286
+ <h3>Available Dimensions</h3>
2287
+ <p class="form-description">Select dimensions to include in the column. You can choose specific members or enter typed values.</p>
2288
+
2289
+ ${this.availableDimensions.map((dimension) => {
2290
+ const isSelected = this._selectedDimensions.has(dimension.id);
2291
+ const selection = this._selectedDimensions.get(dimension.id);
2292
+ const isTypedDimension = !!(dimension.typedMember && (!dimension.members || dimension.members.length === 0));
2293
+ return html`
2294
+ <div class="dimension-item">
2295
+ <div class="dimension-header">
2296
+ <input
2297
+ type="checkbox"
2298
+ class="dimension-checkbox"
2299
+ .checked="${isSelected}"
2300
+ @change="${(e2) => this._handleDimensionToggle(dimension.id, e2)}"
2301
+ id="dim-${dimension.id}"
2302
+ />
2303
+ <label for="dim-${dimension.id}" class="dimension-label">
2304
+ ${dimension.axisLabel || dimension.conceptName}
2305
+ </label>
2306
+ </div>
2307
+
2308
+ ${isSelected ? html`
2309
+ <div class="dimension-details">
2310
+ ${isTypedDimension ? html`
2311
+ <!-- Typed Dimension Input -->
2312
+ <div class="member-selection">
2313
+ <label>Enter value for ${dimension.conceptName}:</label>
2314
+ <input
2315
+ type="text"
2316
+ class="typed-input"
2317
+ .value="${(selection == null ? void 0 : selection.typedValue) || ""}"
2318
+ @input="${(e2) => this._handleTypedValueChange(dimension.id, e2)}"
2319
+ placeholder="Enter value..."
2320
+ />
2321
+ </div>
2322
+ ` : html`
2323
+ <!-- Domain Members Selection -->
2324
+ ${dimension.members && dimension.members.length > 0 ? html`
2325
+ <div class="member-selection">
2326
+ <label>Select member:</label>
2327
+ <div class="member-list">
2328
+ ${dimension.members.map((member) => html`
2329
+ <div class="member-option">
2330
+ <input
2331
+ type="radio"
2332
+ name="member-${dimension.id}"
2333
+ .checked="${(selection == null ? void 0 : selection.memberId) === member.id}"
2334
+ @change="${() => this._handleMemberSelection(dimension.id, member.id, member.label)}"
2335
+ id="member-${dimension.id}-${member.id}"
2336
+ />
2337
+ <label for="member-${dimension.id}-${member.id}">
2338
+ ${member.label}
2339
+ </label>
2340
+ </div>
2341
+ `)}
2342
+ </div>
2343
+ </div>
2344
+ ` : html`
2345
+ <p class="form-description">No members available for this dimension</p>
2346
+ `}
2347
+ `}
2348
+ </div>
2349
+ ` : ""}
2350
+ </div>
2351
+ `;
2352
+ })}
2353
+ </div>
2354
+ ` : ""}
2079
2355
  </div>
2080
2356
 
2081
2357
  <div class="dialog-actions">
@@ -2229,37 +2505,145 @@ JupiterAddColumnDialog.styles = css`
2229
2505
  background: var(--jupiter-disabled-background, #ccc);
2230
2506
  cursor: not-allowed;
2231
2507
  }
2508
+
2509
+ /* Dimension Selection Styles */
2510
+ .dimensions-section {
2511
+ margin-top: 20px;
2512
+ padding-top: 20px;
2513
+ border-top: 1px solid var(--jupiter-border-color, #ddd);
2514
+ }
2515
+
2516
+ .dimensions-section h3 {
2517
+ margin: 0 0 16px 0;
2518
+ font-size: 16px;
2519
+ font-weight: 500;
2520
+ color: var(--jupiter-text-primary, #333);
2521
+ }
2522
+
2523
+ .dimension-item {
2524
+ margin-bottom: 16px;
2525
+ padding: 16px;
2526
+ border: 1px solid var(--jupiter-border-color, #ddd);
2527
+ border-radius: 4px;
2528
+ background: var(--jupiter-card-background, #fafafa);
2529
+ }
2530
+
2531
+ .dimension-header {
2532
+ display: flex;
2533
+ align-items: center;
2534
+ gap: 12px;
2535
+ margin-bottom: 12px;
2536
+ }
2537
+
2538
+ .dimension-checkbox {
2539
+ margin: 0;
2540
+ }
2541
+
2542
+ .dimension-label {
2543
+ font-weight: 500;
2544
+ color: var(--jupiter-text-primary, #333);
2545
+ flex: 1;
2546
+ }
2547
+
2548
+ .dimension-details {
2549
+ margin-left: 24px;
2550
+ }
2551
+
2552
+ .member-selection {
2553
+ margin-top: 12px;
2554
+ }
2555
+
2556
+ .member-selection label {
2557
+ display: block;
2558
+ margin-bottom: 4px;
2559
+ font-size: 13px;
2560
+ color: var(--jupiter-text-secondary, #666);
2561
+ }
2562
+
2563
+ .typed-input {
2564
+ width: 100%;
2565
+ padding: 8px 12px;
2566
+ border: 1px solid var(--jupiter-border-color, #ddd);
2567
+ border-radius: 4px;
2568
+ font-size: 14px;
2569
+ }
2570
+
2571
+ .member-list {
2572
+ max-height: 120px;
2573
+ overflow-y: auto;
2574
+ border: 1px solid var(--jupiter-border-color, #ddd);
2575
+ border-radius: 4px;
2576
+ padding: 8px;
2577
+ }
2578
+
2579
+ .member-option {
2580
+ display: flex;
2581
+ align-items: center;
2582
+ gap: 8px;
2583
+ padding: 4px 0;
2584
+ }
2585
+
2586
+ .member-option input[type="radio"] {
2587
+ margin: 0;
2588
+ }
2589
+
2590
+ .member-option label {
2591
+ margin: 0;
2592
+ font-size: 13px;
2593
+ color: var(--jupiter-text-primary, #333);
2594
+ cursor: pointer;
2595
+ }
2596
+
2597
+ .no-dimensions {
2598
+ text-align: center;
2599
+ color: var(--jupiter-text-secondary, #666);
2600
+ font-style: italic;
2601
+ padding: 20px;
2602
+ }
2603
+
2604
+ .form-description {
2605
+ font-size: 13px;
2606
+ color: var(--jupiter-text-secondary, #666);
2607
+ margin: 0 0 12px 0;
2608
+ line-height: 1.4;
2609
+ }
2232
2610
  `;
2233
- __decorateClass$2([
2611
+ __decorateClass$3([
2234
2612
  n2({ type: String })
2235
2613
  ], JupiterAddColumnDialog.prototype, "periodType", 2);
2236
- __decorateClass$2([
2614
+ __decorateClass$3([
2237
2615
  n2({ type: Boolean })
2238
2616
  ], JupiterAddColumnDialog.prototype, "open", 2);
2239
- __decorateClass$2([
2617
+ __decorateClass$3([
2618
+ n2({ type: Array })
2619
+ ], JupiterAddColumnDialog.prototype, "availableDimensions", 2);
2620
+ __decorateClass$3([
2240
2621
  r()
2241
2622
  ], JupiterAddColumnDialog.prototype, "_startDate", 2);
2242
- __decorateClass$2([
2623
+ __decorateClass$3([
2243
2624
  r()
2244
2625
  ], JupiterAddColumnDialog.prototype, "_endDate", 2);
2245
- __decorateClass$2([
2626
+ __decorateClass$3([
2246
2627
  r()
2247
2628
  ], JupiterAddColumnDialog.prototype, "_instantDate", 2);
2248
- __decorateClass$2([
2629
+ __decorateClass$3([
2249
2630
  r()
2250
2631
  ], JupiterAddColumnDialog.prototype, "_selectedType", 2);
2251
- JupiterAddColumnDialog = __decorateClass$2([
2632
+ __decorateClass$3([
2633
+ r()
2634
+ ], JupiterAddColumnDialog.prototype, "_selectedDimensions", 2);
2635
+ JupiterAddColumnDialog = __decorateClass$3([
2252
2636
  t$1("jupiter-add-column-dialog")
2253
2637
  ], JupiterAddColumnDialog);
2254
- var __defProp$1 = Object.defineProperty;
2255
- var __getOwnPropDesc$1 = Object.getOwnPropertyDescriptor;
2256
- var __decorateClass$1 = (decorators, target, key, kind) => {
2257
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$1(target, key) : target;
2638
+ var __defProp$2 = Object.defineProperty;
2639
+ var __getOwnPropDesc$2 = Object.getOwnPropertyDescriptor;
2640
+ var __decorateClass$2 = (decorators, target, key, kind) => {
2641
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$2(target, key) : target;
2258
2642
  for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
2259
2643
  if (decorator = decorators[i2])
2260
2644
  result = (kind ? decorator(target, key, result) : decorator(result)) || result;
2261
2645
  if (kind && result)
2262
- __defProp$1(target, key, result);
2646
+ __defProp$2(target, key, result);
2263
2647
  return result;
2264
2648
  };
2265
2649
  let JupiterFormSection = class extends LitElement {
@@ -2267,13 +2651,14 @@ let JupiterFormSection = class extends LitElement {
2267
2651
  super(...arguments);
2268
2652
  this.columns = [];
2269
2653
  this.formData = {};
2654
+ this.typedMemberData = {};
2270
2655
  this.disabled = false;
2271
2656
  this.collapsible = true;
2272
2657
  this.locale = "en-US";
2658
+ this.availableDimensions = [];
2273
2659
  this._expanded = true;
2274
2660
  this._showAddColumnDialog = false;
2275
2661
  this._sectionPeriodType = "duration";
2276
- this._typedMemberValues = {};
2277
2662
  this._expandedConcepts = /* @__PURE__ */ new Set();
2278
2663
  }
2279
2664
  connectedCallback() {
@@ -2401,14 +2786,6 @@ let JupiterFormSection = class extends LitElement {
2401
2786
  bubbles: true
2402
2787
  }));
2403
2788
  }
2404
- _handleTypedMemberValueChange(columnId, value) {
2405
- this._typedMemberValues[columnId] = value;
2406
- this.dispatchEvent(new CustomEvent("typed-member-change", {
2407
- detail: { columnId, value, sectionId: this.section.id },
2408
- bubbles: true
2409
- }));
2410
- this.requestUpdate();
2411
- }
2412
2789
  _flattenConcepts(concepts, expanded = /* @__PURE__ */ new Set()) {
2413
2790
  const result = [];
2414
2791
  for (const concept of concepts) {
@@ -2434,6 +2811,23 @@ let JupiterFormSection = class extends LitElement {
2434
2811
  bubbles: true
2435
2812
  }));
2436
2813
  }
2814
+ _getTypedMemberHeaderValue(columnId, axisId) {
2815
+ var _a;
2816
+ return ((_a = this.typedMemberData[columnId]) == null ? void 0 : _a[axisId]) || "";
2817
+ }
2818
+ _handleTypedMemberHeaderChange(event, columnId, axisId) {
2819
+ const target = event.target;
2820
+ const value = target.value;
2821
+ console.log(`🔍 [FormSection] Typed member header change: columnId=${columnId}, axisId=${axisId}, value=${value}`);
2822
+ this.dispatchEvent(new CustomEvent("typed-member-change", {
2823
+ detail: {
2824
+ columnId,
2825
+ axisId,
2826
+ value
2827
+ },
2828
+ bubbles: true
2829
+ }));
2830
+ }
2437
2831
  render() {
2438
2832
  if (!this.section.concepts || this.section.concepts.length === 0) {
2439
2833
  return html`
@@ -2478,32 +2872,43 @@ let JupiterFormSection = class extends LitElement {
2478
2872
  <tr class="header-row">
2479
2873
  <th class="header-cell concept-column">Concept</th>
2480
2874
  ${this.columns.map((column) => {
2481
- var _a;
2875
+ var _a, _b, _c;
2482
2876
  return html`
2483
2877
  <th class="header-cell ${column.removable ? "removable" : ""}">
2484
- ${column.title}
2485
- ${column.description ? html`<div style="font-weight: normal; font-size: 12px; color: var(--jupiter-text-secondary, #666);">${column.description}</div>` : ""}
2486
- ${((_a = column.dimensionData) == null ? void 0 : _a.isTypedMember) ? html`
2487
- <div style="margin-top: 8px;">
2488
- <input
2489
- type="text"
2490
- placeholder="Enter typed member value"
2491
- .value="${this._typedMemberValues[column.id] || ""}"
2492
- @input="${(e2) => this._handleTypedMemberValueChange(column.id, e2.target.value)}"
2493
- style="width: 100%; padding: 4px; border: 1px solid #ccc; border-radius: 3px; font-size: 12px;"
2494
- />
2878
+ <div class="column-header-content">
2879
+ <div class="column-title">
2880
+ ${column.title}
2881
+ ${column.description ? html`<div style="font-weight: normal; font-size: 12px; color: var(--jupiter-text-secondary, #666);">${column.description}</div>` : ""}
2495
2882
  </div>
2496
- ` : ""}
2497
- ${column.removable ? html`
2498
- <button
2499
- class="remove-column-btn"
2500
- @click="${(e2) => {
2883
+
2884
+ <!-- Typed member input fields in column header -->
2885
+ ${((_a = column.dimensionData) == null ? void 0 : _a.hasTypedMembers) ? html`
2886
+ <div class="typed-members-header">
2887
+ ${(_c = (_b = column.dimensionData) == null ? void 0 : _b.typedMembers) == null ? void 0 : _c.map((typedMember) => html`
2888
+ <div class="typed-member-header-input">
2889
+ <input
2890
+ type="text"
2891
+ class="typed-member-header-field"
2892
+ placeholder="Enter ${typedMember.axisLabel}"
2893
+ .value="${this._getTypedMemberHeaderValue(column.id, typedMember.axisId)}"
2894
+ @input="${(e2) => this._handleTypedMemberHeaderChange(e2, column.id, typedMember.axisId)}"
2895
+ />
2896
+ </div>
2897
+ `)}
2898
+ </div>
2899
+ ` : ""}
2900
+
2901
+ ${column.removable ? html`
2902
+ <button
2903
+ class="remove-column-btn"
2904
+ @click="${(e2) => {
2501
2905
  e2.stopPropagation();
2502
2906
  this._handleRemoveColumn(column.id);
2503
2907
  }}"
2504
- title="Remove column"
2505
- >×</button>
2506
- ` : ""}
2908
+ title="Remove column"
2909
+ >×</button>
2910
+ ` : ""}
2911
+ </div>
2507
2912
  </th>
2508
2913
  `;
2509
2914
  })}
@@ -2541,6 +2946,7 @@ let JupiterFormSection = class extends LitElement {
2541
2946
  <jupiter-add-column-dialog
2542
2947
  .periodType="${this._sectionPeriodType}"
2543
2948
  ?open="${this._showAddColumnDialog}"
2949
+ .availableDimensions="${this.availableDimensions}"
2544
2950
  @dialog-cancel="${this._handleDialogCancel}"
2545
2951
  @column-add="${this._handleColumnAdd}"
2546
2952
  ></jupiter-add-column-dialog>
@@ -2686,68 +3092,729 @@ JupiterFormSection.styles = css`
2686
3092
  justify-content: center;
2687
3093
  }
2688
3094
 
2689
- .remove-column-btn:hover {
2690
- background: var(--jupiter-error-color-dark, #b71c1c);
3095
+ .remove-column-btn:hover {
3096
+ background: var(--jupiter-error-color-dark, #b71c1c);
3097
+ }
3098
+
3099
+ .add-column-btn {
3100
+ background: var(--jupiter-primary-color, #667eea);
3101
+ color: white;
3102
+ border: none;
3103
+ padding: 8px 16px;
3104
+ border-radius: 4px;
3105
+ cursor: pointer;
3106
+ font-size: 12px;
3107
+ margin: 8px;
3108
+ }
3109
+
3110
+ .add-column-btn:hover {
3111
+ background: var(--jupiter-primary-color-dark, #5a6fd8);
3112
+ }
3113
+
3114
+ /* Column header content styling */
3115
+ .column-header-content {
3116
+ display: flex;
3117
+ flex-direction: column;
3118
+ gap: 8px;
3119
+ align-items: center;
3120
+ }
3121
+
3122
+ .column-title {
3123
+ text-align: center;
3124
+ }
3125
+
3126
+ /* Typed member header input styles */
3127
+ .typed-members-header {
3128
+ display: flex;
3129
+ flex-direction: column;
3130
+ gap: 4px;
3131
+ width: 100%;
3132
+ padding: 8px;
3133
+ background: var(--jupiter-typed-member-header-background, #f8f9fa);
3134
+ border-radius: 4px;
3135
+ border: 1px solid var(--jupiter-border-color, #e0e0e0);
3136
+ }
3137
+
3138
+ .typed-member-header-input {
3139
+ display: flex;
3140
+ flex-direction: column;
3141
+ gap: 2px;
3142
+ }
3143
+
3144
+ .typed-member-header-label {
3145
+ font-size: 11px;
3146
+ font-weight: 500;
3147
+ color: var(--jupiter-text-secondary, #666);
3148
+ text-align: left;
3149
+ }
3150
+
3151
+ .typed-member-header-field {
3152
+ width: 100%;
3153
+ padding: 4px 6px;
3154
+ border: 1px solid var(--jupiter-border-color, #ddd);
3155
+ border-radius: 3px;
3156
+ font-size: 12px;
3157
+ background: var(--jupiter-input-background, #fff);
3158
+ }
3159
+
3160
+ .typed-member-header-field:focus {
3161
+ outline: none;
3162
+ border-color: var(--jupiter-primary-color, #1976d2);
3163
+ box-shadow: 0 0 0 1px var(--jupiter-primary-color, #1976d2);
3164
+ }
3165
+
3166
+ .typed-member-header-field::placeholder {
3167
+ color: var(--jupiter-text-placeholder, #999);
3168
+ font-size: 11px;
3169
+ }
3170
+
3171
+ .empty-section {
3172
+ padding: 24px;
3173
+ text-align: center;
3174
+ color: var(--jupiter-text-secondary, #666);
3175
+ font-style: italic;
3176
+ }
3177
+ `;
3178
+ __decorateClass$2([
3179
+ n2({ type: Object })
3180
+ ], JupiterFormSection.prototype, "section", 2);
3181
+ __decorateClass$2([
3182
+ n2({ type: Array })
3183
+ ], JupiterFormSection.prototype, "columns", 2);
3184
+ __decorateClass$2([
3185
+ n2({ type: Object })
3186
+ ], JupiterFormSection.prototype, "formData", 2);
3187
+ __decorateClass$2([
3188
+ n2({ type: Object })
3189
+ ], JupiterFormSection.prototype, "typedMemberData", 2);
3190
+ __decorateClass$2([
3191
+ n2({ type: Boolean })
3192
+ ], JupiterFormSection.prototype, "disabled", 2);
3193
+ __decorateClass$2([
3194
+ n2({ type: Boolean })
3195
+ ], JupiterFormSection.prototype, "collapsible", 2);
3196
+ __decorateClass$2([
3197
+ n2({ type: String })
3198
+ ], JupiterFormSection.prototype, "locale", 2);
3199
+ __decorateClass$2([
3200
+ n2({ type: Array })
3201
+ ], JupiterFormSection.prototype, "availableDimensions", 2);
3202
+ __decorateClass$2([
3203
+ r()
3204
+ ], JupiterFormSection.prototype, "_expanded", 2);
3205
+ __decorateClass$2([
3206
+ r()
3207
+ ], JupiterFormSection.prototype, "_showAddColumnDialog", 2);
3208
+ __decorateClass$2([
3209
+ r()
3210
+ ], JupiterFormSection.prototype, "_sectionPeriodType", 2);
3211
+ __decorateClass$2([
3212
+ r()
3213
+ ], JupiterFormSection.prototype, "_expandedConcepts", 2);
3214
+ JupiterFormSection = __decorateClass$2([
3215
+ t$1("jupiter-form-section")
3216
+ ], JupiterFormSection);
3217
+ var __defProp$1 = Object.defineProperty;
3218
+ var __getOwnPropDesc$1 = Object.getOwnPropertyDescriptor;
3219
+ var __decorateClass$1 = (decorators, target, key, kind) => {
3220
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$1(target, key) : target;
3221
+ for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
3222
+ if (decorator = decorators[i2])
3223
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
3224
+ if (kind && result)
3225
+ __defProp$1(target, key, result);
3226
+ return result;
3227
+ };
3228
+ let JupiterFilterRolesDialog = class extends LitElement {
3229
+ constructor() {
3230
+ super(...arguments);
3231
+ this.open = false;
3232
+ this.availableRoles = [];
3233
+ this.selectedRoleIds = [];
3234
+ this._tempSelectedRoles = /* @__PURE__ */ new Set();
3235
+ this._searchQuery = "";
3236
+ this._filteredRoles = [];
3237
+ }
3238
+ connectedCallback() {
3239
+ super.connectedCallback();
3240
+ this._initializeTempSelection();
3241
+ }
3242
+ updated(changedProperties) {
3243
+ if (changedProperties.has("selectedRoleIds") || changedProperties.has("open")) {
3244
+ this._initializeTempSelection();
3245
+ }
3246
+ if (changedProperties.has("availableRoles") || changedProperties.has("_searchQuery")) {
3247
+ this._updateFilteredRoles();
3248
+ }
3249
+ }
3250
+ _updateFilteredRoles() {
3251
+ if (!this._searchQuery.trim()) {
3252
+ this._filteredRoles = [...this.availableRoles];
3253
+ return;
3254
+ }
3255
+ const query = this._searchQuery.toLowerCase().trim();
3256
+ this._filteredRoles = this.availableRoles.filter((role) => {
3257
+ var _a;
3258
+ const titleMatch = role.title.toLowerCase().includes(query);
3259
+ const idMatch = role.id.toLowerCase().includes(query);
3260
+ const descriptionMatch = ((_a = role.description) == null ? void 0 : _a.toLowerCase().includes(query)) || false;
3261
+ const uriMatch = this._searchInRoleURI(role, query);
3262
+ return titleMatch || idMatch || descriptionMatch || uriMatch;
3263
+ });
3264
+ }
3265
+ _searchInRoleURI(role, query) {
3266
+ var _a;
3267
+ if ((_a = role.metadata) == null ? void 0 : _a.roleURI) {
3268
+ return role.metadata.roleURI.toLowerCase().includes(query);
3269
+ }
3270
+ const uriPattern = /https?:\/\/[^\s]+/i;
3271
+ const titleHasURI = uriPattern.test(role.title);
3272
+ const idHasURI = uriPattern.test(role.id);
3273
+ if (titleHasURI || idHasURI) {
3274
+ return role.title.toLowerCase().includes(query) || role.id.toLowerCase().includes(query);
3275
+ }
3276
+ if (role.id.includes(".") || role.id.includes("/") || role.id.includes(":")) {
3277
+ return role.id.toLowerCase().includes(query);
3278
+ }
3279
+ return false;
3280
+ }
3281
+ _handleSearchInput(event) {
3282
+ const input = event.target;
3283
+ this._searchQuery = input.value;
3284
+ }
3285
+ _clearSearch() {
3286
+ var _a;
3287
+ this._searchQuery = "";
3288
+ const searchInput = (_a = this.shadowRoot) == null ? void 0 : _a.querySelector(".search-input");
3289
+ if (searchInput) {
3290
+ searchInput.value = "";
3291
+ searchInput.focus();
3292
+ }
3293
+ }
3294
+ _highlightSearchTerm(text) {
3295
+ if (!this._searchQuery.trim()) {
3296
+ return text;
3297
+ }
3298
+ const query = this._searchQuery.trim();
3299
+ const regex = new RegExp(`(${query.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")})`, "gi");
3300
+ return text.replace(regex, "<mark>$1</mark>");
3301
+ }
3302
+ _renderHighlightedText(text) {
3303
+ return text;
3304
+ }
3305
+ _getSelectedFilteredCount() {
3306
+ return this._filteredRoles.filter((role) => this._tempSelectedRoles.has(role.id)).length;
3307
+ }
3308
+ _initializeTempSelection() {
3309
+ this._tempSelectedRoles = new Set(this.selectedRoleIds);
3310
+ }
3311
+ _handleCheckboxChange(event, roleId) {
3312
+ const checkbox = event.target;
3313
+ const newSelection = new Set(this._tempSelectedRoles);
3314
+ if (checkbox.checked) {
3315
+ newSelection.add(roleId);
3316
+ } else {
3317
+ newSelection.delete(roleId);
3318
+ }
3319
+ this._tempSelectedRoles = newSelection;
3320
+ this.requestUpdate();
3321
+ }
3322
+ _selectAll() {
3323
+ const newSelection = new Set(this._tempSelectedRoles);
3324
+ this._filteredRoles.forEach((role) => newSelection.add(role.id));
3325
+ this._tempSelectedRoles = newSelection;
3326
+ this.requestUpdate();
3327
+ }
3328
+ _selectNone() {
3329
+ const newSelection = new Set(this._tempSelectedRoles);
3330
+ this._filteredRoles.forEach((role) => newSelection.delete(role.id));
3331
+ this._tempSelectedRoles = newSelection;
3332
+ this.requestUpdate();
3333
+ }
3334
+ _selectAllGlobal() {
3335
+ this._tempSelectedRoles = new Set(this.availableRoles.map((role) => role.id));
3336
+ this.requestUpdate();
3337
+ }
3338
+ _selectNoneGlobal() {
3339
+ this._tempSelectedRoles = /* @__PURE__ */ new Set();
3340
+ this.requestUpdate();
3341
+ }
3342
+ _resetToOriginal() {
3343
+ this._tempSelectedRoles = new Set(this.selectedRoleIds);
3344
+ this.requestUpdate();
3345
+ }
3346
+ _handleCancel() {
3347
+ this._initializeTempSelection();
3348
+ this.dispatchEvent(new CustomEvent("dialog-cancel", {
3349
+ bubbles: true
3350
+ }));
3351
+ }
3352
+ _handleApply() {
3353
+ const selectedRoles = Array.from(this._tempSelectedRoles);
3354
+ this.dispatchEvent(new CustomEvent("roles-filter-apply", {
3355
+ detail: { selectedRoleIds: selectedRoles },
3356
+ bubbles: true
3357
+ }));
3358
+ }
3359
+ _handleBackdropClick(event) {
3360
+ if (event.target === this) {
3361
+ this._handleCancel();
3362
+ }
3363
+ }
3364
+ render() {
3365
+ const selectedCount = this._tempSelectedRoles.size;
3366
+ const totalCount = this.availableRoles.length;
3367
+ const filteredCount = this._filteredRoles.length;
3368
+ const hasSearchQuery = this._searchQuery.trim().length > 0;
3369
+ return html`
3370
+ <div class="dialog" @click="${(e2) => e2.stopPropagation()}">
3371
+ <!-- Dialog Header -->
3372
+ <div class="dialog-header">
3373
+ <svg class="filter-icon" viewBox="0 0 24 24">
3374
+ <path d="M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z"/>
3375
+ </svg>
3376
+ <h2 class="dialog-title">Filter Roles</h2>
3377
+ <button class="close-button" @click="${this._handleCancel}">×</button>
3378
+ </div>
3379
+
3380
+ <!-- Dialog Content -->
3381
+ <div class="dialog-content">
3382
+ <p class="description">
3383
+ Select the roles you want to display in the form. You can search and choose specific roles
3384
+ to focus on or manage all ${totalCount} available roles.
3385
+ </p>
3386
+
3387
+ <!-- Search Input -->
3388
+ <div class="search-container">
3389
+ <input
3390
+ type="text"
3391
+ class="search-input"
3392
+ placeholder="Search roles by name, ID, or URI..."
3393
+ .value="${this._searchQuery}"
3394
+ @input="${this._handleSearchInput}"
3395
+ />
3396
+ ${this._searchQuery ? html`
3397
+ <button class="clear-search" @click="${this._clearSearch}" title="Clear search">
3398
+ ×
3399
+ </button>
3400
+ ` : html`
3401
+ <svg class="search-icon" viewBox="0 0 24 24">
3402
+ <path d="M15.5 14h-.79l-.28-.27A6.471 6.471 0 0 0 16 9.5 6.5 6.5 0 1 0 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/>
3403
+ </svg>
3404
+ `}
3405
+ </div>
3406
+
3407
+ <!-- Search Results Info -->
3408
+ ${hasSearchQuery ? html`
3409
+ <div class="search-results-info">
3410
+ Showing ${filteredCount} of ${totalCount} roles
3411
+ ${filteredCount !== totalCount ? html`matching "${this._searchQuery}"` : ""}
3412
+ </div>
3413
+ ` : ""}
3414
+
3415
+ <!-- Selection Controls -->
3416
+ <div class="selection-controls">
3417
+ ${hasSearchQuery ? html`
3418
+ <button class="selection-control" @click="${this._selectAll}">
3419
+ Select Filtered (${filteredCount})
3420
+ </button>
3421
+ <button class="selection-control" @click="${this._selectNone}">
3422
+ Deselect Filtered
3423
+ </button>
3424
+ <button class="selection-control" @click="${this._selectAllGlobal}">
3425
+ Select All (${totalCount})
3426
+ </button>
3427
+ <button class="selection-control" @click="${this._selectNoneGlobal}">
3428
+ Deselect All
3429
+ </button>
3430
+ ` : html`
3431
+ <button class="selection-control" @click="${this._selectAll}">
3432
+ Select All
3433
+ </button>
3434
+ <button class="selection-control" @click="${this._selectNone}">
3435
+ Select None
3436
+ </button>
3437
+ `}
3438
+ <button class="selection-control" @click="${this._resetToOriginal}">
3439
+ Reset
3440
+ </button>
3441
+ </div>
3442
+
3443
+ <!-- Roles List -->
3444
+ <div class="roles-list">
3445
+ ${this._filteredRoles.length === 0 ? html`
3446
+ <div class="no-results">
3447
+ ${hasSearchQuery ? html`
3448
+ No roles found matching "${this._searchQuery}".<br>
3449
+ Try a different search term or clear the search.
3450
+ ` : html`
3451
+ No roles available.
3452
+ `}
3453
+ </div>
3454
+ ` : html`
3455
+ ${this._filteredRoles.map((role) => {
3456
+ var _a;
3457
+ const isSelected = this._tempSelectedRoles.has(role.id);
3458
+ return html`
3459
+ <div class="role-item">
3460
+ <input
3461
+ type="checkbox"
3462
+ class="role-checkbox"
3463
+ .checked="${isSelected}"
3464
+ @change="${(e2) => this._handleCheckboxChange(e2, role.id)}"
3465
+ />
3466
+ <div class="role-info">
3467
+ <h4 class="role-title">${role.title}</h4>
3468
+ ${role.description ? html`
3469
+ <p class="role-description">${role.description}</p>
3470
+ ` : ""}
3471
+ ${role.id !== role.title ? html`
3472
+ <p class="role-description">ID: ${role.id}</p>
3473
+ ` : ""}
3474
+ ${((_a = role.metadata) == null ? void 0 : _a.roleURI) ? html`
3475
+ <p class="role-description">URI: ${role.metadata.roleURI}</p>
3476
+ ` : ""}
3477
+ </div>
3478
+ </div>
3479
+ `;
3480
+ })}
3481
+ `}
3482
+ </div>
3483
+
3484
+ <div class="selected-count">
3485
+ ${selectedCount} of ${totalCount} roles selected
3486
+ ${hasSearchQuery && filteredCount !== totalCount ? html`
3487
+ <br><small>(${this._getSelectedFilteredCount()} of ${filteredCount} filtered roles selected)</small>
3488
+ ` : ""}
3489
+ </div>
3490
+ </div>
3491
+
3492
+ <!-- Dialog Actions -->
3493
+ <div class="dialog-actions">
3494
+ <button class="btn-secondary" @click="${this._handleCancel}">
3495
+ Cancel
3496
+ </button>
3497
+ <button
3498
+ class="btn-primary"
3499
+ @click="${this._handleApply}"
3500
+ ?disabled="${selectedCount === 0}"
3501
+ >
3502
+ Apply Filter (${selectedCount})
3503
+ </button>
3504
+ </div>
3505
+ </div>
3506
+ `;
3507
+ }
3508
+ };
3509
+ JupiterFilterRolesDialog.styles = css`
3510
+ :host {
3511
+ position: fixed;
3512
+ top: 0;
3513
+ left: 0;
3514
+ right: 0;
3515
+ bottom: 0;
3516
+ z-index: 10000;
3517
+ display: none;
3518
+ align-items: center;
3519
+ justify-content: center;
3520
+ background: rgba(0, 0, 0, 0.5);
3521
+ font-family: var(--jupiter-font-family, system-ui, -apple-system, sans-serif);
3522
+ }
3523
+
3524
+ :host([open]) {
3525
+ display: flex;
3526
+ }
3527
+
3528
+ .dialog {
3529
+ background: var(--jupiter-background, #fff);
3530
+ border-radius: 8px;
3531
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
3532
+
3533
+ width: 90vw;
3534
+ max-height: 80vh;
3535
+ display: flex;
3536
+ flex-direction: column;
3537
+ overflow: hidden;
3538
+ }
3539
+
3540
+ .dialog-header {
3541
+ padding: 20px 24px 16px;
3542
+ border-bottom: 1px solid var(--jupiter-border-color, #ddd);
3543
+ display: flex;
3544
+ align-items: center;
3545
+ gap: 12px;
3546
+ }
3547
+
3548
+ .dialog-title {
3549
+ font-size: 18px;
3550
+ font-weight: 600;
3551
+ margin: 0;
3552
+ color: var(--jupiter-text-primary, #333);
3553
+ flex: 1;
3554
+ }
3555
+
3556
+ .filter-icon {
3557
+ width: 20px;
3558
+ height: 20px;
3559
+ fill: var(--jupiter-primary-color, #1976d2);
3560
+ }
3561
+
3562
+ .close-button {
3563
+ background: none;
3564
+ border: none;
3565
+ font-size: 24px;
3566
+ cursor: pointer;
3567
+ padding: 4px;
3568
+ color: var(--jupiter-text-secondary, #666);
3569
+ border-radius: 4px;
3570
+ transition: background-color 0.2s ease;
3571
+ }
3572
+
3573
+ .close-button:hover {
3574
+ background: var(--jupiter-hover-background, #f5f5f5);
3575
+ }
3576
+
3577
+ .dialog-content {
3578
+ flex: 1;
3579
+ overflow-y: auto;
3580
+ padding: 20px 24px;
3581
+ }
3582
+
3583
+ .description {
3584
+ color: var(--jupiter-text-secondary, #666);
3585
+ font-size: 14px;
3586
+ margin: 0 0 20px 0;
3587
+ line-height: 1.5;
3588
+ }
3589
+
3590
+ .selection-controls {
3591
+ display: flex;
3592
+ gap: 12px;
3593
+ margin-bottom: 20px;
3594
+ flex-wrap: wrap;
3595
+ }
3596
+
3597
+ .search-container {
3598
+ margin-bottom: 16px;
3599
+ position: relative;
3600
+ }
3601
+
3602
+ .search-input {
3603
+ width: 100%;
3604
+ padding: 10px 40px 10px 12px;
3605
+ border: 1px solid var(--jupiter-border-color, #ddd);
3606
+ border-radius: 4px;
3607
+ font-size: 14px;
3608
+ font-family: inherit;
3609
+ background: var(--jupiter-background, #fff);
3610
+ color: var(--jupiter-text-primary, #333);
3611
+ transition: border-color 0.2s ease;
3612
+ }
3613
+
3614
+ .search-input:focus {
3615
+ outline: none;
3616
+ border-color: var(--jupiter-primary-color, #1976d2);
3617
+ box-shadow: 0 0 0 2px rgba(25, 118, 210, 0.1);
3618
+ }
3619
+
3620
+ .search-input::placeholder {
3621
+ color: var(--jupiter-text-secondary, #666);
3622
+ }
3623
+
3624
+ .search-icon {
3625
+ position: absolute;
3626
+ right: 12px;
3627
+ top: 50%;
3628
+ transform: translateY(-50%);
3629
+ width: 16px;
3630
+ height: 16px;
3631
+ fill: var(--jupiter-text-secondary, #666);
3632
+ pointer-events: none;
3633
+ }
3634
+
3635
+ .clear-search {
3636
+ position: absolute;
3637
+ right: 12px;
3638
+ top: 50%;
3639
+ transform: translateY(-50%);
3640
+ background: none;
3641
+ border: none;
3642
+ cursor: pointer;
3643
+ padding: 2px;
3644
+ border-radius: 2px;
3645
+ color: var(--jupiter-text-secondary, #666);
3646
+ font-size: 16px;
3647
+ line-height: 1;
3648
+ transition: color 0.2s ease;
3649
+ }
3650
+
3651
+ .clear-search:hover {
3652
+ color: var(--jupiter-text-primary, #333);
3653
+ }
3654
+
3655
+ .search-results-info {
3656
+ font-size: 12px;
3657
+ color: var(--jupiter-text-secondary, #666);
3658
+ margin-bottom: 8px;
3659
+ text-align: center;
3660
+ }
3661
+
3662
+ .no-results {
3663
+ text-align: center;
3664
+ padding: 40px 20px;
3665
+ color: var(--jupiter-text-secondary, #666);
3666
+ font-style: italic;
3667
+ }
3668
+
3669
+ mark {
3670
+ background: var(--jupiter-primary-color, #1976d2);
3671
+ color: white;
3672
+ padding: 1px 2px;
3673
+ border-radius: 2px;
3674
+ font-weight: 500;
3675
+ }
3676
+
3677
+ .selection-control {
3678
+ background: none;
3679
+ border: 1px solid var(--jupiter-primary-color, #1976d2);
3680
+ color: var(--jupiter-primary-color, #1976d2);
3681
+ padding: 6px 12px;
3682
+ border-radius: 4px;
3683
+ font-size: 12px;
3684
+ cursor: pointer;
3685
+ transition: all 0.2s ease;
3686
+ }
3687
+
3688
+ .selection-control:hover {
3689
+ background: var(--jupiter-primary-color, #1976d2);
3690
+ color: white;
3691
+ }
3692
+
3693
+ .roles-list {
3694
+ display: flex;
3695
+ flex-direction: column;
3696
+ gap: 8px;
3697
+ max-height: 300px;
3698
+ overflow-y: auto;
3699
+ border: 1px solid var(--jupiter-border-color, #ddd);
3700
+ border-radius: 4px;
3701
+ padding: 12px;
3702
+ }
3703
+
3704
+ .role-item {
3705
+ display: flex;
3706
+ align-items: flex-start;
3707
+ gap: 12px;
3708
+ padding: 8px;
3709
+ border-radius: 4px;
3710
+ transition: background-color 0.2s ease;
3711
+ }
3712
+
3713
+ .role-item:hover {
3714
+ background: var(--jupiter-hover-background, #f5f5f5);
3715
+ }
3716
+
3717
+ .role-checkbox {
3718
+ margin-top: 2px;
3719
+ cursor: pointer;
3720
+ }
3721
+
3722
+ .role-info {
3723
+ flex: 1;
3724
+ min-width: 0;
3725
+ }
3726
+
3727
+ .role-title {
3728
+ font-weight: 500;
3729
+ color: var(--jupiter-text-primary, #333);
3730
+ margin: 0 0 4px 0;
3731
+ word-wrap: break-word;
3732
+ line-height: 1.3;
3733
+ }
3734
+
3735
+ .role-description {
3736
+ font-size: 13px;
3737
+ color: var(--jupiter-text-secondary, #666);
3738
+ margin: 0;
3739
+ line-height: 1.4;
3740
+ word-break: break-all; /* Allow URI breaking */
3741
+ }
3742
+
3743
+ .role-description:last-child {
3744
+ margin-bottom: 4px;
3745
+ }
3746
+
3747
+ .selected-count {
3748
+ font-size: 13px;
3749
+ color: var(--jupiter-text-secondary, #666);
3750
+ margin-top: 16px;
3751
+ text-align: center;
3752
+ }
3753
+
3754
+ .dialog-actions {
3755
+ padding: 16px 24px;
3756
+ border-top: 1px solid var(--jupiter-border-color, #ddd);
3757
+ display: flex;
3758
+ gap: 12px;
3759
+ justify-content: flex-end;
3760
+ background: var(--jupiter-form-actions-background, #f8f9fa);
3761
+ }
3762
+
3763
+ .dialog-actions button {
3764
+ padding: 10px 20px;
3765
+ border: none;
3766
+ border-radius: 4px;
3767
+ font-size: 14px;
3768
+ font-weight: 500;
3769
+ cursor: pointer;
3770
+ transition: background-color 0.2s ease;
3771
+ }
3772
+
3773
+ .btn-primary {
3774
+ background: var(--jupiter-primary-color, #1976d2);
3775
+ color: white;
3776
+ }
3777
+
3778
+ .btn-primary:hover:not(:disabled) {
3779
+ background: var(--jupiter-primary-color-dark, #1565c0);
2691
3780
  }
2692
3781
 
2693
- .add-column-btn {
2694
- background: var(--jupiter-primary-color, #667eea);
2695
- color: white;
2696
- border: none;
2697
- padding: 8px 16px;
2698
- border-radius: 4px;
2699
- cursor: pointer;
2700
- font-size: 12px;
2701
- margin: 8px;
3782
+ .btn-secondary {
3783
+ background: transparent;
3784
+ color: var(--jupiter-text-secondary, #666);
3785
+ border: 1px solid var(--jupiter-border-color, #ddd);
2702
3786
  }
2703
3787
 
2704
- .add-column-btn:hover {
2705
- background: var(--jupiter-primary-color-dark, #5a6fd8);
3788
+ .btn-secondary:hover:not(:disabled) {
3789
+ background: var(--jupiter-hover-background, #f5f5f5);
2706
3790
  }
2707
3791
 
2708
- .empty-section {
2709
- padding: 24px;
2710
- text-align: center;
2711
- color: var(--jupiter-text-secondary, #666);
2712
- font-style: italic;
3792
+ button:disabled {
3793
+ opacity: 0.6;
3794
+ cursor: not-allowed;
2713
3795
  }
2714
3796
  `;
2715
3797
  __decorateClass$1([
2716
- n2({ type: Object })
2717
- ], JupiterFormSection.prototype, "section", 2);
3798
+ n2({ type: Boolean, reflect: true })
3799
+ ], JupiterFilterRolesDialog.prototype, "open", 2);
2718
3800
  __decorateClass$1([
2719
3801
  n2({ type: Array })
2720
- ], JupiterFormSection.prototype, "columns", 2);
2721
- __decorateClass$1([
2722
- n2({ type: Object })
2723
- ], JupiterFormSection.prototype, "formData", 2);
2724
- __decorateClass$1([
2725
- n2({ type: Boolean })
2726
- ], JupiterFormSection.prototype, "disabled", 2);
2727
- __decorateClass$1([
2728
- n2({ type: Boolean })
2729
- ], JupiterFormSection.prototype, "collapsible", 2);
3802
+ ], JupiterFilterRolesDialog.prototype, "availableRoles", 2);
2730
3803
  __decorateClass$1([
2731
- n2({ type: String })
2732
- ], JupiterFormSection.prototype, "locale", 2);
2733
- __decorateClass$1([
2734
- r()
2735
- ], JupiterFormSection.prototype, "_expanded", 2);
2736
- __decorateClass$1([
2737
- r()
2738
- ], JupiterFormSection.prototype, "_showAddColumnDialog", 2);
3804
+ n2({ type: Array })
3805
+ ], JupiterFilterRolesDialog.prototype, "selectedRoleIds", 2);
2739
3806
  __decorateClass$1([
2740
3807
  r()
2741
- ], JupiterFormSection.prototype, "_sectionPeriodType", 2);
3808
+ ], JupiterFilterRolesDialog.prototype, "_tempSelectedRoles", 2);
2742
3809
  __decorateClass$1([
2743
3810
  r()
2744
- ], JupiterFormSection.prototype, "_typedMemberValues", 2);
3811
+ ], JupiterFilterRolesDialog.prototype, "_searchQuery", 2);
2745
3812
  __decorateClass$1([
2746
3813
  r()
2747
- ], JupiterFormSection.prototype, "_expandedConcepts", 2);
2748
- JupiterFormSection = __decorateClass$1([
2749
- t$1("jupiter-form-section")
2750
- ], JupiterFormSection);
3814
+ ], JupiterFilterRolesDialog.prototype, "_filteredRoles", 2);
3815
+ JupiterFilterRolesDialog = __decorateClass$1([
3816
+ t$1("jupiter-filter-roles-dialog")
3817
+ ], JupiterFilterRolesDialog);
2751
3818
  var __defProp = Object.defineProperty;
2752
3819
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
2753
3820
  var __decorateClass = (decorators, target, key, kind) => {
@@ -2769,13 +3836,18 @@ let JupiterDynamicForm = class extends LitElement {
2769
3836
  this.periodStartDate = "2025-01-01";
2770
3837
  this.periodEndDate = "2025-12-31";
2771
3838
  this._formData = {};
3839
+ this._preservedFormData = {};
3840
+ this._typedMemberData = {};
3841
+ this._preservedTypedMemberData = {};
2772
3842
  this._columns = [];
2773
3843
  this._errors = [];
2774
3844
  this._touched = /* @__PURE__ */ new Set();
2775
3845
  this._dirty = false;
2776
3846
  this._valid = true;
2777
3847
  this._submitted = false;
2778
- this._typedMemberValues = {};
3848
+ this._allSections = [];
3849
+ this._selectedRoleIds = [];
3850
+ this._showFilterDialog = false;
2779
3851
  }
2780
3852
  connectedCallback() {
2781
3853
  super.connectedCallback();
@@ -2798,6 +3870,13 @@ let JupiterDynamicForm = class extends LitElement {
2798
3870
  this.periodEndDate
2799
3871
  );
2800
3872
  console.log("✅ Generated schema with sections:", this._currentSchema.sections.length);
3873
+ this._allSections = [...this._currentSchema.sections];
3874
+ if (this._allSections.length > 10 && this._selectedRoleIds.length === 0) {
3875
+ this._selectedRoleIds = this._allSections.slice(0, 10).map((section) => section.id);
3876
+ } else if (this._selectedRoleIds.length === 0) {
3877
+ this._selectedRoleIds = this._allSections.map((section) => section.id);
3878
+ }
3879
+ this._applyRoleFilter();
2801
3880
  this._columns = [
2802
3881
  {
2803
3882
  id: "base",
@@ -2811,13 +3890,19 @@ let JupiterDynamicForm = class extends LitElement {
2811
3890
  } catch (error) {
2812
3891
  console.error("❌ Error building form from XBRL input:", error);
2813
3892
  this._currentSchema = this._getDefaultSchema();
3893
+ this._allSections = [];
3894
+ this._selectedRoleIds = [];
2814
3895
  this._columns = this._getDefaultColumns();
2815
3896
  }
2816
3897
  } else if (this.schema) {
2817
3898
  this._currentSchema = this.schema;
3899
+ this._allSections = [...this.schema.sections];
3900
+ this._selectedRoleIds = this._allSections.map((section) => section.id);
2818
3901
  this._columns = this._getDefaultColumns();
2819
3902
  } else {
2820
3903
  this._currentSchema = this._getDefaultSchema();
3904
+ this._allSections = [];
3905
+ this._selectedRoleIds = [];
2821
3906
  this._columns = this._getDefaultColumns();
2822
3907
  }
2823
3908
  this._formData = { ...this.initialData };
@@ -2847,6 +3932,106 @@ let JupiterDynamicForm = class extends LitElement {
2847
3932
  }
2848
3933
  ];
2849
3934
  }
3935
+ _applyRoleFilter() {
3936
+ if (!this._currentSchema || !this._allSections.length)
3937
+ return;
3938
+ this._preserveDataForHiddenSections();
3939
+ const filteredSections = this._allSections.filter(
3940
+ (section) => this._selectedRoleIds.includes(section.id)
3941
+ );
3942
+ this._restoreDataForVisibleSections(filteredSections);
3943
+ this._currentSchema = {
3944
+ ...this._currentSchema,
3945
+ sections: filteredSections
3946
+ };
3947
+ }
3948
+ _preserveDataForHiddenSections() {
3949
+ var _a;
3950
+ const currentlyVisibleSectionIds = ((_a = this._currentSchema) == null ? void 0 : _a.sections.map((s2) => s2.id)) || [];
3951
+ const sectionsThatWillBeHidden = currentlyVisibleSectionIds.filter(
3952
+ (sectionId) => !this._selectedRoleIds.includes(sectionId)
3953
+ );
3954
+ sectionsThatWillBeHidden.forEach((sectionId) => {
3955
+ const section = this._allSections.find((s2) => s2.id === sectionId);
3956
+ if (section) {
3957
+ this._preserveSectionData(section);
3958
+ }
3959
+ });
3960
+ console.log(`📦 Preserved data for ${sectionsThatWillBeHidden.length} hidden sections:`, sectionsThatWillBeHidden);
3961
+ }
3962
+ _restoreDataForVisibleSections(visibleSections) {
3963
+ visibleSections.forEach((section) => {
3964
+ this._restoreSectionData(section);
3965
+ });
3966
+ console.log(`🔄 Restored data for ${visibleSections.length} visible sections`);
3967
+ }
3968
+ _preserveSectionData(section) {
3969
+ section.concepts.forEach((concept) => {
3970
+ this._preserveConceptData(concept);
3971
+ });
3972
+ }
3973
+ _preserveConceptData(concept) {
3974
+ if (this._formData[concept.id]) {
3975
+ this._preservedFormData[concept.id] = { ...this._formData[concept.id] };
3976
+ console.log(`💾 Preserved form data for concept: ${concept.id}`);
3977
+ }
3978
+ concept.fields.forEach((field) => {
3979
+ if (this._typedMemberData[field.columnId]) {
3980
+ this._preservedTypedMemberData[field.columnId] = { ...this._typedMemberData[field.columnId] };
3981
+ console.log(`💾 Preserved typed data for column: ${field.columnId}`);
3982
+ }
3983
+ });
3984
+ if (concept.children) {
3985
+ concept.children.forEach((child) => {
3986
+ this._preserveConceptData(child);
3987
+ });
3988
+ }
3989
+ }
3990
+ _restoreSectionData(section) {
3991
+ section.concepts.forEach((concept) => {
3992
+ this._restoreConceptData(concept);
3993
+ });
3994
+ }
3995
+ _restoreConceptData(concept) {
3996
+ if (this._preservedFormData[concept.id]) {
3997
+ this._formData[concept.id] = { ...this._preservedFormData[concept.id] };
3998
+ console.log(`🔄 Restored form data for concept: ${concept.id}`);
3999
+ }
4000
+ concept.fields.forEach((field) => {
4001
+ if (this._preservedTypedMemberData[field.columnId]) {
4002
+ this._typedMemberData[field.columnId] = { ...this._preservedTypedMemberData[field.columnId] };
4003
+ console.log(`🔄 Restored typed data for column: ${field.columnId}`);
4004
+ }
4005
+ });
4006
+ if (concept.children) {
4007
+ concept.children.forEach((child) => {
4008
+ this._restoreConceptData(child);
4009
+ });
4010
+ }
4011
+ }
4012
+ _shouldShowFilterButton() {
4013
+ return this._allSections.length > 10;
4014
+ }
4015
+ _handleFilterRolesClick() {
4016
+ this._showFilterDialog = true;
4017
+ }
4018
+ _handleFilterDialogCancel() {
4019
+ this._showFilterDialog = false;
4020
+ }
4021
+ _handleRoleFilterApply(event) {
4022
+ const { selectedRoleIds } = event.detail;
4023
+ this._selectedRoleIds = selectedRoleIds;
4024
+ this._applyRoleFilter();
4025
+ this._showFilterDialog = false;
4026
+ this.dispatchEvent(new CustomEvent("roles-filter-changed", {
4027
+ detail: {
4028
+ selectedRoleIds,
4029
+ totalRoles: this._allSections.length,
4030
+ visibleRoles: selectedRoleIds.length
4031
+ },
4032
+ bubbles: true
4033
+ }));
4034
+ }
2850
4035
  _validateForm() {
2851
4036
  var _a;
2852
4037
  const errors = [];
@@ -2874,11 +4059,13 @@ let JupiterDynamicForm = class extends LitElement {
2874
4059
  }
2875
4060
  _handleFieldChange(event) {
2876
4061
  const { fieldId, conceptId, columnId, value } = event.detail;
2877
- if (!this._formData[conceptId]) {
2878
- this._formData[conceptId] = {};
4062
+ const updatedFormData = { ...this._formData };
4063
+ if (!updatedFormData[conceptId]) {
4064
+ updatedFormData[conceptId] = {};
2879
4065
  }
2880
- const oldValue = this._formData[conceptId][columnId];
2881
- this._formData[conceptId][columnId] = value;
4066
+ const oldValue = updatedFormData[conceptId][columnId];
4067
+ updatedFormData[conceptId] = { ...updatedFormData[conceptId], [columnId]: value };
4068
+ this._formData = updatedFormData;
2882
4069
  this._touched.add(`${conceptId}-${columnId}`);
2883
4070
  this._dirty = true;
2884
4071
  this._validateForm();
@@ -2888,13 +4075,32 @@ let JupiterDynamicForm = class extends LitElement {
2888
4075
  bubbles: true
2889
4076
  }));
2890
4077
  }
4078
+ /**
4079
+ * Generate a unique concept key that includes section context
4080
+ */
4081
+ _generateUniqueConceptKey(sectionId, conceptId) {
4082
+ return `${sectionId}::${conceptId}`;
4083
+ }
4084
+ /**
4085
+ * Extract the original concept ID from a unique concept key
4086
+ */
4087
+ _extractOriginalConceptId(uniqueConceptKey) {
4088
+ const parts = uniqueConceptKey.split("::");
4089
+ return parts.length > 1 ? parts[1] : uniqueConceptKey;
4090
+ }
2891
4091
  _handleTypedMemberChange(event) {
2892
- const { columnId, value, sectionId } = event.detail;
2893
- this._typedMemberValues[columnId] = value;
4092
+ const { columnId, axisId, value } = event.detail;
4093
+ console.log(`🔍 [DynamicForm] Typed member change: columnId=${columnId}, axisId=${axisId}, value=${value}`);
4094
+ const updatedTypedMemberData = { ...this._typedMemberData };
4095
+ if (!updatedTypedMemberData[columnId]) {
4096
+ updatedTypedMemberData[columnId] = {};
4097
+ }
4098
+ updatedTypedMemberData[columnId] = { ...updatedTypedMemberData[columnId], [axisId]: value };
4099
+ this._typedMemberData = updatedTypedMemberData;
2894
4100
  this._dirty = true;
2895
4101
  this.requestUpdate();
2896
4102
  this.dispatchEvent(new CustomEvent("typed-member-change", {
2897
- detail: { columnId, value, sectionId },
4103
+ detail: { columnId, axisId, value },
2898
4104
  bubbles: true
2899
4105
  }));
2900
4106
  }
@@ -2940,66 +4146,125 @@ let JupiterDynamicForm = class extends LitElement {
2940
4146
  const { sectionId, columnRequest } = event.detail;
2941
4147
  this._addColumnFromRequest(columnRequest, sectionId);
2942
4148
  }
4149
+ _getAvailableDimensionsForSection(sectionId) {
4150
+ var _a, _b, _c;
4151
+ console.log(`🔍 Getting dimensions for section: ${sectionId}`);
4152
+ if (!((_b = (_a = this.xbrlInput) == null ? void 0 : _a.hypercubes) == null ? void 0 : _b[0])) {
4153
+ console.log("❌ No hypercubes data available");
4154
+ return [];
4155
+ }
4156
+ console.log(`📊 Available hypercube roles:`, this.xbrlInput.hypercubes[0].roles.map((r2) => r2.roleId));
4157
+ const hypercubeRole = this.xbrlInput.hypercubes[0].roles.find((hr) => hr.roleId === sectionId);
4158
+ if (!((_c = hypercubeRole == null ? void 0 : hypercubeRole.items) == null ? void 0 : _c.length)) {
4159
+ console.log(`❌ No hypercube items found for role: ${sectionId}`);
4160
+ return [];
4161
+ }
4162
+ console.log(`✅ Found hypercube role with ${hypercubeRole.items.length} items`);
4163
+ const availableDimensions = [];
4164
+ hypercubeRole.items.forEach((item) => {
4165
+ if (item.dimensions && item.dimensions.length > 0) {
4166
+ item.dimensions.forEach((dimension) => {
4167
+ var _a2;
4168
+ if (!availableDimensions.find((d2) => d2.id === dimension.id)) {
4169
+ const axisLabel = ((_a2 = dimension.labels.find((l2) => l2.role === "http://www.xbrl.org/2003/role/label")) == null ? void 0 : _a2.label) || dimension.conceptName;
4170
+ const availableDimension = {
4171
+ id: dimension.id,
4172
+ conceptName: dimension.conceptName,
4173
+ axisLabel
4174
+ };
4175
+ if (dimension.members && dimension.members.length > 0) {
4176
+ availableDimension.members = dimension.members.map((member) => {
4177
+ var _a3, _b2;
4178
+ return {
4179
+ id: member.id,
4180
+ label: ((_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 || member.id
4181
+ };
4182
+ });
4183
+ }
4184
+ if (dimension.typedMember) {
4185
+ availableDimension.typedMember = {
4186
+ id: dimension.typedMember.id,
4187
+ dataType: "string"
4188
+ // Default to string for now
4189
+ };
4190
+ }
4191
+ availableDimensions.push(availableDimension);
4192
+ }
4193
+ });
4194
+ }
4195
+ });
4196
+ console.log(`📈 Found ${availableDimensions.length} dimensions for section ${sectionId}:`, availableDimensions.map((d2) => d2.axisLabel));
4197
+ return availableDimensions;
4198
+ }
2943
4199
  _addColumnFromRequest(request, sectionId) {
2944
- var _a, _b, _c, _d, _e, _f;
4200
+ var _a, _b, _c, _d, _e;
2945
4201
  const timestamp = Date.now();
2946
4202
  const newColumnId = `col-${timestamp}`;
2947
4203
  let title = "";
2948
4204
  let description = "";
2949
4205
  if (request.periodType === "instant") {
2950
- title = request.instantDate || "Instant Date";
2951
- description = `Instant period: ${request.instantDate}`;
4206
+ title = "Current";
4207
+ description = `Values as of ${request.instantDate}`;
2952
4208
  } else if (request.periodType === "duration" || request.periodType === "mixed") {
2953
- title = `${request.startDate} / ${request.endDate}`;
2954
- description = `Duration period: ${request.startDate} to ${request.endDate}`;
4209
+ title = "Current Period";
4210
+ description = `Period: ${request.startDate} to ${request.endDate}`;
2955
4211
  }
2956
4212
  let dimensionData = {
2957
4213
  dimensionId: "period",
2958
4214
  memberValue: request.periodType === "instant" ? `instant-${request.instantDate}` : `duration-${request.startDate}-${request.endDate}`,
2959
4215
  memberLabel: title
2960
4216
  };
2961
- if ((_b = (_a = this.xbrlInput) == null ? void 0 : _a.hypercubes) == null ? void 0 : _b[0]) {
2962
- const hypercubeRole = this.xbrlInput.hypercubes[0].roles.find((hr) => hr.roleId === sectionId);
2963
- if (((_c = hypercubeRole == null ? void 0 : hypercubeRole.items) == null ? void 0 : _c.length) === 1) {
2964
- const item = hypercubeRole.items[0];
2965
- if (item.dimensions.length === 1) {
2966
- const dimension = item.dimensions[0];
2967
- if (dimension.typedMember) {
2968
- const axisLabel = ((_d = dimension.labels.find((l2) => l2.role === "http://www.xbrl.org/2003/role/label")) == null ? void 0 : _d.label) || dimension.conceptName;
2969
- const typedMemberLabel = dimension.typedMember.id.split("_").pop() || "TypedMember";
2970
- const periodPart = request.periodType === "instant" ? `(${request.instantDate})` : `(${request.startDate} / ${request.endDate})`;
2971
- title = `${typedMemberLabel} ${periodPart}`;
2972
- dimensionData = {
2973
- dimensionId: newColumnId,
2974
- axisId: dimension.id,
2975
- memberId: dimension.typedMember.id,
2976
- memberValue: typedMemberLabel,
2977
- memberLabel: typedMemberLabel,
2978
- axis: axisLabel,
2979
- axisLabel,
2980
- memberKey: `${axisLabel} | ${typedMemberLabel}`,
2981
- dimensionIdKey: `${dimension.id} | ${dimension.typedMember.id}`,
2982
- isTypedMember: true
2983
- };
2984
- console.log(`📊 Applied typed member dimension to new column: ${dimensionData.memberKey}`);
2985
- } else if (dimension.members && dimension.members.length > 0) {
2986
- const axisLabel = ((_e = dimension.labels.find((l2) => l2.role === "http://www.xbrl.org/2003/role/label")) == null ? void 0 : _e.label) || dimension.conceptName;
2987
- const firstMember = dimension.members[0];
2988
- const memberLabel = ((_f = firstMember.labels.find((l2) => l2.role === "http://www.xbrl.org/2003/role/label")) == null ? void 0 : _f.label) || firstMember.conceptName;
2989
- const periodPart = request.periodType === "instant" ? `(${request.instantDate})` : `(${request.startDate} / ${request.endDate})`;
2990
- title = `${memberLabel} ${periodPart}`;
2991
- dimensionData = {
2992
- dimensionId: newColumnId,
2993
- axisId: dimension.id,
2994
- memberId: firstMember.id,
2995
- memberValue: memberLabel,
2996
- memberLabel,
2997
- axis: axisLabel,
2998
- axisLabel,
2999
- memberKey: `${axisLabel} | ${memberLabel}`,
3000
- dimensionIdKey: `${dimension.id} | ${firstMember.id}`
3001
- };
3002
- console.log(`📊 Applied hypercube dimension to new column: ${dimensionData.memberKey}`);
4217
+ if (request.selectedDimensions && request.selectedDimensions.length > 0) {
4218
+ const dimensionParts = [];
4219
+ const dimensionKeys = [];
4220
+ for (const dimSelection of request.selectedDimensions) {
4221
+ if (dimSelection.isTyped && dimSelection.typedValue) {
4222
+ dimensionParts.push(`${dimSelection.axisLabel}: ${dimSelection.typedValue}`);
4223
+ dimensionKeys.push(`${dimSelection.axisId}|${dimSelection.typedValue}`);
4224
+ } else if (dimSelection.memberId && dimSelection.memberLabel) {
4225
+ dimensionParts.push(dimSelection.memberLabel);
4226
+ dimensionKeys.push(`${dimSelection.axisId}|${dimSelection.memberId}`);
4227
+ }
4228
+ }
4229
+ const periodPart = request.periodType === "instant" ? `(${request.instantDate})` : `(${request.startDate} / ${request.endDate})`;
4230
+ if (dimensionParts.length > 0) {
4231
+ title = `${dimensionParts.join(" | ")} ${periodPart}`;
4232
+ dimensionData = {
4233
+ dimensionId: newColumnId,
4234
+ memberValue: dimensionParts.join(" | "),
4235
+ memberLabel: dimensionParts.join(" | "),
4236
+ memberKey: dimensionParts.join(" | "),
4237
+ dimensionIdKey: dimensionKeys.join("::"),
4238
+ selectedDimensions: request.selectedDimensions
4239
+ };
4240
+ console.log(`📊 Applied selected dimensions to new column: ${dimensionData.memberKey}`);
4241
+ }
4242
+ } else {
4243
+ if ((_b = (_a = this.xbrlInput) == null ? void 0 : _a.hypercubes) == null ? void 0 : _b[0]) {
4244
+ const hypercubeRole = this.xbrlInput.hypercubes[0].roles.find((hr) => hr.roleId === sectionId);
4245
+ if (((_c = hypercubeRole == null ? void 0 : hypercubeRole.items) == null ? void 0 : _c.length) === 1) {
4246
+ const item = hypercubeRole.items[0];
4247
+ if (item.dimensions.length === 1) {
4248
+ const dimension = item.dimensions[0];
4249
+ if (dimension.members && dimension.members.length > 0) {
4250
+ const axisLabel = ((_d = dimension.labels.find((l2) => l2.role === "http://www.xbrl.org/2003/role/label")) == null ? void 0 : _d.label) || dimension.conceptName;
4251
+ const firstMember = dimension.members[0];
4252
+ const memberLabel = ((_e = firstMember.labels.find((l2) => l2.role === "http://www.xbrl.org/2003/role/label")) == null ? void 0 : _e.label) || firstMember.conceptName;
4253
+ const periodPart = request.periodType === "instant" ? `(${request.instantDate})` : `(${request.startDate} / ${request.endDate})`;
4254
+ title = `${memberLabel} ${periodPart}`;
4255
+ dimensionData = {
4256
+ dimensionId: newColumnId,
4257
+ axisId: dimension.id,
4258
+ memberId: firstMember.id,
4259
+ memberValue: memberLabel,
4260
+ memberLabel,
4261
+ axis: axisLabel,
4262
+ axisLabel,
4263
+ memberKey: `${axisLabel} | ${memberLabel}`,
4264
+ dimensionIdKey: `${dimension.id} | ${firstMember.id}`
4265
+ };
4266
+ console.log(`📊 Applied hypercube dimension to new column: ${dimensionData.memberKey}`);
4267
+ }
3003
4268
  }
3004
4269
  }
3005
4270
  }
@@ -3154,9 +4419,27 @@ let JupiterDynamicForm = class extends LitElement {
3154
4419
  }));
3155
4420
  }
3156
4421
  _handleSubmit() {
4422
+ console.log("📝 Form submission started...");
3157
4423
  this._submitted = true;
3158
4424
  this._validateForm();
3159
4425
  const submissionData = this._generateSubmissionData();
4426
+ console.log("📊 Generated submission data:", {
4427
+ formData: this._formData,
4428
+ submissionData,
4429
+ submissionDataCount: submissionData.length,
4430
+ valid: this._valid,
4431
+ errors: this._errors
4432
+ });
4433
+ submissionData.forEach((entry, index) => {
4434
+ console.log(`📋 Submission Entry ${index + 1}:`, {
4435
+ conceptId: entry.conceptId,
4436
+ value: entry.value,
4437
+ period: entry.period,
4438
+ dimension: entry.dimension,
4439
+ typedMembers: entry.typedMembers,
4440
+ hasTypedMembers: !!(entry.typedMembers && Object.keys(entry.typedMembers).length > 0)
4441
+ });
4442
+ });
3160
4443
  this.dispatchEvent(new CustomEvent("form-submit", {
3161
4444
  detail: {
3162
4445
  data: this._formData,
@@ -3166,6 +4449,7 @@ let JupiterDynamicForm = class extends LitElement {
3166
4449
  },
3167
4450
  bubbles: true
3168
4451
  }));
4452
+ console.log("✅ Form submit event dispatched");
3169
4453
  }
3170
4454
  _handleSaveDraft() {
3171
4455
  const draftData = this._generateSubmissionData();
@@ -3187,7 +4471,103 @@ let JupiterDynamicForm = class extends LitElement {
3187
4471
  this._currentSchema.sections.forEach((section) => {
3188
4472
  this._processConceptsForSubmission(section.concepts, submissionData, section);
3189
4473
  });
3190
- return submissionData;
4474
+ this._includePreservedDataInSubmission(submissionData);
4475
+ const uniqueSubmissionData = this._removeDuplicateSubmissions(submissionData);
4476
+ return uniqueSubmissionData;
4477
+ }
4478
+ _includePreservedDataInSubmission(submissionData) {
4479
+ Object.keys(this._preservedFormData).forEach((conceptId) => {
4480
+ const conceptData = this._preservedFormData[conceptId];
4481
+ if (conceptData) {
4482
+ Object.keys(conceptData).forEach((columnId) => {
4483
+ const value = conceptData[columnId];
4484
+ if (value !== void 0 && value !== null && value !== "") {
4485
+ const originalConcept = this._findConceptInAllSections(conceptId);
4486
+ if (originalConcept) {
4487
+ const originalSection = this._findSectionForConcept(conceptId);
4488
+ this._addConceptDataToSubmission(originalConcept, columnId, value, submissionData, originalSection || void 0);
4489
+ }
4490
+ }
4491
+ });
4492
+ }
4493
+ });
4494
+ console.log(`📤 Included preserved data in submission. Total entries: ${submissionData.length}`);
4495
+ }
4496
+ _findConceptInAllSections(conceptId) {
4497
+ for (const section of this._allSections) {
4498
+ const concept = this._findConceptInSection(section.concepts, conceptId);
4499
+ if (concept) {
4500
+ return concept;
4501
+ }
4502
+ }
4503
+ return null;
4504
+ }
4505
+ _findConceptInSection(concepts, conceptId) {
4506
+ for (const concept of concepts) {
4507
+ if (concept.id === conceptId) {
4508
+ return concept;
4509
+ }
4510
+ if (concept.children) {
4511
+ const found = this._findConceptInSection(concept.children, conceptId);
4512
+ if (found) {
4513
+ return found;
4514
+ }
4515
+ }
4516
+ }
4517
+ return null;
4518
+ }
4519
+ _findSectionForConcept(conceptId) {
4520
+ for (const section of this._allSections) {
4521
+ const concept = this._findConceptInSection(section.concepts, conceptId);
4522
+ if (concept) {
4523
+ return section;
4524
+ }
4525
+ }
4526
+ return null;
4527
+ }
4528
+ _addConceptDataToSubmission(concept, columnId, value, submissionData, section) {
4529
+ var _a;
4530
+ const field = concept.fields.find((f2) => f2.columnId === columnId);
4531
+ if (!field)
4532
+ return;
4533
+ const isInstant = concept.periodType === "instant";
4534
+ const entry = {
4535
+ conceptId: concept.originalConceptId || concept.id,
4536
+ value,
4537
+ period: {
4538
+ type: concept.periodType || "duration",
4539
+ ...isInstant ? { date: field.periodStartDate || this.periodStartDate } : {
4540
+ startDate: field.periodStartDate || this.periodStartDate,
4541
+ endDate: field.periodEndDate || this.periodEndDate
4542
+ }
4543
+ }
4544
+ };
4545
+ const column = this._findColumnByIdInAllSections(columnId);
4546
+ if ((_a = column == null ? void 0 : column.dimensionData) == null ? void 0 : _a.memberLabel) {
4547
+ entry.dimension = column.dimensionData.memberLabel;
4548
+ }
4549
+ submissionData.push(entry);
4550
+ }
4551
+ _findColumnByIdInAllSections(columnId) {
4552
+ for (const section of this._allSections) {
4553
+ if (section.columns) {
4554
+ const column = section.columns.find((col) => col.id === columnId);
4555
+ if (column) {
4556
+ return column;
4557
+ }
4558
+ }
4559
+ }
4560
+ return void 0;
4561
+ }
4562
+ _removeDuplicateSubmissions(submissionData) {
4563
+ const uniqueEntries = /* @__PURE__ */ new Map();
4564
+ submissionData.forEach((entry) => {
4565
+ const key = `${entry.conceptId}_${entry.value}_${entry.dimension || "no-dimension"}`;
4566
+ if (!uniqueEntries.has(key)) {
4567
+ uniqueEntries.set(key, entry);
4568
+ }
4569
+ });
4570
+ return Array.from(uniqueEntries.values());
3191
4571
  }
3192
4572
  _findColumnById(columnId) {
3193
4573
  if (!this._currentSchema) {
@@ -3203,22 +4583,114 @@ let JupiterDynamicForm = class extends LitElement {
3203
4583
  }
3204
4584
  return void 0;
3205
4585
  }
4586
+ _findColumnByIdInSection(columnId, section) {
4587
+ if (!(section == null ? void 0 : section.columns)) {
4588
+ return void 0;
4589
+ }
4590
+ return section.columns.find((col) => col.id === columnId);
4591
+ }
4592
+ _getTypedMemberNameForAxis(axisId, section) {
4593
+ var _a, _b, _c, _d;
4594
+ if (!((_b = (_a = this.xbrlInput) == null ? void 0 : _a.hypercubes) == null ? void 0 : _b[0])) {
4595
+ return null;
4596
+ }
4597
+ const sectionRoleId = section == null ? void 0 : section.id;
4598
+ if (!sectionRoleId) {
4599
+ return null;
4600
+ }
4601
+ const hypercube = this.xbrlInput.hypercubes[0];
4602
+ const role = (_c = hypercube.roles) == null ? void 0 : _c.find((r2) => r2.roleId === sectionRoleId);
4603
+ if (!(role == null ? void 0 : role.items)) {
4604
+ return null;
4605
+ }
4606
+ for (const item of role.items) {
4607
+ if (item.dimensions) {
4608
+ const dimension = item.dimensions.find((d2) => d2.id === axisId);
4609
+ if ((_d = dimension == null ? void 0 : dimension.typedMember) == null ? void 0 : _d.id) {
4610
+ return dimension.typedMember.id;
4611
+ }
4612
+ }
4613
+ }
4614
+ return null;
4615
+ }
4616
+ _doesConceptApplyToTypedDimension(concept, section, columnId) {
4617
+ var _a, _b, _c;
4618
+ if (!((_b = (_a = this.xbrlInput) == null ? void 0 : _a.hypercubes) == null ? void 0 : _b[0])) {
4619
+ return false;
4620
+ }
4621
+ const sectionRoleId = section == null ? void 0 : section.id;
4622
+ if (!sectionRoleId) {
4623
+ return false;
4624
+ }
4625
+ const hypercubeRole = this.xbrlInput.hypercubes[0].roles.find((hr) => hr.roleId === sectionRoleId);
4626
+ if (!((_c = hypercubeRole == null ? void 0 : hypercubeRole.items) == null ? void 0 : _c.length)) {
4627
+ return false;
4628
+ }
4629
+ for (const item of hypercubeRole.items) {
4630
+ const conceptIdToCheck = concept.originalConceptId || concept.id;
4631
+ if (item.conceptIds && item.conceptIds.includes(conceptIdToCheck)) {
4632
+ const hasTypedDimensions = item.dimensions.some((dim) => dim.typedMember);
4633
+ console.log(`🔍 [DynamicForm] Concept ${conceptIdToCheck} found in hypercube item. Has typed dimensions:`, hasTypedDimensions);
4634
+ return hasTypedDimensions;
4635
+ }
4636
+ }
4637
+ console.log(`🔍 [DynamicForm] Concept ${concept.originalConceptId || concept.id} not found in any hypercube items for role ${sectionRoleId}`);
4638
+ return false;
4639
+ }
4640
+ /**
4641
+ * Get the specific typed dimensions that apply to a concept in its role
4642
+ */
4643
+ _getApplicableTypedDimensions(concept, section) {
4644
+ var _a, _b, _c;
4645
+ if (!((_b = (_a = this.xbrlInput) == null ? void 0 : _a.hypercubes) == null ? void 0 : _b[0]) || !(section == null ? void 0 : section.id)) {
4646
+ return [];
4647
+ }
4648
+ const hypercubeRole = this.xbrlInput.hypercubes[0].roles.find((hr) => hr.roleId === section.id);
4649
+ if (!((_c = hypercubeRole == null ? void 0 : hypercubeRole.items) == null ? void 0 : _c.length)) {
4650
+ return [];
4651
+ }
4652
+ const conceptIdToCheck = concept.originalConceptId || concept.id;
4653
+ for (const item of hypercubeRole.items) {
4654
+ if (item.conceptIds && item.conceptIds.includes(conceptIdToCheck)) {
4655
+ const typedDimensions = item.dimensions.filter((dim) => dim.typedMember).map((dim) => dim.id);
4656
+ console.log(`🔍 [DynamicForm] Found applicable typed dimensions for concept ${conceptIdToCheck}:`, typedDimensions);
4657
+ return typedDimensions;
4658
+ }
4659
+ }
4660
+ return [];
4661
+ }
3206
4662
  _processConceptsForSubmission(concepts, submissionData, section) {
4663
+ const targetRole = "Toelichting op de geconsolideerde jaarrekening - Financiële vaste activa: Deelnemingen: Volledig geconsolideerd: Specificatie";
4664
+ const sectionTitle = (section == null ? void 0 : section.title) || "Unknown";
3207
4665
  concepts.forEach((concept) => {
4666
+ if (sectionTitle === targetRole) {
4667
+ console.warn(`[DUPLICATE DEBUG] Processing concept ${concept.originalConceptId || concept.id} in target role`);
4668
+ if (concept.fields) {
4669
+ console.warn(`[DUPLICATE DEBUG] Concept has ${concept.fields.length} fields`);
4670
+ concept.fields.forEach((field, index) => {
4671
+ var _a;
4672
+ console.warn(`[DUPLICATE DEBUG] Field ${index}: columnId=${field.columnId}, current value=${(_a = this._formData[concept.id]) == null ? void 0 : _a[field.columnId]}`);
4673
+ });
4674
+ }
4675
+ }
4676
+ if (concept.fields && concept.fields.length > 1) {
4677
+ console.log(`🔍 [DEBUG] Processing concept ${concept.originalConceptId}, fields count: ${concept.fields.length}`);
4678
+ concept.fields.forEach((field, index) => {
4679
+ var _a;
4680
+ console.log(` Field ${index}: columnId=${field.columnId}, value=${(_a = this._formData[concept.id]) == null ? void 0 : _a[field.columnId]}`);
4681
+ });
4682
+ }
3208
4683
  if (concept.fields && concept.fields.length > 0) {
3209
4684
  concept.fields.forEach((field) => {
3210
- var _a, _b, _c, _d;
4685
+ var _a, _b;
3211
4686
  const conceptData = this._formData[concept.id];
3212
4687
  const fieldValue = conceptData == null ? void 0 : conceptData[field.columnId];
3213
4688
  if (fieldValue !== void 0 && fieldValue !== null && fieldValue !== "") {
3214
- const column = this._findColumnById(field.columnId);
3215
- console.log(`🔍 Processing field for concept ${concept.id}:`, {
3216
- fieldColumnId: field.columnId,
3217
- foundColumn: column,
3218
- columnType: column == null ? void 0 : column.type,
3219
- dimensionData: column == null ? void 0 : column.dimensionData,
3220
- isTypedMember: (_a = column == null ? void 0 : column.dimensionData) == null ? void 0 : _a.isTypedMember
3221
- });
4689
+ if (sectionTitle === targetRole) {
4690
+ console.warn(`[DUPLICATE DEBUG] Creating submission entry for concept ${concept.originalConceptId || concept.id}, field columnId=${field.columnId}, value=${fieldValue}`);
4691
+ }
4692
+ const column = this._findColumnByIdInSection(field.columnId, section);
4693
+ console.log(`🔍 [DynamicForm] Processing field for concept ${concept.originalConceptId || concept.id}, field columnId: ${field.columnId}, found column in section ${section == null ? void 0 : section.id}: ${!!column}, column title: ${column == null ? void 0 : column.title}`);
3222
4694
  const submissionEntry = {
3223
4695
  conceptId: concept.id,
3224
4696
  value: fieldValue,
@@ -3232,45 +4704,50 @@ let JupiterDynamicForm = class extends LitElement {
3232
4704
  submissionEntry.period.startDate = field.periodStartDate || this.periodStartDate;
3233
4705
  submissionEntry.period.endDate = field.periodEndDate || this.periodEndDate;
3234
4706
  }
3235
- if ((column == null ? void 0 : column.type) === "dimension" && ((_b = column.dimensionData) == null ? void 0 : _b.dimensionIdKey)) {
3236
- console.log(`✅ Found column dimension data:`, column.dimensionData);
3237
- if (column.dimensionData.isTypedMember) {
3238
- submissionEntry.dimension = column.dimensionData.dimensionIdKey;
3239
- submissionEntry.typedDimension = true;
3240
- submissionEntry.typedMemberValue = this._typedMemberValues[column.id] || "";
3241
- } else {
3242
- submissionEntry.dimension = column.dimensionData.dimensionIdKey;
3243
- }
3244
- } else if ((_c = section == null ? void 0 : section.columns) == null ? void 0 : _c.length) {
3245
- console.log(`🔍 Checking section columns for dimension data:`, {
3246
- sectionId: section.id,
3247
- columnsCount: section.columns.length,
3248
- columns: section.columns.map((col) => {
3249
- var _a2, _b2;
3250
- return {
3251
- id: col.id,
3252
- type: col.type,
3253
- hasDimensionData: !!col.dimensionData,
3254
- dimensionIdKey: (_a2 = col.dimensionData) == null ? void 0 : _a2.dimensionIdKey,
3255
- isTypedMember: (_b2 = col.dimensionData) == null ? void 0 : _b2.isTypedMember
3256
- };
3257
- })
3258
- });
3259
- const sectionDimensionColumn = section.columns.find((col) => {
3260
- var _a2;
3261
- return col.type === "dimension" && ((_a2 = col.dimensionData) == null ? void 0 : _a2.dimensionIdKey);
3262
- });
3263
- if ((_d = sectionDimensionColumn == null ? void 0 : sectionDimensionColumn.dimensionData) == null ? void 0 : _d.dimensionIdKey) {
3264
- console.log(`✅ Found section dimension data:`, sectionDimensionColumn.dimensionData);
3265
- if (sectionDimensionColumn.dimensionData.isTypedMember) {
3266
- submissionEntry.dimension = sectionDimensionColumn.dimensionData.dimensionIdKey;
3267
- submissionEntry.typedDimension = true;
3268
- submissionEntry.typedMemberValue = this._typedMemberValues[sectionDimensionColumn.id] || "";
4707
+ if ((column == null ? void 0 : column.type) === "dimension" && ((_a = column.dimensionData) == null ? void 0 : _a.dimensionIdKey)) {
4708
+ submissionEntry.dimension = column.dimensionData.dimensionIdKey;
4709
+ console.log(`🔍 [DynamicForm] Using dimension key from field's column (${field.columnId}):`, column.dimensionData.dimensionIdKey);
4710
+ } else {
4711
+ console.log(`🔍 [DynamicForm] No dimension data found for field column ${field.columnId}. Column type: ${column == null ? void 0 : column.type}, has dimensionData: ${!!(column == null ? void 0 : column.dimensionData)}`);
4712
+ }
4713
+ if (this._typedMemberData[field.columnId]) {
4714
+ const applicableTypedDimensions = this._getApplicableTypedDimensions(concept, section);
4715
+ console.log(`🔍 [DynamicForm] Concept ${concept.id} applicable typed dimensions:`, applicableTypedDimensions);
4716
+ if (applicableTypedDimensions.length > 0) {
4717
+ const filteredTypedMembers = {};
4718
+ const allTypedMemberData = this._typedMemberData[field.columnId];
4719
+ applicableTypedDimensions.forEach((dimensionId) => {
4720
+ if (allTypedMemberData[dimensionId]) {
4721
+ const memberName = this._getTypedMemberNameForAxis(dimensionId, section);
4722
+ filteredTypedMembers[dimensionId] = {
4723
+ value: allTypedMemberData[dimensionId],
4724
+ memberName: memberName || "Unknown"
4725
+ };
4726
+ }
4727
+ });
4728
+ if (Object.keys(filteredTypedMembers).length > 0) {
4729
+ submissionEntry.typedMembers = filteredTypedMembers;
4730
+ console.log(`🔍 [DynamicForm] Adding filtered typed members to submission:`, filteredTypedMembers);
3269
4731
  } else {
3270
- submissionEntry.dimension = sectionDimensionColumn.dimensionData.dimensionIdKey;
4732
+ console.log(`🔍 [DynamicForm] No typed member values found for applicable dimensions:`, applicableTypedDimensions);
3271
4733
  }
4734
+ } else {
4735
+ console.log(`🔍 [DynamicForm] Skipping typed members for concept ${concept.id} - not applicable to this hypercube`);
4736
+ }
4737
+ } else {
4738
+ console.log(`🔍 [DynamicForm] No typed member data found for column ${field.columnId}. Available columns:`, Object.keys(this._typedMemberData));
4739
+ if (column) {
4740
+ console.log(`🔍 [DynamicForm] Column details:`, {
4741
+ id: column.id,
4742
+ type: column.type,
4743
+ hasTypedMembers: (_b = column.dimensionData) == null ? void 0 : _b.hasTypedMembers,
4744
+ dimensionData: column.dimensionData
4745
+ });
3272
4746
  }
3273
4747
  }
4748
+ if (sectionTitle === targetRole) {
4749
+ console.warn(`[DUPLICATE DEBUG] Final submission entry:`, submissionEntry);
4750
+ }
3274
4751
  submissionData.push(submissionEntry);
3275
4752
  }
3276
4753
  });
@@ -3285,6 +4762,9 @@ let JupiterDynamicForm = class extends LitElement {
3285
4762
  this._touched.clear();
3286
4763
  this._dirty = false;
3287
4764
  this._submitted = false;
4765
+ this._preservedFormData = {};
4766
+ this._preservedTypedMemberData = {};
4767
+ console.log("🔄 Form reset - all data and preserved data cleared");
3288
4768
  this._validateForm();
3289
4769
  this.requestUpdate();
3290
4770
  this.dispatchEvent(new CustomEvent("form-reset", {
@@ -3360,9 +4840,11 @@ let JupiterDynamicForm = class extends LitElement {
3360
4840
  .section="${section}"
3361
4841
  .columns="${section.columns || this._columns}"
3362
4842
  .formData="${this._formData}"
4843
+ .typedMemberData="${this._typedMemberData}"
3363
4844
  .disabled="${this.disabled || this.readonly}"
3364
4845
  .collapsible="${config.collapsibleSections !== false}"
3365
4846
  .locale="${config.locale || "en-US"}"
4847
+ .availableDimensions="${this._getAvailableDimensionsForSection(section.id)}"
3366
4848
  @field-change="${this._handleFieldChange}"
3367
4849
  @typed-member-change="${this._handleTypedMemberChange}"
3368
4850
  @section-expand="${this._handleSectionExpand}"
@@ -3375,6 +4857,21 @@ let JupiterDynamicForm = class extends LitElement {
3375
4857
 
3376
4858
  <!-- Form Actions - Fixed Footer -->
3377
4859
  <div class="form-actions">
4860
+ <!-- Filter Roles Button (shown when more than 10 roles) -->
4861
+ ${this._shouldShowFilterButton() ? html`
4862
+ <button
4863
+ class="filter-roles-button"
4864
+ @click="${this._handleFilterRolesClick}"
4865
+ ?disabled="${this.disabled || this.readonly}"
4866
+ >
4867
+ <svg class="filter-icon" viewBox="0 0 24 24">
4868
+ <path d="M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z"/>
4869
+ </svg>
4870
+ Filter Roles
4871
+ <span class="roles-count">${this._selectedRoleIds.length}/${this._allSections.length}</span>
4872
+ </button>
4873
+ ` : ""}
4874
+
3378
4875
  <button
3379
4876
  class="btn-secondary"
3380
4877
  @click="${this._handleSaveDraft}"
@@ -3397,6 +4894,18 @@ let JupiterDynamicForm = class extends LitElement {
3397
4894
  <span>Valid: ${this._valid ? "Yes" : "No"}</span>
3398
4895
  </div>
3399
4896
  </div>
4897
+
4898
+ <!-- Filter Roles Dialog -->
4899
+ ${this._showFilterDialog ? html`
4900
+ <jupiter-filter-roles-dialog
4901
+ ?open="${this._showFilterDialog}"
4902
+ .availableRoles="${this._allSections}"
4903
+ .selectedRoleIds="${this._selectedRoleIds}"
4904
+ @dialog-cancel="${this._handleFilterDialogCancel}"
4905
+ @roles-filter-apply="${this._handleRoleFilterApply}"
4906
+ @click="${this._handleFilterDialogCancel}"
4907
+ ></jupiter-filter-roles-dialog>
4908
+ ` : ""}
3400
4909
  </div>
3401
4910
  `;
3402
4911
  }
@@ -3531,6 +5040,47 @@ JupiterDynamicForm.styles = css`
3531
5040
  color: var(--jupiter-text-secondary, #666);
3532
5041
  margin-left: auto;
3533
5042
  }
5043
+
5044
+ .filter-roles-button {
5045
+ display: flex;
5046
+ align-items: center;
5047
+ gap: 8px;
5048
+ padding: 8px 16px;
5049
+ background: transparent;
5050
+ border: 1px solid var(--jupiter-primary-color, #1976d2);
5051
+ color: var(--jupiter-primary-color, #1976d2);
5052
+ border-radius: 4px;
5053
+ font-size: 13px;
5054
+ font-weight: 500;
5055
+ cursor: pointer;
5056
+ transition: all 0.2s ease;
5057
+ margin-right: auto;
5058
+ }
5059
+
5060
+ .filter-roles-button:hover:not(:disabled) {
5061
+ background: var(--jupiter-primary-color, #1976d2);
5062
+ color: white;
5063
+ }
5064
+
5065
+ .filter-roles-button .filter-icon {
5066
+ width: 16px;
5067
+ height: 16px;
5068
+ fill: currentColor;
5069
+ }
5070
+
5071
+ .roles-count {
5072
+ display: inline-flex;
5073
+ align-items: center;
5074
+ background: var(--jupiter-primary-color, #1976d2);
5075
+ color: white;
5076
+ border-radius: 10px;
5077
+ font-size: 11px;
5078
+ font-weight: 600;
5079
+ padding: 2px 6px;
5080
+ margin-left: 4px;
5081
+ min-width: 18px;
5082
+ justify-content: center;
5083
+ }
3534
5084
  `;
3535
5085
  __decorateClass([
3536
5086
  n2({ type: Object })
@@ -3559,6 +5109,15 @@ __decorateClass([
3559
5109
  __decorateClass([
3560
5110
  r()
3561
5111
  ], JupiterDynamicForm.prototype, "_formData", 2);
5112
+ __decorateClass([
5113
+ r()
5114
+ ], JupiterDynamicForm.prototype, "_preservedFormData", 2);
5115
+ __decorateClass([
5116
+ r()
5117
+ ], JupiterDynamicForm.prototype, "_typedMemberData", 2);
5118
+ __decorateClass([
5119
+ r()
5120
+ ], JupiterDynamicForm.prototype, "_preservedTypedMemberData", 2);
3562
5121
  __decorateClass([
3563
5122
  r()
3564
5123
  ], JupiterDynamicForm.prototype, "_columns", 2);
@@ -3582,16 +5141,23 @@ __decorateClass([
3582
5141
  ], JupiterDynamicForm.prototype, "_currentSchema", 2);
3583
5142
  __decorateClass([
3584
5143
  r()
3585
- ], JupiterDynamicForm.prototype, "_typedMemberValues", 2);
5144
+ ], JupiterDynamicForm.prototype, "_allSections", 2);
5145
+ __decorateClass([
5146
+ r()
5147
+ ], JupiterDynamicForm.prototype, "_selectedRoleIds", 2);
5148
+ __decorateClass([
5149
+ r()
5150
+ ], JupiterDynamicForm.prototype, "_showFilterDialog", 2);
3586
5151
  JupiterDynamicForm = __decorateClass([
3587
5152
  t$1("jupiter-dynamic-form")
3588
5153
  ], JupiterDynamicForm);
3589
- const version = "1.0.0";
5154
+ const version = "1.5.0";
3590
5155
  export {
3591
5156
  FormValidator,
3592
5157
  JupiterAddColumnDialog,
3593
5158
  JupiterConceptTree,
3594
5159
  JupiterDynamicForm,
5160
+ JupiterFilterRolesDialog,
3595
5161
  JupiterFormField,
3596
5162
  JupiterFormSection,
3597
5163
  version