jupiter-dynamic-forms 1.2.0 → 1.5.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/core/add-column-dialog.d.ts +30 -0
- package/dist/core/add-column-dialog.d.ts.map +1 -0
- package/dist/core/concept-tree.d.ts +2 -0
- package/dist/core/concept-tree.d.ts.map +1 -1
- package/dist/core/dynamic-form.d.ts +11 -0
- package/dist/core/dynamic-form.d.ts.map +1 -1
- package/dist/core/form-field.d.ts +1 -0
- package/dist/core/form-field.d.ts.map +1 -1
- package/dist/core/form-section.d.ts +11 -0
- package/dist/core/form-section.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +386 -171
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1373 -258
- package/dist/index.mjs.map +1 -1
- package/dist/schema/types.d.ts +28 -0
- package/dist/schema/types.d.ts.map +1 -1
- package/dist/schema/xbrl-types.d.ts +23 -20
- package/dist/schema/xbrl-types.d.ts.map +1 -1
- package/dist/utils/xbrl-form-builder.d.ts +40 -4
- package/dist/utils/xbrl-form-builder.d.ts.map +1 -1
- package/package.json +3 -2
- package/wrappers/angular/jupiter-dynamic-forms.module.ts +1 -1
package/dist/index.mjs
CHANGED
|
@@ -523,18 +523,32 @@ class FormValidator {
|
|
|
523
523
|
}
|
|
524
524
|
}
|
|
525
525
|
class XBRLFormBuilder {
|
|
526
|
+
/**
|
|
527
|
+
* Create unique concept ID by combining original ID with preferred label suffix
|
|
528
|
+
* This handles cases where the same concept appears multiple times with different labels
|
|
529
|
+
*/
|
|
530
|
+
static createUniqueConceptId(concept) {
|
|
531
|
+
if (concept.preferredLabel && concept.preferredLabel.trim() !== "") {
|
|
532
|
+
const roleMatch = concept.preferredLabel.match(/\/([^\/]+)$/);
|
|
533
|
+
const roleSuffix = roleMatch ? roleMatch[1] : concept.preferredLabel.replace(/[^a-zA-Z0-9]/g, "_");
|
|
534
|
+
return `${concept.id}_${roleSuffix}`;
|
|
535
|
+
}
|
|
536
|
+
return concept.id;
|
|
537
|
+
}
|
|
526
538
|
/**
|
|
527
539
|
* Build form schema from XBRL input data
|
|
528
540
|
* Creates accordion sections for each presentation role
|
|
529
541
|
*/
|
|
530
542
|
static buildFormSchema(xbrlInput, periodStartDate, periodEndDate) {
|
|
543
|
+
var _a;
|
|
531
544
|
if (!xbrlInput.presentation || xbrlInput.presentation.length === 0) {
|
|
532
545
|
throw new Error("XBRL presentation data is required");
|
|
533
546
|
}
|
|
534
547
|
const presentationData = xbrlInput.presentation[0];
|
|
548
|
+
const hypercubeData = (_a = xbrlInput.hypercubes) == null ? void 0 : _a[0];
|
|
535
549
|
const sections = [];
|
|
536
550
|
presentationData.roles.forEach((role) => {
|
|
537
|
-
const section = this.buildSectionFromRole(role, periodStartDate, periodEndDate);
|
|
551
|
+
const section = this.buildSectionFromRole(role, periodStartDate, periodEndDate, hypercubeData);
|
|
538
552
|
this.assignFieldColumnIds(section);
|
|
539
553
|
sections.push(section);
|
|
540
554
|
});
|
|
@@ -549,19 +563,32 @@ class XBRLFormBuilder {
|
|
|
549
563
|
/**
|
|
550
564
|
* Build a form section from a presentation role
|
|
551
565
|
*/
|
|
552
|
-
static buildSectionFromRole(role, periodStartDate, periodEndDate) {
|
|
566
|
+
static buildSectionFromRole(role, periodStartDate, periodEndDate, hypercubeData) {
|
|
553
567
|
var _a;
|
|
554
568
|
const title = this.extractRoleTitle(role.role);
|
|
569
|
+
const nonAbstractConcepts = this.getAllNonAbstractConcepts(role);
|
|
570
|
+
const periodTypes = new Set(
|
|
571
|
+
nonAbstractConcepts.filter((concept) => concept.periodType).map((concept) => concept.periodType)
|
|
572
|
+
);
|
|
573
|
+
const hypercubeRole = hypercubeData == null ? void 0 : hypercubeData.roles.find((hr) => hr.roleId === role.id);
|
|
574
|
+
if (hypercubeRole) {
|
|
575
|
+
console.log(`🏷️ Found matching hypercube role "${role.id}"`);
|
|
576
|
+
} else {
|
|
577
|
+
console.log(`❌ No hypercube role found for "${role.id}"`);
|
|
578
|
+
}
|
|
579
|
+
const columns = this.generateDefaultColumnsForRole(role, periodStartDate || "2025-01-01", periodEndDate || "2025-12-31", hypercubeRole, nonAbstractConcepts, periodTypes);
|
|
580
|
+
const availableColumnIds = columns.map((col) => col.id);
|
|
581
|
+
console.log(`📋 Available column IDs for role "${role.id}":`, availableColumnIds);
|
|
582
|
+
const roleInfo = { periodTypes, availableColumnIds };
|
|
555
583
|
const conceptTrees = [];
|
|
556
584
|
if ((_a = role.presentationLinkbase) == null ? void 0 : _a.concepts) {
|
|
557
585
|
role.presentationLinkbase.concepts.forEach((concept) => {
|
|
558
|
-
const conceptTree = this.buildConceptTree(concept, 0, periodStartDate, periodEndDate);
|
|
586
|
+
const conceptTree = this.buildConceptTree(concept, 0, periodStartDate, periodEndDate, roleInfo);
|
|
559
587
|
if (conceptTree) {
|
|
560
588
|
conceptTrees.push(conceptTree);
|
|
561
589
|
}
|
|
562
590
|
});
|
|
563
591
|
}
|
|
564
|
-
const columns = this.generateDefaultColumnsForRole(role, periodStartDate || "2025-01-01", periodEndDate || "2025-12-31");
|
|
565
592
|
return {
|
|
566
593
|
id: role.id,
|
|
567
594
|
title,
|
|
@@ -574,52 +601,97 @@ class XBRLFormBuilder {
|
|
|
574
601
|
/**
|
|
575
602
|
* Build concept tree from XBRL presentation concept
|
|
576
603
|
*/
|
|
577
|
-
static buildConceptTree(concept, level, periodStartDate, periodEndDate) {
|
|
604
|
+
static buildConceptTree(concept, level, periodStartDate, periodEndDate, roleInfo) {
|
|
578
605
|
const label = this.getPreferredLabel(concept.labels);
|
|
579
606
|
const fields = [];
|
|
580
607
|
if (!concept.elementAbstract) {
|
|
581
|
-
|
|
582
|
-
if (
|
|
583
|
-
|
|
608
|
+
let columnIds = [];
|
|
609
|
+
if ((roleInfo == null ? void 0 : roleInfo.availableColumnIds) && roleInfo.availableColumnIds.length > 0) {
|
|
610
|
+
columnIds = roleInfo.availableColumnIds.filter((colId) => {
|
|
611
|
+
if (concept.periodType === "instant") {
|
|
612
|
+
return colId.includes("instant") || colId === "instant";
|
|
613
|
+
} else if (concept.periodType === "duration") {
|
|
614
|
+
return colId.includes("duration") || colId === "duration";
|
|
615
|
+
} else {
|
|
616
|
+
return true;
|
|
617
|
+
}
|
|
618
|
+
});
|
|
619
|
+
if (columnIds.length === 0) {
|
|
620
|
+
columnIds = roleInfo.availableColumnIds;
|
|
621
|
+
}
|
|
622
|
+
} else {
|
|
623
|
+
if (!(roleInfo == null ? void 0 : roleInfo.periodTypes) || roleInfo.periodTypes.size === 0) {
|
|
624
|
+
columnIds = ["default"];
|
|
625
|
+
} else if (roleInfo.periodTypes.size === 1 && roleInfo.periodTypes.has("instant")) {
|
|
626
|
+
columnIds = ["instant"];
|
|
627
|
+
} else if (roleInfo.periodTypes.size === 1 && roleInfo.periodTypes.has("duration")) {
|
|
628
|
+
columnIds = ["duration"];
|
|
629
|
+
} else {
|
|
630
|
+
if (concept.periodType === "instant") {
|
|
631
|
+
columnIds = ["instant"];
|
|
632
|
+
} else if (concept.periodType === "duration") {
|
|
633
|
+
columnIds = ["duration"];
|
|
634
|
+
} else {
|
|
635
|
+
columnIds = ["duration", "instant"];
|
|
636
|
+
}
|
|
637
|
+
}
|
|
584
638
|
}
|
|
639
|
+
columnIds.forEach((columnId) => {
|
|
640
|
+
const field = this.createFieldFromConcept(concept, periodStartDate, periodEndDate, columnId);
|
|
641
|
+
if (field)
|
|
642
|
+
fields.push(field);
|
|
643
|
+
});
|
|
585
644
|
}
|
|
586
645
|
const children = [];
|
|
587
646
|
if (concept.children && concept.children.length > 0) {
|
|
588
647
|
concept.children.forEach((child) => {
|
|
589
|
-
const childTree = this.buildConceptTree(child, level + 1, periodStartDate, periodEndDate);
|
|
648
|
+
const childTree = this.buildConceptTree(child, level + 1, periodStartDate, periodEndDate, roleInfo);
|
|
590
649
|
if (childTree) {
|
|
591
650
|
children.push(childTree);
|
|
592
651
|
}
|
|
593
652
|
});
|
|
594
653
|
}
|
|
654
|
+
const hasContent = fields.length > 0 || children.length > 0;
|
|
655
|
+
if (!hasContent) {
|
|
656
|
+
return null;
|
|
657
|
+
}
|
|
595
658
|
return {
|
|
596
|
-
id: concept
|
|
659
|
+
id: this.createUniqueConceptId(concept),
|
|
660
|
+
// Use unique ID for form management
|
|
661
|
+
originalConceptId: concept.id,
|
|
662
|
+
// Store original for submission data
|
|
597
663
|
name: concept.conceptName,
|
|
598
664
|
label,
|
|
599
665
|
description: `${concept.conceptName} (${concept.type})`,
|
|
600
666
|
level,
|
|
601
667
|
children,
|
|
602
668
|
fields,
|
|
603
|
-
collapsed: level > 0
|
|
669
|
+
collapsed: level > 0,
|
|
604
670
|
// Collapse nested levels by default
|
|
671
|
+
abstract: concept.elementAbstract,
|
|
672
|
+
periodType: concept.periodType
|
|
605
673
|
};
|
|
606
674
|
}
|
|
607
675
|
/**
|
|
608
676
|
* Create form field from XBRL concept
|
|
609
677
|
*/
|
|
610
|
-
static createFieldFromConcept(concept, periodStartDate, periodEndDate) {
|
|
678
|
+
static createFieldFromConcept(concept, periodStartDate, periodEndDate, forcedColumnId) {
|
|
611
679
|
const fieldType = this.mapXBRLTypeToFieldType(concept.type);
|
|
612
680
|
const label = this.getPreferredLabel(concept.labels);
|
|
613
|
-
let columnId
|
|
614
|
-
if (
|
|
615
|
-
columnId =
|
|
616
|
-
} else if (concept.periodType === "duration") {
|
|
617
|
-
columnId = "duration_start";
|
|
681
|
+
let columnId;
|
|
682
|
+
if (forcedColumnId) {
|
|
683
|
+
columnId = forcedColumnId;
|
|
618
684
|
} else {
|
|
619
|
-
|
|
685
|
+
if (concept.periodType === "instant") {
|
|
686
|
+
columnId = "instant";
|
|
687
|
+
} else if (concept.periodType === "duration") {
|
|
688
|
+
columnId = "duration";
|
|
689
|
+
} else {
|
|
690
|
+
columnId = "default";
|
|
691
|
+
}
|
|
620
692
|
}
|
|
621
693
|
const field = {
|
|
622
|
-
id: `${concept.id}_field`,
|
|
694
|
+
id: `${concept.id}_${columnId}_field`,
|
|
623
695
|
conceptId: concept.id,
|
|
624
696
|
columnId,
|
|
625
697
|
type: fieldType,
|
|
@@ -686,16 +758,8 @@ class XBRLFormBuilder {
|
|
|
686
758
|
* Recursively assign column IDs to fields in a concept tree
|
|
687
759
|
*/
|
|
688
760
|
static assignColumnIdsToConceptFields(conceptTree, columnIds) {
|
|
689
|
-
conceptTree.fields.
|
|
690
|
-
|
|
691
|
-
field.columnId = "instant";
|
|
692
|
-
} else if (columnIds.includes("duration_start") && field.columnId === "duration_start") {
|
|
693
|
-
field.columnId = "duration_start";
|
|
694
|
-
} else if (columnIds.includes("period_start") && (field.columnId === "duration_start" || field.columnId === "instant")) {
|
|
695
|
-
field.columnId = "period_start";
|
|
696
|
-
} else if (columnIds.length > 0) {
|
|
697
|
-
field.columnId = columnIds[0];
|
|
698
|
-
}
|
|
761
|
+
conceptTree.fields = conceptTree.fields.filter((field) => {
|
|
762
|
+
return columnIds.includes(field.columnId);
|
|
699
763
|
});
|
|
700
764
|
if (conceptTree.children) {
|
|
701
765
|
conceptTree.children.forEach((child) => {
|
|
@@ -703,6 +767,18 @@ class XBRLFormBuilder {
|
|
|
703
767
|
});
|
|
704
768
|
}
|
|
705
769
|
}
|
|
770
|
+
/**
|
|
771
|
+
* Count total fields in a concept tree recursively
|
|
772
|
+
*/
|
|
773
|
+
static countFieldsInTree(conceptTree) {
|
|
774
|
+
let count = conceptTree.fields.length;
|
|
775
|
+
if (conceptTree.children) {
|
|
776
|
+
conceptTree.children.forEach((child) => {
|
|
777
|
+
count += this.countFieldsInTree(child);
|
|
778
|
+
});
|
|
779
|
+
}
|
|
780
|
+
return count;
|
|
781
|
+
}
|
|
706
782
|
/**
|
|
707
783
|
* Get all non-abstract concepts from a role recursively
|
|
708
784
|
*/
|
|
@@ -732,10 +808,14 @@ class XBRLFormBuilder {
|
|
|
732
808
|
/**
|
|
733
809
|
* Generate default columns based on period types of non-abstract concepts in a role
|
|
734
810
|
*/
|
|
735
|
-
static generateDefaultColumnsForRole(role, periodStartDate, periodEndDate) {
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
811
|
+
static generateDefaultColumnsForRole(role, periodStartDate, periodEndDate, hypercubeRole, nonAbstractConcepts, rolePeriodTypes) {
|
|
812
|
+
var _a, _b, _c;
|
|
813
|
+
const concepts = nonAbstractConcepts || this.getAllNonAbstractConcepts(role);
|
|
814
|
+
const periodTypes = rolePeriodTypes || new Set(
|
|
815
|
+
concepts.filter((concept) => concept.periodType).map((concept) => concept.periodType)
|
|
816
|
+
);
|
|
817
|
+
console.log(`📊 Analyzing role "${role.role}" with ${concepts.length} non-abstract concepts`);
|
|
818
|
+
if (concepts.length === 0) {
|
|
739
819
|
console.log("📊 No non-abstract concepts found, using default column");
|
|
740
820
|
return [{
|
|
741
821
|
id: "default",
|
|
@@ -746,71 +826,359 @@ class XBRLFormBuilder {
|
|
|
746
826
|
removable: false
|
|
747
827
|
}];
|
|
748
828
|
}
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
829
|
+
let dimensionColumns = [];
|
|
830
|
+
if (((_a = hypercubeRole == null ? void 0 : hypercubeRole.items) == null ? void 0 : _a.length) === 1) {
|
|
831
|
+
const item = hypercubeRole.items[0];
|
|
832
|
+
console.log(`🔍 Processing hypercube item for role "${role.role}":`, {
|
|
833
|
+
itemId: item.id,
|
|
834
|
+
conceptIds: ((_b = item.conceptIds) == null ? void 0 : _b.length) || 0,
|
|
835
|
+
dimensions: item.dimensions.length
|
|
836
|
+
});
|
|
837
|
+
if (item.dimensions.length === 1) {
|
|
838
|
+
dimensionColumns = this.generateSingleDimensionColumns(item.dimensions[0], periodStartDate, periodEndDate, periodTypes);
|
|
839
|
+
} else if (item.dimensions.length > 1) {
|
|
840
|
+
dimensionColumns = this.generateMultiDimensionColumns(item.dimensions, periodStartDate, periodEndDate, periodTypes);
|
|
841
|
+
}
|
|
842
|
+
} else if (((_c = hypercubeRole == null ? void 0 : hypercubeRole.items) == null ? void 0 : _c.length) && hypercubeRole.items.length > 1) {
|
|
843
|
+
console.log(`⚠️ Multiple items found (${hypercubeRole.items.length}), skipping for now`);
|
|
844
|
+
}
|
|
752
845
|
console.log(`📅 Found period types: ${Array.from(periodTypes).join(", ")}`);
|
|
753
846
|
const columns = [];
|
|
847
|
+
if (dimensionColumns.length > 0) {
|
|
848
|
+
columns.push(...dimensionColumns);
|
|
849
|
+
} else {
|
|
850
|
+
if (periodTypes.size === 0) {
|
|
851
|
+
console.log("📅 No period types found, using default column");
|
|
852
|
+
columns.push({
|
|
853
|
+
id: "default",
|
|
854
|
+
title: "Value",
|
|
855
|
+
description: "Default value column",
|
|
856
|
+
type: "base",
|
|
857
|
+
order: 0,
|
|
858
|
+
removable: false
|
|
859
|
+
});
|
|
860
|
+
} else if (periodTypes.size === 1 && periodTypes.has("instant")) {
|
|
861
|
+
console.log("📅 All concepts are instant type, creating single column");
|
|
862
|
+
columns.push({
|
|
863
|
+
id: "instant",
|
|
864
|
+
title: `As of ${this.formatDateForDisplay(periodStartDate)}`,
|
|
865
|
+
description: `Values as of ${periodStartDate}`,
|
|
866
|
+
type: "base",
|
|
867
|
+
order: 0,
|
|
868
|
+
removable: false
|
|
869
|
+
});
|
|
870
|
+
} else if (periodTypes.size === 1 && periodTypes.has("duration")) {
|
|
871
|
+
console.log("📅 All concepts are duration type, creating single column with period range");
|
|
872
|
+
columns.push({
|
|
873
|
+
id: "duration",
|
|
874
|
+
title: `${this.formatDateForDisplay(periodStartDate)} / ${this.formatDateForDisplay(periodEndDate)}`,
|
|
875
|
+
description: `Period: ${periodStartDate} to ${periodEndDate}`,
|
|
876
|
+
type: "base",
|
|
877
|
+
order: 0,
|
|
878
|
+
removable: false
|
|
879
|
+
});
|
|
880
|
+
} else {
|
|
881
|
+
console.log("📅 Mixed period types found, creating both duration and instant columns");
|
|
882
|
+
columns.push({
|
|
883
|
+
id: "duration",
|
|
884
|
+
title: `${this.formatDateForDisplay(periodStartDate)} / ${this.formatDateForDisplay(periodEndDate)}`,
|
|
885
|
+
description: `Period: ${periodStartDate} to ${periodEndDate}`,
|
|
886
|
+
type: "base",
|
|
887
|
+
order: 0,
|
|
888
|
+
removable: false
|
|
889
|
+
});
|
|
890
|
+
columns.push({
|
|
891
|
+
id: "instant",
|
|
892
|
+
title: `As of ${this.formatDateForDisplay(periodStartDate)}`,
|
|
893
|
+
description: `Values as of ${periodStartDate}`,
|
|
894
|
+
type: "base",
|
|
895
|
+
order: 1,
|
|
896
|
+
removable: false
|
|
897
|
+
});
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
console.log(`📊 Generated ${columns.length} columns for role "${role.role}":`, columns.map((c2) => c2.title));
|
|
901
|
+
return columns;
|
|
902
|
+
}
|
|
903
|
+
/**
|
|
904
|
+
* Generate columns for single dimension scenarios
|
|
905
|
+
*/
|
|
906
|
+
static generateSingleDimensionColumns(dimension, periodStartDate, periodEndDate, periodTypes) {
|
|
907
|
+
var _a, _b;
|
|
908
|
+
console.log(`📊 Found single dimension:`, {
|
|
909
|
+
id: dimension.id,
|
|
910
|
+
conceptName: dimension.conceptName,
|
|
911
|
+
membersCount: dimension.members.length
|
|
912
|
+
});
|
|
913
|
+
if (dimension.members.length === 0) {
|
|
914
|
+
return [];
|
|
915
|
+
}
|
|
916
|
+
const axisLabel = ((_a = dimension.labels.find((l2) => l2.role === "http://www.xbrl.org/2003/role/label")) == null ? void 0 : _a.label) || dimension.conceptName;
|
|
917
|
+
const firstMember = dimension.members[0];
|
|
918
|
+
const memberLabel = ((_b = firstMember.labels.find((l2) => l2.role === "http://www.xbrl.org/2003/role/label")) == null ? void 0 : _b.label) || firstMember.conceptName;
|
|
919
|
+
const dimensionInfo = {
|
|
920
|
+
axisId: dimension.id,
|
|
921
|
+
axisLabel,
|
|
922
|
+
memberId: firstMember.id,
|
|
923
|
+
memberLabel,
|
|
924
|
+
dimensionKey: `${axisLabel} | ${memberLabel}`,
|
|
925
|
+
dimensionIdKey: `${dimension.id} | ${firstMember.id}`
|
|
926
|
+
};
|
|
927
|
+
console.log(`📊 Generated dimension info:`, dimensionInfo);
|
|
928
|
+
const columns = [];
|
|
754
929
|
if (periodTypes.size === 0) {
|
|
755
|
-
console.log("📅 No period types found, using default column");
|
|
756
930
|
columns.push({
|
|
757
931
|
id: "default",
|
|
758
|
-
title:
|
|
932
|
+
title: dimensionInfo.memberLabel,
|
|
759
933
|
description: "Default value column",
|
|
760
|
-
type: "
|
|
934
|
+
type: "dimension",
|
|
935
|
+
dimensionData: {
|
|
936
|
+
dimensionId: "default",
|
|
937
|
+
axisId: dimensionInfo.axisId,
|
|
938
|
+
memberId: dimensionInfo.memberId,
|
|
939
|
+
memberValue: dimensionInfo.memberLabel,
|
|
940
|
+
memberLabel: dimensionInfo.memberLabel,
|
|
941
|
+
axis: dimensionInfo.axisLabel,
|
|
942
|
+
axisLabel: dimensionInfo.axisLabel,
|
|
943
|
+
memberKey: dimensionInfo.dimensionKey,
|
|
944
|
+
dimensionIdKey: dimensionInfo.dimensionIdKey
|
|
945
|
+
},
|
|
761
946
|
order: 0,
|
|
762
947
|
removable: false
|
|
763
948
|
});
|
|
764
949
|
} else if (periodTypes.size === 1 && periodTypes.has("instant")) {
|
|
765
|
-
console.log("📅 All concepts are instant type, creating single column");
|
|
766
950
|
columns.push({
|
|
767
951
|
id: "instant",
|
|
768
|
-
title:
|
|
952
|
+
title: `${dimensionInfo.memberLabel} (${this.formatDateForDisplay(periodStartDate)})`,
|
|
769
953
|
description: `Values as of ${periodStartDate}`,
|
|
770
|
-
type: "
|
|
954
|
+
type: "dimension",
|
|
955
|
+
dimensionData: {
|
|
956
|
+
dimensionId: "instant",
|
|
957
|
+
axisId: dimensionInfo.axisId,
|
|
958
|
+
memberId: dimensionInfo.memberId,
|
|
959
|
+
memberValue: dimensionInfo.memberLabel,
|
|
960
|
+
memberLabel: dimensionInfo.memberLabel,
|
|
961
|
+
axis: dimensionInfo.axisLabel,
|
|
962
|
+
axisLabel: dimensionInfo.axisLabel,
|
|
963
|
+
memberKey: dimensionInfo.dimensionKey,
|
|
964
|
+
dimensionIdKey: dimensionInfo.dimensionIdKey
|
|
965
|
+
},
|
|
771
966
|
order: 0,
|
|
772
967
|
removable: false
|
|
773
968
|
});
|
|
774
969
|
} else if (periodTypes.size === 1 && periodTypes.has("duration")) {
|
|
775
|
-
console.log("📅 All concepts are duration type, creating two columns");
|
|
776
970
|
columns.push({
|
|
777
|
-
id: "
|
|
778
|
-
title:
|
|
779
|
-
description: `Period
|
|
780
|
-
type: "
|
|
971
|
+
id: "duration",
|
|
972
|
+
title: `${dimensionInfo.memberLabel} (${this.formatDateForDisplay(periodStartDate)} / ${this.formatDateForDisplay(periodEndDate)})`,
|
|
973
|
+
description: `Period: ${periodStartDate} to ${periodEndDate}`,
|
|
974
|
+
type: "dimension",
|
|
975
|
+
dimensionData: {
|
|
976
|
+
dimensionId: "duration",
|
|
977
|
+
axisId: dimensionInfo.axisId,
|
|
978
|
+
memberId: dimensionInfo.memberId,
|
|
979
|
+
memberValue: dimensionInfo.memberLabel,
|
|
980
|
+
memberLabel: dimensionInfo.memberLabel,
|
|
981
|
+
axis: dimensionInfo.axisLabel,
|
|
982
|
+
axisLabel: dimensionInfo.axisLabel,
|
|
983
|
+
memberKey: dimensionInfo.dimensionKey,
|
|
984
|
+
dimensionIdKey: dimensionInfo.dimensionIdKey
|
|
985
|
+
},
|
|
781
986
|
order: 0,
|
|
782
987
|
removable: false
|
|
783
988
|
});
|
|
784
|
-
columns.push({
|
|
785
|
-
id: "duration_end",
|
|
786
|
-
title: `To ${this.formatDateForDisplay(periodEndDate)}`,
|
|
787
|
-
description: `Period end: ${periodEndDate}`,
|
|
788
|
-
type: "base",
|
|
789
|
-
order: 1,
|
|
790
|
-
removable: false
|
|
791
|
-
});
|
|
792
989
|
} else {
|
|
793
|
-
console.log("📅 Mixed period types found, creating two columns for full range");
|
|
794
990
|
columns.push({
|
|
795
|
-
id: "
|
|
796
|
-
title:
|
|
797
|
-
description: `Period
|
|
798
|
-
type: "
|
|
991
|
+
id: "duration",
|
|
992
|
+
title: `${dimensionInfo.memberLabel} (${this.formatDateForDisplay(periodStartDate)} / ${this.formatDateForDisplay(periodEndDate)})`,
|
|
993
|
+
description: `Period: ${periodStartDate} to ${periodEndDate}`,
|
|
994
|
+
type: "dimension",
|
|
995
|
+
dimensionData: {
|
|
996
|
+
dimensionId: "duration",
|
|
997
|
+
axisId: dimensionInfo.axisId,
|
|
998
|
+
memberId: dimensionInfo.memberId,
|
|
999
|
+
memberValue: dimensionInfo.memberLabel,
|
|
1000
|
+
memberLabel: dimensionInfo.memberLabel,
|
|
1001
|
+
axis: dimensionInfo.axisLabel,
|
|
1002
|
+
axisLabel: dimensionInfo.axisLabel,
|
|
1003
|
+
memberKey: dimensionInfo.dimensionKey,
|
|
1004
|
+
dimensionIdKey: dimensionInfo.dimensionIdKey
|
|
1005
|
+
},
|
|
799
1006
|
order: 0,
|
|
800
1007
|
removable: false
|
|
801
1008
|
});
|
|
802
1009
|
columns.push({
|
|
803
|
-
id: "
|
|
804
|
-
title:
|
|
805
|
-
description: `
|
|
806
|
-
type: "
|
|
1010
|
+
id: "instant",
|
|
1011
|
+
title: `${dimensionInfo.memberLabel} (${this.formatDateForDisplay(periodStartDate)})`,
|
|
1012
|
+
description: `Values as of ${periodStartDate}`,
|
|
1013
|
+
type: "dimension",
|
|
1014
|
+
dimensionData: {
|
|
1015
|
+
dimensionId: "instant",
|
|
1016
|
+
axisId: dimensionInfo.axisId,
|
|
1017
|
+
memberId: dimensionInfo.memberId,
|
|
1018
|
+
memberValue: dimensionInfo.memberLabel,
|
|
1019
|
+
memberLabel: dimensionInfo.memberLabel,
|
|
1020
|
+
axis: dimensionInfo.axisLabel,
|
|
1021
|
+
axisLabel: dimensionInfo.axisLabel,
|
|
1022
|
+
memberKey: dimensionInfo.dimensionKey,
|
|
1023
|
+
dimensionIdKey: dimensionInfo.dimensionIdKey
|
|
1024
|
+
},
|
|
807
1025
|
order: 1,
|
|
808
1026
|
removable: false
|
|
809
1027
|
});
|
|
810
1028
|
}
|
|
811
|
-
console.log(`📊 Generated ${columns.length} columns for role "${role.role}":`, columns.map((c2) => c2.title));
|
|
812
1029
|
return columns;
|
|
813
1030
|
}
|
|
1031
|
+
/**
|
|
1032
|
+
* Generate columns for multi-dimension scenarios - creates combinations of all dimension members
|
|
1033
|
+
*/
|
|
1034
|
+
static generateMultiDimensionColumns(dimensions, periodStartDate, periodEndDate, periodTypes) {
|
|
1035
|
+
console.log(`📊 Processing ${dimensions.length} dimensions for multi-dimensional columns`);
|
|
1036
|
+
const dimensionInfos = dimensions.map((dimension) => {
|
|
1037
|
+
var _a;
|
|
1038
|
+
const axisLabel = ((_a = dimension.labels.find((l2) => l2.role === "http://www.xbrl.org/2003/role/label")) == null ? void 0 : _a.label) || dimension.conceptName;
|
|
1039
|
+
const allMembers = this.getAllDimensionMembers(dimension.members);
|
|
1040
|
+
return {
|
|
1041
|
+
id: dimension.id,
|
|
1042
|
+
axisLabel,
|
|
1043
|
+
members: allMembers.map((member) => {
|
|
1044
|
+
var _a2;
|
|
1045
|
+
return {
|
|
1046
|
+
id: member.id,
|
|
1047
|
+
label: ((_a2 = member.labels.find((l2) => l2.role === "http://www.xbrl.org/2003/role/label")) == null ? void 0 : _a2.label) || member.conceptName
|
|
1048
|
+
};
|
|
1049
|
+
})
|
|
1050
|
+
};
|
|
1051
|
+
});
|
|
1052
|
+
const combinations = this.generateDimensionCombinations(dimensionInfos);
|
|
1053
|
+
console.log(`📊 Generated ${combinations.length} dimension combinations`);
|
|
1054
|
+
const columns = [];
|
|
1055
|
+
combinations.forEach((combination, index) => {
|
|
1056
|
+
const columnTitle = combination.map((c2) => c2.memberLabel).join(" | ");
|
|
1057
|
+
const dimensionData = {
|
|
1058
|
+
dimensionId: `multi_${index}`,
|
|
1059
|
+
memberValue: columnTitle,
|
|
1060
|
+
// Required field
|
|
1061
|
+
memberLabel: columnTitle,
|
|
1062
|
+
// Required field
|
|
1063
|
+
combinations: combination.map((c2) => ({
|
|
1064
|
+
axisId: c2.axisId,
|
|
1065
|
+
axisLabel: c2.axisLabel,
|
|
1066
|
+
memberId: c2.memberId,
|
|
1067
|
+
memberLabel: c2.memberLabel
|
|
1068
|
+
})),
|
|
1069
|
+
memberKey: columnTitle,
|
|
1070
|
+
dimensionIdKey: combination.map((c2) => `${c2.axisId}|${c2.memberId}`).join("::")
|
|
1071
|
+
};
|
|
1072
|
+
if (periodTypes.size === 0 || periodTypes.size === 1 && periodTypes.has("duration")) {
|
|
1073
|
+
columns.push({
|
|
1074
|
+
id: `duration_${index}`,
|
|
1075
|
+
title: `${columnTitle} (${this.formatDateForDisplay(periodStartDate)} / ${this.formatDateForDisplay(periodEndDate)})`,
|
|
1076
|
+
description: `Period: ${periodStartDate} to ${periodEndDate}`,
|
|
1077
|
+
type: "dimension",
|
|
1078
|
+
dimensionData: {
|
|
1079
|
+
...dimensionData,
|
|
1080
|
+
dimensionId: `duration_${index}`
|
|
1081
|
+
},
|
|
1082
|
+
order: index * 2,
|
|
1083
|
+
removable: false
|
|
1084
|
+
});
|
|
1085
|
+
} else if (periodTypes.size === 1 && periodTypes.has("instant")) {
|
|
1086
|
+
columns.push({
|
|
1087
|
+
id: `instant_${index}`,
|
|
1088
|
+
title: `${columnTitle} (${this.formatDateForDisplay(periodStartDate)})`,
|
|
1089
|
+
description: `Values as of ${periodStartDate}`,
|
|
1090
|
+
type: "dimension",
|
|
1091
|
+
dimensionData: {
|
|
1092
|
+
...dimensionData,
|
|
1093
|
+
dimensionId: `instant_${index}`
|
|
1094
|
+
},
|
|
1095
|
+
order: index * 2,
|
|
1096
|
+
removable: false
|
|
1097
|
+
});
|
|
1098
|
+
} else {
|
|
1099
|
+
columns.push({
|
|
1100
|
+
id: `duration_${index}`,
|
|
1101
|
+
title: `${columnTitle} (${this.formatDateForDisplay(periodStartDate)} / ${this.formatDateForDisplay(periodEndDate)})`,
|
|
1102
|
+
description: `Period: ${periodStartDate} to ${periodEndDate}`,
|
|
1103
|
+
type: "dimension",
|
|
1104
|
+
dimensionData: {
|
|
1105
|
+
...dimensionData,
|
|
1106
|
+
dimensionId: `duration_${index}`
|
|
1107
|
+
},
|
|
1108
|
+
order: index * 2,
|
|
1109
|
+
removable: false
|
|
1110
|
+
});
|
|
1111
|
+
columns.push({
|
|
1112
|
+
id: `instant_${index}`,
|
|
1113
|
+
title: `${columnTitle} (${this.formatDateForDisplay(periodStartDate)})`,
|
|
1114
|
+
description: `Values as of ${periodStartDate}`,
|
|
1115
|
+
type: "dimension",
|
|
1116
|
+
dimensionData: {
|
|
1117
|
+
...dimensionData,
|
|
1118
|
+
dimensionId: `instant_${index}`
|
|
1119
|
+
},
|
|
1120
|
+
order: index * 2 + 1,
|
|
1121
|
+
removable: false
|
|
1122
|
+
});
|
|
1123
|
+
}
|
|
1124
|
+
});
|
|
1125
|
+
console.log(`📊 Generated ${columns.length} multi-dimensional columns`);
|
|
1126
|
+
return columns;
|
|
1127
|
+
}
|
|
1128
|
+
/**
|
|
1129
|
+
* Get all members including children recursively
|
|
1130
|
+
*/
|
|
1131
|
+
static getAllDimensionMembers(members) {
|
|
1132
|
+
const allMembers = [];
|
|
1133
|
+
members.forEach((member) => {
|
|
1134
|
+
allMembers.push(member);
|
|
1135
|
+
if (member.children && member.children.length > 0) {
|
|
1136
|
+
allMembers.push(...this.getAllDimensionMembers(member.children));
|
|
1137
|
+
}
|
|
1138
|
+
});
|
|
1139
|
+
return allMembers;
|
|
1140
|
+
}
|
|
1141
|
+
/**
|
|
1142
|
+
* Generate all combinations of dimension members
|
|
1143
|
+
*/
|
|
1144
|
+
static generateDimensionCombinations(dimensionInfos) {
|
|
1145
|
+
if (dimensionInfos.length === 0)
|
|
1146
|
+
return [];
|
|
1147
|
+
if (dimensionInfos.length === 1) {
|
|
1148
|
+
return dimensionInfos[0].members.map((member) => [{
|
|
1149
|
+
axisId: dimensionInfos[0].id,
|
|
1150
|
+
axisLabel: dimensionInfos[0].axisLabel,
|
|
1151
|
+
memberId: member.id,
|
|
1152
|
+
memberLabel: member.label
|
|
1153
|
+
}]);
|
|
1154
|
+
}
|
|
1155
|
+
const [firstDimension, ...restDimensions] = dimensionInfos;
|
|
1156
|
+
const restCombinations = this.generateDimensionCombinations(restDimensions);
|
|
1157
|
+
const combinations = [];
|
|
1158
|
+
firstDimension.members.forEach((member) => {
|
|
1159
|
+
if (restCombinations.length === 0) {
|
|
1160
|
+
combinations.push([{
|
|
1161
|
+
axisId: firstDimension.id,
|
|
1162
|
+
axisLabel: firstDimension.axisLabel,
|
|
1163
|
+
memberId: member.id,
|
|
1164
|
+
memberLabel: member.label
|
|
1165
|
+
}]);
|
|
1166
|
+
} else {
|
|
1167
|
+
restCombinations.forEach((restCombination) => {
|
|
1168
|
+
combinations.push([
|
|
1169
|
+
{
|
|
1170
|
+
axisId: firstDimension.id,
|
|
1171
|
+
axisLabel: firstDimension.axisLabel,
|
|
1172
|
+
memberId: member.id,
|
|
1173
|
+
memberLabel: member.label
|
|
1174
|
+
},
|
|
1175
|
+
...restCombination
|
|
1176
|
+
]);
|
|
1177
|
+
});
|
|
1178
|
+
}
|
|
1179
|
+
});
|
|
1180
|
+
return combinations;
|
|
1181
|
+
}
|
|
814
1182
|
/**
|
|
815
1183
|
* Format date for display in column headers
|
|
816
1184
|
*/
|
|
@@ -864,15 +1232,15 @@ class XBRLFormBuilder {
|
|
|
864
1232
|
}];
|
|
865
1233
|
}
|
|
866
1234
|
}
|
|
867
|
-
var __defProp$
|
|
868
|
-
var __getOwnPropDesc$
|
|
869
|
-
var __decorateClass$
|
|
870
|
-
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$
|
|
1235
|
+
var __defProp$4 = Object.defineProperty;
|
|
1236
|
+
var __getOwnPropDesc$4 = Object.getOwnPropertyDescriptor;
|
|
1237
|
+
var __decorateClass$4 = (decorators, target, key, kind) => {
|
|
1238
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$4(target, key) : target;
|
|
871
1239
|
for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
|
|
872
1240
|
if (decorator = decorators[i2])
|
|
873
1241
|
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
874
1242
|
if (kind && result)
|
|
875
|
-
__defProp$
|
|
1243
|
+
__defProp$4(target, key, result);
|
|
876
1244
|
return result;
|
|
877
1245
|
};
|
|
878
1246
|
let JupiterFormField = class extends LitElement {
|
|
@@ -881,6 +1249,7 @@ let JupiterFormField = class extends LitElement {
|
|
|
881
1249
|
this.value = null;
|
|
882
1250
|
this.disabled = false;
|
|
883
1251
|
this.locale = "en-US";
|
|
1252
|
+
this.hideLabel = false;
|
|
884
1253
|
this._errors = [];
|
|
885
1254
|
this._touched = false;
|
|
886
1255
|
}
|
|
@@ -949,10 +1318,14 @@ let JupiterFormField = class extends LitElement {
|
|
|
949
1318
|
const hasErrors = this._errors.some((e2) => e2.severity === "error");
|
|
950
1319
|
const hasWarnings = this._errors.some((e2) => e2.severity === "warning");
|
|
951
1320
|
const cssClass = `field-input ${hasErrors ? "error" : hasWarnings ? "warning" : ""}`;
|
|
1321
|
+
const fieldId = `${this.conceptId}__${this.columnId}`;
|
|
1322
|
+
const fieldName = `data[${this.conceptId}][${this.columnId}]`;
|
|
952
1323
|
switch (this.field.type) {
|
|
953
1324
|
case "textarea":
|
|
954
1325
|
return html`
|
|
955
1326
|
<textarea
|
|
1327
|
+
id="${fieldId}"
|
|
1328
|
+
name="${fieldName}"
|
|
956
1329
|
class="${cssClass}"
|
|
957
1330
|
.value="${this.value || ""}"
|
|
958
1331
|
?disabled="${this.disabled || this.field.disabled}"
|
|
@@ -965,6 +1338,8 @@ let JupiterFormField = class extends LitElement {
|
|
|
965
1338
|
case "select":
|
|
966
1339
|
return html`
|
|
967
1340
|
<select
|
|
1341
|
+
id="${fieldId}"
|
|
1342
|
+
name="${fieldName}"
|
|
968
1343
|
class="${cssClass}"
|
|
969
1344
|
.value="${this.value || ""}"
|
|
970
1345
|
?disabled="${this.disabled || this.field.disabled}"
|
|
@@ -988,6 +1363,8 @@ let JupiterFormField = class extends LitElement {
|
|
|
988
1363
|
return html`
|
|
989
1364
|
<div class="checkbox-container">
|
|
990
1365
|
<input
|
|
1366
|
+
id="${fieldId}"
|
|
1367
|
+
name="${fieldName}"
|
|
991
1368
|
type="checkbox"
|
|
992
1369
|
class="field-input"
|
|
993
1370
|
.checked="${Boolean(this.value)}"
|
|
@@ -1002,6 +1379,8 @@ let JupiterFormField = class extends LitElement {
|
|
|
1002
1379
|
default:
|
|
1003
1380
|
return html`
|
|
1004
1381
|
<input
|
|
1382
|
+
id="${fieldId}"
|
|
1383
|
+
name="${fieldName}"
|
|
1005
1384
|
type="${this._getInputType()}"
|
|
1006
1385
|
class="${cssClass}"
|
|
1007
1386
|
.value="${this.value || ""}"
|
|
@@ -1036,7 +1415,7 @@ let JupiterFormField = class extends LitElement {
|
|
|
1036
1415
|
}
|
|
1037
1416
|
}
|
|
1038
1417
|
render() {
|
|
1039
|
-
const showLabel = this.field.type !== "boolean";
|
|
1418
|
+
const showLabel = !this.hideLabel && this.field.type !== "boolean";
|
|
1040
1419
|
return html`
|
|
1041
1420
|
<div class="field-container">
|
|
1042
1421
|
${showLabel ? html`
|
|
@@ -1063,7 +1442,11 @@ let JupiterFormField = class extends LitElement {
|
|
|
1063
1442
|
JupiterFormField.styles = css`
|
|
1064
1443
|
:host {
|
|
1065
1444
|
display: block;
|
|
1066
|
-
margin-bottom:
|
|
1445
|
+
margin-bottom: 0px; /* Remove bottom margin for table layout */
|
|
1446
|
+
}
|
|
1447
|
+
|
|
1448
|
+
:host([hideLabel]) {
|
|
1449
|
+
margin-bottom: 0px;
|
|
1067
1450
|
}
|
|
1068
1451
|
|
|
1069
1452
|
.field-container {
|
|
@@ -1085,10 +1468,10 @@ JupiterFormField.styles = css`
|
|
|
1085
1468
|
|
|
1086
1469
|
.field-input {
|
|
1087
1470
|
width: 100%;
|
|
1088
|
-
padding: 8px
|
|
1471
|
+
padding: 6px 8px; /* Reduced padding for table cells */
|
|
1089
1472
|
border: 1px solid var(--jupiter-border-color, #ddd);
|
|
1090
1473
|
border-radius: 4px;
|
|
1091
|
-
font-size:
|
|
1474
|
+
font-size: 13px; /* Slightly smaller font for table */
|
|
1092
1475
|
font-family: inherit;
|
|
1093
1476
|
background: var(--jupiter-input-background, #fff);
|
|
1094
1477
|
color: var(--jupiter-text-primary, #333);
|
|
@@ -1162,42 +1545,45 @@ JupiterFormField.styles = css`
|
|
|
1162
1545
|
width: auto;
|
|
1163
1546
|
}
|
|
1164
1547
|
`;
|
|
1165
|
-
__decorateClass$
|
|
1548
|
+
__decorateClass$4([
|
|
1166
1549
|
n2({ type: Object })
|
|
1167
1550
|
], JupiterFormField.prototype, "field", 2);
|
|
1168
|
-
__decorateClass$
|
|
1551
|
+
__decorateClass$4([
|
|
1169
1552
|
n2({ type: String })
|
|
1170
1553
|
], JupiterFormField.prototype, "conceptId", 2);
|
|
1171
|
-
__decorateClass$
|
|
1554
|
+
__decorateClass$4([
|
|
1172
1555
|
n2({ type: String })
|
|
1173
1556
|
], JupiterFormField.prototype, "columnId", 2);
|
|
1174
|
-
__decorateClass$
|
|
1557
|
+
__decorateClass$4([
|
|
1175
1558
|
n2()
|
|
1176
1559
|
], JupiterFormField.prototype, "value", 2);
|
|
1177
|
-
__decorateClass$
|
|
1560
|
+
__decorateClass$4([
|
|
1178
1561
|
n2({ type: Boolean })
|
|
1179
1562
|
], JupiterFormField.prototype, "disabled", 2);
|
|
1180
|
-
__decorateClass$
|
|
1563
|
+
__decorateClass$4([
|
|
1181
1564
|
n2({ type: String })
|
|
1182
1565
|
], JupiterFormField.prototype, "locale", 2);
|
|
1183
|
-
__decorateClass$
|
|
1566
|
+
__decorateClass$4([
|
|
1567
|
+
n2({ type: Boolean })
|
|
1568
|
+
], JupiterFormField.prototype, "hideLabel", 2);
|
|
1569
|
+
__decorateClass$4([
|
|
1184
1570
|
r()
|
|
1185
1571
|
], JupiterFormField.prototype, "_errors", 2);
|
|
1186
|
-
__decorateClass$
|
|
1572
|
+
__decorateClass$4([
|
|
1187
1573
|
r()
|
|
1188
1574
|
], JupiterFormField.prototype, "_touched", 2);
|
|
1189
|
-
JupiterFormField = __decorateClass$
|
|
1575
|
+
JupiterFormField = __decorateClass$4([
|
|
1190
1576
|
t$1("jupiter-form-field")
|
|
1191
1577
|
], JupiterFormField);
|
|
1192
|
-
var __defProp$
|
|
1193
|
-
var __getOwnPropDesc$
|
|
1194
|
-
var __decorateClass$
|
|
1195
|
-
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$
|
|
1578
|
+
var __defProp$3 = Object.defineProperty;
|
|
1579
|
+
var __getOwnPropDesc$3 = Object.getOwnPropertyDescriptor;
|
|
1580
|
+
var __decorateClass$3 = (decorators, target, key, kind) => {
|
|
1581
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$3(target, key) : target;
|
|
1196
1582
|
for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
|
|
1197
1583
|
if (decorator = decorators[i2])
|
|
1198
1584
|
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
1199
1585
|
if (kind && result)
|
|
1200
|
-
__defProp$
|
|
1586
|
+
__defProp$3(target, key, result);
|
|
1201
1587
|
return result;
|
|
1202
1588
|
};
|
|
1203
1589
|
let JupiterConceptTree = class extends LitElement {
|
|
@@ -1207,11 +1593,18 @@ let JupiterConceptTree = class extends LitElement {
|
|
|
1207
1593
|
this.formData = {};
|
|
1208
1594
|
this.disabled = false;
|
|
1209
1595
|
this.locale = "en-US";
|
|
1596
|
+
this.expandedConcepts = /* @__PURE__ */ new Set();
|
|
1210
1597
|
this._expanded = true;
|
|
1211
1598
|
}
|
|
1212
1599
|
connectedCallback() {
|
|
1213
1600
|
super.connectedCallback();
|
|
1214
|
-
this._expanded =
|
|
1601
|
+
this._expanded = this.expandedConcepts.has(this.concept.id);
|
|
1602
|
+
}
|
|
1603
|
+
willUpdate(changedProperties) {
|
|
1604
|
+
super.willUpdate(changedProperties);
|
|
1605
|
+
if (changedProperties.has("expandedConcepts")) {
|
|
1606
|
+
this._expanded = this.expandedConcepts.has(this.concept.id);
|
|
1607
|
+
}
|
|
1215
1608
|
}
|
|
1216
1609
|
_toggleExpanded() {
|
|
1217
1610
|
this._expanded = !this._expanded;
|
|
@@ -1224,7 +1617,8 @@ let JupiterConceptTree = class extends LitElement {
|
|
|
1224
1617
|
}));
|
|
1225
1618
|
}
|
|
1226
1619
|
_getFieldForColumn(columnId) {
|
|
1227
|
-
|
|
1620
|
+
var _a;
|
|
1621
|
+
return (_a = this.concept.fields) == null ? void 0 : _a.find((field) => field.columnId === columnId);
|
|
1228
1622
|
}
|
|
1229
1623
|
_getFieldValue(field) {
|
|
1230
1624
|
var _a;
|
|
@@ -1240,104 +1634,103 @@ let JupiterConceptTree = class extends LitElement {
|
|
|
1240
1634
|
render() {
|
|
1241
1635
|
const hasChildren = this.concept.children && this.concept.children.length > 0;
|
|
1242
1636
|
const level = this.concept.level || 0;
|
|
1637
|
+
const isAbstract = this.concept.abstract || false;
|
|
1243
1638
|
return html`
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
<div class="concept-
|
|
1639
|
+
<!-- Concept Name Cell (Left Column) -->
|
|
1640
|
+
<td class="concept-name-cell ${isAbstract ? "abstract" : hasChildren ? "" : "leaf"}">
|
|
1641
|
+
<div class="concept-content" style="--level: ${level}">
|
|
1247
1642
|
<div class="concept-indent"></div>
|
|
1248
|
-
<div class="concept-toggle ${hasChildren ? this._expanded ? "expanded" : "" : "no-children"}"
|
|
1643
|
+
<div class="concept-toggle ${hasChildren ? this._expanded ? "expanded" : "" : "no-children"}"
|
|
1644
|
+
@click="${this._toggleExpanded}">
|
|
1249
1645
|
${hasChildren ? "▶" : ""}
|
|
1250
1646
|
</div>
|
|
1251
|
-
<div class="concept-label"
|
|
1647
|
+
<div class="concept-label"
|
|
1648
|
+
@click="${this._toggleExpanded}"
|
|
1649
|
+
title="${this.concept.id}${this.concept.description ? " - " + this.concept.description : ""}">
|
|
1252
1650
|
${this.concept.label}
|
|
1253
|
-
${this.concept.description ? html`
|
|
1254
|
-
<span class="concept-description">${this.concept.description}</span>
|
|
1255
|
-
` : ""}
|
|
1256
1651
|
</div>
|
|
1257
1652
|
</div>
|
|
1653
|
+
</td>
|
|
1258
1654
|
|
|
1259
|
-
|
|
1260
|
-
|
|
1655
|
+
<!-- Input Field Cells (Period Columns) - Only for non-abstract concepts -->
|
|
1656
|
+
${this.columns.map((column) => {
|
|
1261
1657
|
const field = this._getFieldForColumn(column.id);
|
|
1658
|
+
const shouldShowField = !isAbstract && field;
|
|
1262
1659
|
return html`
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1660
|
+
<td class="field-cell ${!shouldShowField ? "empty" : ""} ${isAbstract ? "abstract-row" : ""}">
|
|
1661
|
+
${shouldShowField ? html`
|
|
1662
|
+
<jupiter-form-field
|
|
1663
|
+
.field="${field}"
|
|
1664
|
+
.conceptId="${this.concept.id}"
|
|
1665
|
+
.columnId="${column.id}"
|
|
1666
|
+
.value="${this._getFieldValue(field)}"
|
|
1667
|
+
.disabled="${this.disabled}"
|
|
1668
|
+
.locale="${this.locale}"
|
|
1669
|
+
.hideLabel="${true}"
|
|
1670
|
+
@field-change="${this._handleFieldChange}"
|
|
1671
|
+
></jupiter-form-field>
|
|
1672
|
+
` : ""}
|
|
1673
|
+
</td>
|
|
1674
|
+
`;
|
|
1277
1675
|
})}
|
|
1278
|
-
</div>
|
|
1279
|
-
|
|
1280
|
-
<!-- Children Concepts -->
|
|
1281
|
-
${hasChildren ? html`
|
|
1282
|
-
<div class="children ${!this._expanded ? "collapsed" : ""}">
|
|
1283
|
-
${this.concept.children.map((child) => html`
|
|
1284
|
-
<jupiter-concept-tree
|
|
1285
|
-
.concept="${child}"
|
|
1286
|
-
.columns="${this.columns}"
|
|
1287
|
-
.formData="${this.formData}"
|
|
1288
|
-
.disabled="${this.disabled}"
|
|
1289
|
-
.locale="${this.locale}"
|
|
1290
|
-
@field-change="${this._handleFieldChange}"
|
|
1291
|
-
@concept-expand="${(e2) => {
|
|
1292
|
-
e2.stopPropagation();
|
|
1293
|
-
this.dispatchEvent(new CustomEvent("concept-expand", { detail: e2.detail, bubbles: true }));
|
|
1294
|
-
}}"
|
|
1295
|
-
></jupiter-concept-tree>
|
|
1296
|
-
`)}
|
|
1297
|
-
</div>
|
|
1298
|
-
` : ""}
|
|
1299
1676
|
`;
|
|
1300
1677
|
}
|
|
1301
1678
|
};
|
|
1302
1679
|
JupiterConceptTree.styles = css`
|
|
1303
1680
|
:host {
|
|
1304
|
-
|
|
1305
|
-
}
|
|
1306
|
-
|
|
1307
|
-
.concept-row {
|
|
1681
|
+
/* Component renders table cells directly */
|
|
1308
1682
|
display: contents;
|
|
1309
1683
|
}
|
|
1310
1684
|
|
|
1311
|
-
.concept-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
padding: 8px 12px;
|
|
1315
|
-
background: var(--jupiter-concept-background, #f8f9fa);
|
|
1685
|
+
.concept-name-cell {
|
|
1686
|
+
vertical-align: top;
|
|
1687
|
+
padding: 2px 4px;
|
|
1316
1688
|
border: 1px solid var(--jupiter-border-color, #ddd);
|
|
1317
1689
|
border-bottom: none;
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1690
|
+
background: var(--jupiter-concept-background, #f8f9fa);
|
|
1691
|
+
position: sticky;
|
|
1692
|
+
left: 0;
|
|
1693
|
+
z-index: 1;
|
|
1694
|
+
width: 300px;
|
|
1695
|
+
min-width: 300px;
|
|
1696
|
+
max-width: 300px;
|
|
1697
|
+
}
|
|
1698
|
+
|
|
1699
|
+
.concept-name-cell.abstract {
|
|
1700
|
+
background: var(--jupiter-abstract-background, #f0f2f5);
|
|
1701
|
+
font-weight: 600;
|
|
1702
|
+
}
|
|
1703
|
+
|
|
1704
|
+
.concept-name-cell.leaf {
|
|
1705
|
+
background: var(--jupiter-leaf-background, #fff);
|
|
1706
|
+
font-weight: 400;
|
|
1321
1707
|
}
|
|
1322
1708
|
|
|
1323
|
-
.concept-
|
|
1324
|
-
|
|
1709
|
+
.concept-content {
|
|
1710
|
+
display: flex;
|
|
1711
|
+
align-items: center;
|
|
1712
|
+
min-height: 28px;
|
|
1713
|
+
font-size: 13px;
|
|
1714
|
+
line-height: 1.3;
|
|
1715
|
+
width: 100%;
|
|
1716
|
+
overflow: hidden;
|
|
1325
1717
|
}
|
|
1326
1718
|
|
|
1327
1719
|
.concept-indent {
|
|
1328
|
-
width: calc(var(--level, 0) *
|
|
1720
|
+
width: calc(var(--level, 0) * 16px);
|
|
1329
1721
|
flex-shrink: 0;
|
|
1330
1722
|
}
|
|
1331
1723
|
|
|
1332
1724
|
.concept-toggle {
|
|
1333
|
-
width:
|
|
1334
|
-
height:
|
|
1335
|
-
margin-right:
|
|
1725
|
+
width: 14px;
|
|
1726
|
+
height: 14px;
|
|
1727
|
+
margin-right: 6px;
|
|
1336
1728
|
display: flex;
|
|
1337
1729
|
align-items: center;
|
|
1338
1730
|
justify-content: center;
|
|
1339
|
-
font-size:
|
|
1731
|
+
font-size: 10px;
|
|
1340
1732
|
transition: transform 0.2s ease;
|
|
1733
|
+
cursor: pointer;
|
|
1341
1734
|
}
|
|
1342
1735
|
|
|
1343
1736
|
.concept-toggle.expanded {
|
|
@@ -1351,71 +1744,390 @@ JupiterConceptTree.styles = css`
|
|
|
1351
1744
|
.concept-label {
|
|
1352
1745
|
flex: 1;
|
|
1353
1746
|
color: var(--jupiter-text-primary, #333);
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
margin-left: 8px;
|
|
1361
|
-
}
|
|
1362
|
-
|
|
1363
|
-
.concept-fields {
|
|
1364
|
-
display: contents;
|
|
1747
|
+
cursor: pointer;
|
|
1748
|
+
word-wrap: break-word;
|
|
1749
|
+
overflow-wrap: break-word;
|
|
1750
|
+
hyphens: auto;
|
|
1751
|
+
line-height: 1.3;
|
|
1752
|
+
min-width: 0; /* Allows flex item to shrink below content size */
|
|
1365
1753
|
}
|
|
1366
1754
|
|
|
1367
1755
|
.field-cell {
|
|
1756
|
+
vertical-align: middle;
|
|
1757
|
+
padding: 2px 6px;
|
|
1368
1758
|
border: 1px solid var(--jupiter-border-color, #ddd);
|
|
1369
1759
|
border-bottom: none;
|
|
1370
|
-
padding: 8px;
|
|
1371
1760
|
background: var(--jupiter-cell-background, #fff);
|
|
1372
|
-
min-height:
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
.field-cell:last-child {
|
|
1378
|
-
border-right: 1px solid var(--jupiter-border-color, #ddd);
|
|
1761
|
+
min-height: 28px;
|
|
1762
|
+
text-align: center;
|
|
1763
|
+
min-width: 180px;
|
|
1764
|
+
width: 180px;
|
|
1379
1765
|
}
|
|
1380
1766
|
|
|
1381
1767
|
.field-cell.empty {
|
|
1382
1768
|
background: var(--jupiter-empty-cell-background, #f8f9fa);
|
|
1383
1769
|
}
|
|
1384
1770
|
|
|
1385
|
-
.
|
|
1386
|
-
|
|
1771
|
+
.field-cell.abstract-row {
|
|
1772
|
+
background: var(--jupiter-abstract-cell-background, #f0f2f5);
|
|
1387
1773
|
}
|
|
1388
1774
|
|
|
1389
|
-
|
|
1775
|
+
/* Children are rendered as separate table rows, not nested */
|
|
1776
|
+
.children-wrapper {
|
|
1390
1777
|
display: none;
|
|
1391
1778
|
}
|
|
1392
|
-
|
|
1393
|
-
.concept-row:last-of-type .concept-header,
|
|
1394
|
-
.concept-row:last-of-type .field-cell {
|
|
1395
|
-
border-bottom: 1px solid var(--jupiter-border-color, #ddd);
|
|
1396
|
-
}
|
|
1397
1779
|
`;
|
|
1398
|
-
__decorateClass$
|
|
1780
|
+
__decorateClass$3([
|
|
1399
1781
|
n2({ type: Object })
|
|
1400
1782
|
], JupiterConceptTree.prototype, "concept", 2);
|
|
1401
|
-
__decorateClass$
|
|
1783
|
+
__decorateClass$3([
|
|
1402
1784
|
n2({ type: Array })
|
|
1403
1785
|
], JupiterConceptTree.prototype, "columns", 2);
|
|
1404
|
-
__decorateClass$
|
|
1786
|
+
__decorateClass$3([
|
|
1405
1787
|
n2({ type: Object })
|
|
1406
1788
|
], JupiterConceptTree.prototype, "formData", 2);
|
|
1407
|
-
__decorateClass$
|
|
1789
|
+
__decorateClass$3([
|
|
1408
1790
|
n2({ type: Boolean })
|
|
1409
1791
|
], JupiterConceptTree.prototype, "disabled", 2);
|
|
1410
|
-
__decorateClass$
|
|
1792
|
+
__decorateClass$3([
|
|
1411
1793
|
n2({ type: String })
|
|
1412
1794
|
], JupiterConceptTree.prototype, "locale", 2);
|
|
1413
|
-
__decorateClass$
|
|
1795
|
+
__decorateClass$3([
|
|
1796
|
+
n2({ type: Set })
|
|
1797
|
+
], JupiterConceptTree.prototype, "expandedConcepts", 2);
|
|
1798
|
+
__decorateClass$3([
|
|
1414
1799
|
r()
|
|
1415
1800
|
], JupiterConceptTree.prototype, "_expanded", 2);
|
|
1416
|
-
JupiterConceptTree = __decorateClass$
|
|
1801
|
+
JupiterConceptTree = __decorateClass$3([
|
|
1417
1802
|
t$1("jupiter-concept-tree")
|
|
1418
1803
|
], JupiterConceptTree);
|
|
1804
|
+
var __defProp$2 = Object.defineProperty;
|
|
1805
|
+
var __getOwnPropDesc$2 = Object.getOwnPropertyDescriptor;
|
|
1806
|
+
var __decorateClass$2 = (decorators, target, key, kind) => {
|
|
1807
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$2(target, key) : target;
|
|
1808
|
+
for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
|
|
1809
|
+
if (decorator = decorators[i2])
|
|
1810
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
1811
|
+
if (kind && result)
|
|
1812
|
+
__defProp$2(target, key, result);
|
|
1813
|
+
return result;
|
|
1814
|
+
};
|
|
1815
|
+
let JupiterAddColumnDialog = class extends LitElement {
|
|
1816
|
+
constructor() {
|
|
1817
|
+
super(...arguments);
|
|
1818
|
+
this.periodType = "duration";
|
|
1819
|
+
this.open = false;
|
|
1820
|
+
this._startDate = "";
|
|
1821
|
+
this._endDate = "";
|
|
1822
|
+
this._instantDate = "";
|
|
1823
|
+
this._selectedType = "duration";
|
|
1824
|
+
}
|
|
1825
|
+
updated(changedProperties) {
|
|
1826
|
+
if (changedProperties.has("open") && this.open) {
|
|
1827
|
+
this._resetForm();
|
|
1828
|
+
}
|
|
1829
|
+
}
|
|
1830
|
+
connectedCallback() {
|
|
1831
|
+
super.connectedCallback();
|
|
1832
|
+
this._resetForm();
|
|
1833
|
+
}
|
|
1834
|
+
willUpdate(changedProperties) {
|
|
1835
|
+
super.willUpdate(changedProperties);
|
|
1836
|
+
if (changedProperties.has("open") && this.open) {
|
|
1837
|
+
this._resetForm();
|
|
1838
|
+
}
|
|
1839
|
+
}
|
|
1840
|
+
_resetForm() {
|
|
1841
|
+
const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
1842
|
+
this._startDate = today;
|
|
1843
|
+
this._endDate = today;
|
|
1844
|
+
this._instantDate = today;
|
|
1845
|
+
this._selectedType = "duration";
|
|
1846
|
+
}
|
|
1847
|
+
_handleCancel() {
|
|
1848
|
+
this.open = false;
|
|
1849
|
+
this.dispatchEvent(new CustomEvent("dialog-cancel", { bubbles: true }));
|
|
1850
|
+
}
|
|
1851
|
+
_handleConfirm() {
|
|
1852
|
+
if (!this._isFormValid())
|
|
1853
|
+
return;
|
|
1854
|
+
const request = {
|
|
1855
|
+
periodType: this.periodType === "mixed" ? this._selectedType : this.periodType
|
|
1856
|
+
};
|
|
1857
|
+
if (this.periodType === "instant" || this.periodType === "mixed" && this._selectedType === "instant") {
|
|
1858
|
+
request.instantDate = this._instantDate;
|
|
1859
|
+
} else {
|
|
1860
|
+
request.startDate = this._startDate;
|
|
1861
|
+
request.endDate = this._endDate;
|
|
1862
|
+
}
|
|
1863
|
+
this.dispatchEvent(new CustomEvent("column-add", {
|
|
1864
|
+
detail: request,
|
|
1865
|
+
bubbles: true
|
|
1866
|
+
}));
|
|
1867
|
+
}
|
|
1868
|
+
_isFormValid() {
|
|
1869
|
+
if (this.periodType === "mixed") {
|
|
1870
|
+
if (this._selectedType === "instant") {
|
|
1871
|
+
return !!this._instantDate;
|
|
1872
|
+
} else {
|
|
1873
|
+
return !!this._startDate && !!this._endDate && this._startDate <= this._endDate;
|
|
1874
|
+
}
|
|
1875
|
+
} else if (this.periodType === "duration") {
|
|
1876
|
+
return !!this._startDate && !!this._endDate && this._startDate <= this._endDate;
|
|
1877
|
+
} else if (this.periodType === "instant") {
|
|
1878
|
+
return !!this._instantDate;
|
|
1879
|
+
}
|
|
1880
|
+
return false;
|
|
1881
|
+
}
|
|
1882
|
+
_handleStartDateChange(e2) {
|
|
1883
|
+
this._startDate = e2.target.value;
|
|
1884
|
+
}
|
|
1885
|
+
_handleEndDateChange(e2) {
|
|
1886
|
+
this._endDate = e2.target.value;
|
|
1887
|
+
}
|
|
1888
|
+
_handleSelectedTypeChange(e2) {
|
|
1889
|
+
this._selectedType = e2.target.value;
|
|
1890
|
+
}
|
|
1891
|
+
_handleInstantDateChange(e2) {
|
|
1892
|
+
this._instantDate = e2.target.value;
|
|
1893
|
+
}
|
|
1894
|
+
render() {
|
|
1895
|
+
if (!this.open)
|
|
1896
|
+
return html``;
|
|
1897
|
+
const isValid = this._isFormValid();
|
|
1898
|
+
return html`
|
|
1899
|
+
<div class="dialog" @click="${(e2) => e2.stopPropagation()}">
|
|
1900
|
+
<div class="dialog-header">
|
|
1901
|
+
<h2 class="dialog-title">Add Column</h2>
|
|
1902
|
+
<p class="dialog-description">
|
|
1903
|
+
${this.periodType === "instant" ? "Add a new instant period column by specifying the date." : this.periodType === "duration" ? "Add a new duration period column by specifying the start and end dates." : "This section contains both instant and duration concepts. Choose the type of column to add."}
|
|
1904
|
+
</p>
|
|
1905
|
+
</div>
|
|
1906
|
+
|
|
1907
|
+
<div class="dialog-content">
|
|
1908
|
+
${this.periodType === "mixed" ? html`
|
|
1909
|
+
<div class="form-group">
|
|
1910
|
+
<label class="form-label required">Column Type</label>
|
|
1911
|
+
<select
|
|
1912
|
+
class="form-input"
|
|
1913
|
+
.value="${this._selectedType}"
|
|
1914
|
+
@change="${this._handleSelectedTypeChange}"
|
|
1915
|
+
required
|
|
1916
|
+
>
|
|
1917
|
+
<option value="instant">Instant (single date)</option>
|
|
1918
|
+
<option value="duration">Duration (start and end dates)</option>
|
|
1919
|
+
</select>
|
|
1920
|
+
</div>
|
|
1921
|
+
` : ""}
|
|
1922
|
+
|
|
1923
|
+
${this.periodType === "instant" || this.periodType === "mixed" && this._selectedType === "instant" ? html`
|
|
1924
|
+
<div class="form-group">
|
|
1925
|
+
<label class="form-label required">Instant Date</label>
|
|
1926
|
+
<input
|
|
1927
|
+
type="date"
|
|
1928
|
+
class="form-input"
|
|
1929
|
+
.value="${this._instantDate}"
|
|
1930
|
+
@change="${this._handleInstantDateChange}"
|
|
1931
|
+
required
|
|
1932
|
+
/>
|
|
1933
|
+
</div>
|
|
1934
|
+
` : html`
|
|
1935
|
+
<div class="form-group">
|
|
1936
|
+
<label class="form-label required">Start Period Date</label>
|
|
1937
|
+
<input
|
|
1938
|
+
type="date"
|
|
1939
|
+
class="form-input"
|
|
1940
|
+
.value="${this._startDate}"
|
|
1941
|
+
@change="${this._handleStartDateChange}"
|
|
1942
|
+
required
|
|
1943
|
+
/>
|
|
1944
|
+
</div>
|
|
1945
|
+
<div class="form-group">
|
|
1946
|
+
<label class="form-label required">End Period Date</label>
|
|
1947
|
+
<input
|
|
1948
|
+
type="date"
|
|
1949
|
+
class="form-input"
|
|
1950
|
+
.value="${this._endDate}"
|
|
1951
|
+
@change="${this._handleEndDateChange}"
|
|
1952
|
+
required
|
|
1953
|
+
/>
|
|
1954
|
+
</div>
|
|
1955
|
+
`}
|
|
1956
|
+
</div>
|
|
1957
|
+
|
|
1958
|
+
<div class="dialog-actions">
|
|
1959
|
+
<button class="btn btn-cancel" @click="${this._handleCancel}">
|
|
1960
|
+
Cancel
|
|
1961
|
+
</button>
|
|
1962
|
+
<button
|
|
1963
|
+
class="btn btn-primary"
|
|
1964
|
+
?disabled="${!isValid}"
|
|
1965
|
+
@click="${this._handleConfirm}"
|
|
1966
|
+
>
|
|
1967
|
+
Add Column
|
|
1968
|
+
</button>
|
|
1969
|
+
</div>
|
|
1970
|
+
</div>
|
|
1971
|
+
`;
|
|
1972
|
+
}
|
|
1973
|
+
};
|
|
1974
|
+
JupiterAddColumnDialog.styles = css`
|
|
1975
|
+
:host {
|
|
1976
|
+
position: fixed;
|
|
1977
|
+
top: 0;
|
|
1978
|
+
left: 0;
|
|
1979
|
+
width: 100%;
|
|
1980
|
+
height: 100%;
|
|
1981
|
+
background: rgba(0, 0, 0, 0.5);
|
|
1982
|
+
z-index: 1000;
|
|
1983
|
+
display: flex;
|
|
1984
|
+
align-items: center;
|
|
1985
|
+
justify-content: center;
|
|
1986
|
+
opacity: 0;
|
|
1987
|
+
visibility: hidden;
|
|
1988
|
+
transition: opacity 0.3s ease, visibility 0.3s ease;
|
|
1989
|
+
}
|
|
1990
|
+
|
|
1991
|
+
:host([open]) {
|
|
1992
|
+
opacity: 1;
|
|
1993
|
+
visibility: visible;
|
|
1994
|
+
}
|
|
1995
|
+
|
|
1996
|
+
.dialog {
|
|
1997
|
+
background: white;
|
|
1998
|
+
border-radius: 8px;
|
|
1999
|
+
padding: 24px;
|
|
2000
|
+
min-width: 400px;
|
|
2001
|
+
max-width: 500px;
|
|
2002
|
+
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
|
|
2003
|
+
transform: scale(0.9);
|
|
2004
|
+
transition: transform 0.3s ease;
|
|
2005
|
+
}
|
|
2006
|
+
|
|
2007
|
+
:host([open]) .dialog {
|
|
2008
|
+
transform: scale(1);
|
|
2009
|
+
}
|
|
2010
|
+
|
|
2011
|
+
.dialog-header {
|
|
2012
|
+
margin-bottom: 20px;
|
|
2013
|
+
}
|
|
2014
|
+
|
|
2015
|
+
.dialog-title {
|
|
2016
|
+
font-size: 20px;
|
|
2017
|
+
font-weight: 600;
|
|
2018
|
+
color: var(--jupiter-text-primary, #333);
|
|
2019
|
+
margin: 0 0 8px 0;
|
|
2020
|
+
}
|
|
2021
|
+
|
|
2022
|
+
.dialog-description {
|
|
2023
|
+
font-size: 14px;
|
|
2024
|
+
color: var(--jupiter-text-secondary, #666);
|
|
2025
|
+
margin: 0;
|
|
2026
|
+
}
|
|
2027
|
+
|
|
2028
|
+
.dialog-content {
|
|
2029
|
+
margin-bottom: 24px;
|
|
2030
|
+
}
|
|
2031
|
+
|
|
2032
|
+
.form-group {
|
|
2033
|
+
margin-bottom: 16px;
|
|
2034
|
+
}
|
|
2035
|
+
|
|
2036
|
+
.form-label {
|
|
2037
|
+
display: block;
|
|
2038
|
+
font-weight: 500;
|
|
2039
|
+
margin-bottom: 6px;
|
|
2040
|
+
color: var(--jupiter-text-primary, #333);
|
|
2041
|
+
font-size: 14px;
|
|
2042
|
+
}
|
|
2043
|
+
|
|
2044
|
+
.form-label.required::after {
|
|
2045
|
+
content: ' *';
|
|
2046
|
+
color: var(--jupiter-error-color, #d32f2f);
|
|
2047
|
+
}
|
|
2048
|
+
|
|
2049
|
+
.form-input {
|
|
2050
|
+
width: 100%;
|
|
2051
|
+
box-sizing: border-box;
|
|
2052
|
+
padding: 10px 12px;
|
|
2053
|
+
border: 1px solid var(--jupiter-border-color, #ddd);
|
|
2054
|
+
border-radius: 4px;
|
|
2055
|
+
font-size: 14px;
|
|
2056
|
+
font-family: inherit;
|
|
2057
|
+
transition: border-color 0.2s ease;
|
|
2058
|
+
}
|
|
2059
|
+
|
|
2060
|
+
.form-input:focus {
|
|
2061
|
+
outline: none;
|
|
2062
|
+
border-color: var(--jupiter-primary-color, #007bff);
|
|
2063
|
+
box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25);
|
|
2064
|
+
}
|
|
2065
|
+
|
|
2066
|
+
select.form-input {
|
|
2067
|
+
cursor: pointer;
|
|
2068
|
+
background-color: white;
|
|
2069
|
+
}
|
|
2070
|
+
|
|
2071
|
+
.dialog-actions {
|
|
2072
|
+
display: flex;
|
|
2073
|
+
gap: 12px;
|
|
2074
|
+
justify-content: flex-end;
|
|
2075
|
+
}
|
|
2076
|
+
|
|
2077
|
+
.btn {
|
|
2078
|
+
padding: 10px 20px;
|
|
2079
|
+
border: none;
|
|
2080
|
+
border-radius: 4px;
|
|
2081
|
+
font-size: 14px;
|
|
2082
|
+
font-weight: 500;
|
|
2083
|
+
cursor: pointer;
|
|
2084
|
+
transition: background-color 0.2s ease;
|
|
2085
|
+
}
|
|
2086
|
+
|
|
2087
|
+
.btn-cancel {
|
|
2088
|
+
background: var(--jupiter-neutral-background, #f5f5f5);
|
|
2089
|
+
color: var(--jupiter-text-primary, #333);
|
|
2090
|
+
}
|
|
2091
|
+
|
|
2092
|
+
.btn-cancel:hover {
|
|
2093
|
+
background: var(--jupiter-neutral-background-hover, #e0e0e0);
|
|
2094
|
+
}
|
|
2095
|
+
|
|
2096
|
+
.btn-primary {
|
|
2097
|
+
background: var(--jupiter-primary-color, #667eea);
|
|
2098
|
+
color: white;
|
|
2099
|
+
}
|
|
2100
|
+
|
|
2101
|
+
.btn-primary:hover {
|
|
2102
|
+
background: var(--jupiter-primary-color-dark, #5a6fd8);
|
|
2103
|
+
}
|
|
2104
|
+
|
|
2105
|
+
.btn-primary:disabled {
|
|
2106
|
+
background: var(--jupiter-disabled-background, #ccc);
|
|
2107
|
+
cursor: not-allowed;
|
|
2108
|
+
}
|
|
2109
|
+
`;
|
|
2110
|
+
__decorateClass$2([
|
|
2111
|
+
n2({ type: String })
|
|
2112
|
+
], JupiterAddColumnDialog.prototype, "periodType", 2);
|
|
2113
|
+
__decorateClass$2([
|
|
2114
|
+
n2({ type: Boolean })
|
|
2115
|
+
], JupiterAddColumnDialog.prototype, "open", 2);
|
|
2116
|
+
__decorateClass$2([
|
|
2117
|
+
r()
|
|
2118
|
+
], JupiterAddColumnDialog.prototype, "_startDate", 2);
|
|
2119
|
+
__decorateClass$2([
|
|
2120
|
+
r()
|
|
2121
|
+
], JupiterAddColumnDialog.prototype, "_endDate", 2);
|
|
2122
|
+
__decorateClass$2([
|
|
2123
|
+
r()
|
|
2124
|
+
], JupiterAddColumnDialog.prototype, "_instantDate", 2);
|
|
2125
|
+
__decorateClass$2([
|
|
2126
|
+
r()
|
|
2127
|
+
], JupiterAddColumnDialog.prototype, "_selectedType", 2);
|
|
2128
|
+
JupiterAddColumnDialog = __decorateClass$2([
|
|
2129
|
+
t$1("jupiter-add-column-dialog")
|
|
2130
|
+
], JupiterAddColumnDialog);
|
|
1419
2131
|
var __defProp$1 = Object.defineProperty;
|
|
1420
2132
|
var __getOwnPropDesc$1 = Object.getOwnPropertyDescriptor;
|
|
1421
2133
|
var __decorateClass$1 = (decorators, target, key, kind) => {
|
|
@@ -1436,10 +2148,58 @@ let JupiterFormSection = class extends LitElement {
|
|
|
1436
2148
|
this.collapsible = true;
|
|
1437
2149
|
this.locale = "en-US";
|
|
1438
2150
|
this._expanded = true;
|
|
2151
|
+
this._showAddColumnDialog = false;
|
|
2152
|
+
this._sectionPeriodType = "duration";
|
|
2153
|
+
this._expandedConcepts = /* @__PURE__ */ new Set();
|
|
1439
2154
|
}
|
|
1440
2155
|
connectedCallback() {
|
|
1441
2156
|
super.connectedCallback();
|
|
1442
2157
|
this._expanded = this.section.expanded !== false;
|
|
2158
|
+
this._determinePeriodType();
|
|
2159
|
+
}
|
|
2160
|
+
_determinePeriodType() {
|
|
2161
|
+
const nonAbstractConcepts = this._getAllNonAbstractConcepts(this.section.concepts);
|
|
2162
|
+
console.log(`🔍 Section ${this.section.id} (${this.section.title}): Found ${nonAbstractConcepts.length} non-abstract concepts`);
|
|
2163
|
+
console.log(`📝 All concepts in section:`, this.section.concepts.map((c2) => ({
|
|
2164
|
+
name: c2.name,
|
|
2165
|
+
abstract: c2.abstract,
|
|
2166
|
+
periodType: c2.periodType
|
|
2167
|
+
})));
|
|
2168
|
+
if (nonAbstractConcepts.length === 0) {
|
|
2169
|
+
this._sectionPeriodType = "duration";
|
|
2170
|
+
console.log(`📊 Section ${this.section.id}: No concepts, defaulting to duration`);
|
|
2171
|
+
return;
|
|
2172
|
+
}
|
|
2173
|
+
const periodTypes = new Set(nonAbstractConcepts.map((c2) => c2.periodType).filter(Boolean));
|
|
2174
|
+
console.log(`🏷️ Section ${this.section.id}: Found period types:`, Array.from(periodTypes));
|
|
2175
|
+
console.log(
|
|
2176
|
+
`📝 Section ${this.section.id}: Non-abstract concepts and their period types:`,
|
|
2177
|
+
nonAbstractConcepts.map((c2) => ({ name: c2.name, periodType: c2.periodType, abstract: c2.abstract }))
|
|
2178
|
+
);
|
|
2179
|
+
if (periodTypes.size === 0) {
|
|
2180
|
+
this._sectionPeriodType = "duration";
|
|
2181
|
+
console.log(`📊 Section ${this.section.id}: No period types defined, defaulting to duration`);
|
|
2182
|
+
} else if (periodTypes.size === 1) {
|
|
2183
|
+
const singleType = Array.from(periodTypes)[0];
|
|
2184
|
+
this._sectionPeriodType = singleType === "instant" ? "instant" : "duration";
|
|
2185
|
+
console.log(`📊 Section ${this.section.id}: Single period type '${singleType}', setting to '${this._sectionPeriodType}'`);
|
|
2186
|
+
} else {
|
|
2187
|
+
this._sectionPeriodType = "mixed";
|
|
2188
|
+
console.log(`📊 Section ${this.section.id}: Mixed period types, setting to 'mixed'`);
|
|
2189
|
+
}
|
|
2190
|
+
console.log(`✅ Section ${this.section.id}: Final period type: ${this._sectionPeriodType}`);
|
|
2191
|
+
}
|
|
2192
|
+
_getAllNonAbstractConcepts(concepts) {
|
|
2193
|
+
const result = [];
|
|
2194
|
+
for (const concept of concepts) {
|
|
2195
|
+
if (!concept.abstract) {
|
|
2196
|
+
result.push(concept);
|
|
2197
|
+
}
|
|
2198
|
+
if (concept.children) {
|
|
2199
|
+
result.push(...this._getAllNonAbstractConcepts(concept.children));
|
|
2200
|
+
}
|
|
2201
|
+
}
|
|
2202
|
+
return result;
|
|
1443
2203
|
}
|
|
1444
2204
|
_toggleExpanded() {
|
|
1445
2205
|
if (!this.collapsible)
|
|
@@ -1455,7 +2215,58 @@ let JupiterFormSection = class extends LitElement {
|
|
|
1455
2215
|
}
|
|
1456
2216
|
_handleRemoveColumn(columnId) {
|
|
1457
2217
|
this.dispatchEvent(new CustomEvent("column-remove", {
|
|
1458
|
-
detail: {
|
|
2218
|
+
detail: {
|
|
2219
|
+
columnId,
|
|
2220
|
+
sectionId: this.section.id
|
|
2221
|
+
},
|
|
2222
|
+
bubbles: true
|
|
2223
|
+
}));
|
|
2224
|
+
}
|
|
2225
|
+
_handleAddColumn() {
|
|
2226
|
+
const buttonPeriodType = this._determineButtonPeriodType();
|
|
2227
|
+
this._sectionPeriodType = buttonPeriodType;
|
|
2228
|
+
this._showAddColumnDialog = true;
|
|
2229
|
+
}
|
|
2230
|
+
_determineButtonPeriodType() {
|
|
2231
|
+
const allNonAbstractConcepts = this._getAllNonAbstractConcepts(this.section.concepts);
|
|
2232
|
+
if (allNonAbstractConcepts.length === 0) {
|
|
2233
|
+
return "duration";
|
|
2234
|
+
}
|
|
2235
|
+
const periodTypes = new Set(
|
|
2236
|
+
allNonAbstractConcepts.map((c2) => c2.periodType).filter((periodType) => periodType !== void 0 && periodType !== null)
|
|
2237
|
+
);
|
|
2238
|
+
if (periodTypes.size === 0) {
|
|
2239
|
+
return "duration";
|
|
2240
|
+
} else if (periodTypes.size === 1) {
|
|
2241
|
+
const singleType = Array.from(periodTypes)[0];
|
|
2242
|
+
return singleType === "instant" ? "instant" : "duration";
|
|
2243
|
+
} else {
|
|
2244
|
+
return "mixed";
|
|
2245
|
+
}
|
|
2246
|
+
}
|
|
2247
|
+
_getConceptsWithFields(concepts) {
|
|
2248
|
+
const result = [];
|
|
2249
|
+
for (const concept of concepts) {
|
|
2250
|
+
if (!concept.abstract && concept.fields && concept.fields.length > 0) {
|
|
2251
|
+
result.push(concept);
|
|
2252
|
+
}
|
|
2253
|
+
if (concept.children) {
|
|
2254
|
+
result.push(...this._getConceptsWithFields(concept.children));
|
|
2255
|
+
}
|
|
2256
|
+
}
|
|
2257
|
+
return result;
|
|
2258
|
+
}
|
|
2259
|
+
_handleDialogCancel() {
|
|
2260
|
+
this._showAddColumnDialog = false;
|
|
2261
|
+
}
|
|
2262
|
+
_handleColumnAdd(event) {
|
|
2263
|
+
event.stopPropagation();
|
|
2264
|
+
this._showAddColumnDialog = false;
|
|
2265
|
+
this.dispatchEvent(new CustomEvent("column-add-request", {
|
|
2266
|
+
detail: {
|
|
2267
|
+
sectionId: this.section.id,
|
|
2268
|
+
columnRequest: event.detail
|
|
2269
|
+
},
|
|
1459
2270
|
bubbles: true
|
|
1460
2271
|
}));
|
|
1461
2272
|
}
|
|
@@ -1466,8 +2277,26 @@ let JupiterFormSection = class extends LitElement {
|
|
|
1466
2277
|
bubbles: true
|
|
1467
2278
|
}));
|
|
1468
2279
|
}
|
|
2280
|
+
_flattenConcepts(concepts, expanded = /* @__PURE__ */ new Set()) {
|
|
2281
|
+
const result = [];
|
|
2282
|
+
for (const concept of concepts) {
|
|
2283
|
+
result.push(concept);
|
|
2284
|
+
if (concept.children && concept.children.length > 0 && expanded.has(concept.id)) {
|
|
2285
|
+
const childrenFlattened = this._flattenConcepts(concept.children, expanded);
|
|
2286
|
+
result.push(...childrenFlattened);
|
|
2287
|
+
}
|
|
2288
|
+
}
|
|
2289
|
+
return result;
|
|
2290
|
+
}
|
|
1469
2291
|
_handleConceptExpand(event) {
|
|
1470
2292
|
event.stopPropagation();
|
|
2293
|
+
const { conceptId, expanded } = event.detail;
|
|
2294
|
+
if (expanded) {
|
|
2295
|
+
this._expandedConcepts.add(conceptId);
|
|
2296
|
+
} else {
|
|
2297
|
+
this._expandedConcepts.delete(conceptId);
|
|
2298
|
+
}
|
|
2299
|
+
this.requestUpdate();
|
|
1471
2300
|
this.dispatchEvent(new CustomEvent("concept-expand", {
|
|
1472
2301
|
detail: event.detail,
|
|
1473
2302
|
bubbles: true
|
|
@@ -1514,7 +2343,7 @@ let JupiterFormSection = class extends LitElement {
|
|
|
1514
2343
|
<div class="table-container">
|
|
1515
2344
|
<table class="form-table">
|
|
1516
2345
|
<thead class="table-header">
|
|
1517
|
-
<tr>
|
|
2346
|
+
<tr class="header-row">
|
|
1518
2347
|
<th class="header-cell concept-column">Concept</th>
|
|
1519
2348
|
${this.columns.map((column) => html`
|
|
1520
2349
|
<th class="header-cell ${column.removable ? "removable" : ""}">
|
|
@@ -1532,24 +2361,43 @@ let JupiterFormSection = class extends LitElement {
|
|
|
1532
2361
|
` : ""}
|
|
1533
2362
|
</th>
|
|
1534
2363
|
`)}
|
|
2364
|
+
<th class="header-cell">
|
|
2365
|
+
<button class="add-column-btn" @click="${(e2) => {
|
|
2366
|
+
e2.stopPropagation();
|
|
2367
|
+
this._handleAddColumn();
|
|
2368
|
+
}}" title="Add Column">
|
|
2369
|
+
+ Add Column
|
|
2370
|
+
</button>
|
|
2371
|
+
</th>
|
|
1535
2372
|
</tr>
|
|
1536
2373
|
</thead>
|
|
1537
2374
|
<tbody class="table-body">
|
|
1538
|
-
${this.section.concepts.map((concept) => html`
|
|
1539
|
-
<
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
2375
|
+
${this._flattenConcepts(this.section.concepts, this._expandedConcepts).map((concept) => html`
|
|
2376
|
+
<tr>
|
|
2377
|
+
<jupiter-concept-tree
|
|
2378
|
+
.concept="${concept}"
|
|
2379
|
+
.columns="${this.columns}"
|
|
2380
|
+
.formData="${this.formData}"
|
|
2381
|
+
.disabled="${this.disabled}"
|
|
2382
|
+
.locale="${this.locale}"
|
|
2383
|
+
.expandedConcepts="${this._expandedConcepts}"
|
|
2384
|
+
@field-change="${this._handleFieldChange}"
|
|
2385
|
+
@concept-expand="${this._handleConceptExpand}"
|
|
2386
|
+
></jupiter-concept-tree>
|
|
2387
|
+
</tr>
|
|
1548
2388
|
`)}
|
|
1549
2389
|
</tbody>
|
|
1550
2390
|
</table>
|
|
1551
2391
|
</div>
|
|
1552
2392
|
</div>
|
|
2393
|
+
|
|
2394
|
+
<!-- Add Column Dialog -->
|
|
2395
|
+
<jupiter-add-column-dialog
|
|
2396
|
+
.periodType="${this._sectionPeriodType}"
|
|
2397
|
+
?open="${this._showAddColumnDialog}"
|
|
2398
|
+
@dialog-cancel="${this._handleDialogCancel}"
|
|
2399
|
+
@column-add="${this._handleColumnAdd}"
|
|
2400
|
+
></jupiter-add-column-dialog>
|
|
1553
2401
|
`;
|
|
1554
2402
|
}
|
|
1555
2403
|
};
|
|
@@ -1633,7 +2481,8 @@ JupiterFormSection.styles = css`
|
|
|
1633
2481
|
|
|
1634
2482
|
.form-table {
|
|
1635
2483
|
width: 100%;
|
|
1636
|
-
border-collapse:
|
|
2484
|
+
border-collapse: separate;
|
|
2485
|
+
border-spacing: 0;
|
|
1637
2486
|
background: var(--jupiter-table-background, #fff);
|
|
1638
2487
|
}
|
|
1639
2488
|
|
|
@@ -1644,18 +2493,27 @@ JupiterFormSection.styles = css`
|
|
|
1644
2493
|
z-index: 1;
|
|
1645
2494
|
}
|
|
1646
2495
|
|
|
2496
|
+
.header-row {
|
|
2497
|
+
/* Table row - no special display needed */
|
|
2498
|
+
}
|
|
2499
|
+
|
|
1647
2500
|
.header-cell {
|
|
1648
|
-
padding: 12px;
|
|
2501
|
+
padding: 8px 12px;
|
|
1649
2502
|
text-align: left;
|
|
1650
2503
|
font-weight: 600;
|
|
1651
2504
|
color: var(--jupiter-text-primary, #333);
|
|
1652
2505
|
border: 1px solid var(--jupiter-border-color, #ddd);
|
|
1653
2506
|
background: var(--jupiter-header-background, #f8f9fa);
|
|
1654
|
-
min-width:
|
|
2507
|
+
min-width: 180px;
|
|
2508
|
+
width: 180px;
|
|
2509
|
+
font-size: 14px;
|
|
2510
|
+
vertical-align: middle;
|
|
1655
2511
|
}
|
|
1656
2512
|
|
|
1657
2513
|
.header-cell.concept-column {
|
|
2514
|
+
width: 300px;
|
|
1658
2515
|
min-width: 300px;
|
|
2516
|
+
max-width: 300px;
|
|
1659
2517
|
position: sticky;
|
|
1660
2518
|
left: 0;
|
|
1661
2519
|
z-index: 2;
|
|
@@ -1686,8 +2544,19 @@ JupiterFormSection.styles = css`
|
|
|
1686
2544
|
background: var(--jupiter-error-color-dark, #b71c1c);
|
|
1687
2545
|
}
|
|
1688
2546
|
|
|
1689
|
-
.
|
|
1690
|
-
|
|
2547
|
+
.add-column-btn {
|
|
2548
|
+
background: var(--jupiter-primary-color, #667eea);
|
|
2549
|
+
color: white;
|
|
2550
|
+
border: none;
|
|
2551
|
+
padding: 8px 16px;
|
|
2552
|
+
border-radius: 4px;
|
|
2553
|
+
cursor: pointer;
|
|
2554
|
+
font-size: 12px;
|
|
2555
|
+
margin: 8px;
|
|
2556
|
+
}
|
|
2557
|
+
|
|
2558
|
+
.add-column-btn:hover {
|
|
2559
|
+
background: var(--jupiter-primary-color-dark, #5a6fd8);
|
|
1691
2560
|
}
|
|
1692
2561
|
|
|
1693
2562
|
.empty-section {
|
|
@@ -1718,6 +2587,15 @@ __decorateClass$1([
|
|
|
1718
2587
|
__decorateClass$1([
|
|
1719
2588
|
r()
|
|
1720
2589
|
], JupiterFormSection.prototype, "_expanded", 2);
|
|
2590
|
+
__decorateClass$1([
|
|
2591
|
+
r()
|
|
2592
|
+
], JupiterFormSection.prototype, "_showAddColumnDialog", 2);
|
|
2593
|
+
__decorateClass$1([
|
|
2594
|
+
r()
|
|
2595
|
+
], JupiterFormSection.prototype, "_sectionPeriodType", 2);
|
|
2596
|
+
__decorateClass$1([
|
|
2597
|
+
r()
|
|
2598
|
+
], JupiterFormSection.prototype, "_expandedConcepts", 2);
|
|
1721
2599
|
JupiterFormSection = __decorateClass$1([
|
|
1722
2600
|
t$1("jupiter-form-section")
|
|
1723
2601
|
], JupiterFormSection);
|
|
@@ -1873,21 +2751,208 @@ let JupiterDynamicForm = class extends LitElement {
|
|
|
1873
2751
|
}));
|
|
1874
2752
|
}
|
|
1875
2753
|
_handleColumnRemove(event) {
|
|
1876
|
-
const { columnId } = event.detail;
|
|
1877
|
-
this.
|
|
1878
|
-
|
|
1879
|
-
if (
|
|
1880
|
-
|
|
2754
|
+
const { columnId, sectionId } = event.detail;
|
|
2755
|
+
if (this._currentSchema && sectionId) {
|
|
2756
|
+
const targetSection = this._currentSchema.sections.find((section) => section.id === sectionId);
|
|
2757
|
+
if (targetSection && targetSection.columns) {
|
|
2758
|
+
targetSection.columns = targetSection.columns.filter((col) => col.id !== columnId);
|
|
2759
|
+
}
|
|
2760
|
+
} else {
|
|
2761
|
+
this._columns = this._columns.filter((col) => col.id !== columnId);
|
|
2762
|
+
if (this._currentSchema) {
|
|
2763
|
+
this._currentSchema.sections.forEach((section) => {
|
|
2764
|
+
if (section.columns) {
|
|
2765
|
+
section.columns = section.columns.filter((col) => col.id !== columnId);
|
|
2766
|
+
}
|
|
2767
|
+
});
|
|
1881
2768
|
}
|
|
1882
2769
|
}
|
|
2770
|
+
this._removeColumnData(columnId, sectionId);
|
|
1883
2771
|
this._dirty = true;
|
|
1884
2772
|
this._validateForm();
|
|
1885
2773
|
this.requestUpdate();
|
|
1886
2774
|
this.dispatchEvent(new CustomEvent("column-remove", {
|
|
1887
|
-
detail: { columnId },
|
|
2775
|
+
detail: { columnId, sectionId },
|
|
1888
2776
|
bubbles: true
|
|
1889
2777
|
}));
|
|
1890
2778
|
}
|
|
2779
|
+
_handleColumnAddRequest(event) {
|
|
2780
|
+
const { sectionId, columnRequest } = event.detail;
|
|
2781
|
+
this._addColumnFromRequest(columnRequest, sectionId);
|
|
2782
|
+
}
|
|
2783
|
+
_addColumnFromRequest(request, sectionId) {
|
|
2784
|
+
var _a, _b, _c, _d, _e;
|
|
2785
|
+
const timestamp = Date.now();
|
|
2786
|
+
const newColumnId = `col-${timestamp}`;
|
|
2787
|
+
let title = "";
|
|
2788
|
+
let description = "";
|
|
2789
|
+
if (request.periodType === "instant") {
|
|
2790
|
+
title = request.instantDate || "Instant Date";
|
|
2791
|
+
description = `Instant period: ${request.instantDate}`;
|
|
2792
|
+
} else if (request.periodType === "duration" || request.periodType === "mixed") {
|
|
2793
|
+
title = `${request.startDate} / ${request.endDate}`;
|
|
2794
|
+
description = `Duration period: ${request.startDate} to ${request.endDate}`;
|
|
2795
|
+
}
|
|
2796
|
+
let dimensionData = {
|
|
2797
|
+
dimensionId: "period",
|
|
2798
|
+
memberValue: request.periodType === "instant" ? `instant-${request.instantDate}` : `duration-${request.startDate}-${request.endDate}`,
|
|
2799
|
+
memberLabel: title
|
|
2800
|
+
};
|
|
2801
|
+
if ((_b = (_a = this.xbrlInput) == null ? void 0 : _a.hypercubes) == null ? void 0 : _b[0]) {
|
|
2802
|
+
const hypercubeRole = this.xbrlInput.hypercubes[0].roles.find((hr) => hr.roleId === sectionId);
|
|
2803
|
+
if (((_c = hypercubeRole == null ? void 0 : hypercubeRole.items) == null ? void 0 : _c.length) === 1) {
|
|
2804
|
+
const item = hypercubeRole.items[0];
|
|
2805
|
+
if (item.dimensions.length === 1) {
|
|
2806
|
+
const dimension = item.dimensions[0];
|
|
2807
|
+
if (dimension.members.length > 0) {
|
|
2808
|
+
const axisLabel = ((_d = dimension.labels.find((l2) => l2.role === "http://www.xbrl.org/2003/role/label")) == null ? void 0 : _d.label) || dimension.conceptName;
|
|
2809
|
+
const firstMember = dimension.members[0];
|
|
2810
|
+
const memberLabel = ((_e = firstMember.labels.find((l2) => l2.role === "http://www.xbrl.org/2003/role/label")) == null ? void 0 : _e.label) || firstMember.conceptName;
|
|
2811
|
+
const periodPart = request.periodType === "instant" ? `(${request.instantDate})` : `(${request.startDate} / ${request.endDate})`;
|
|
2812
|
+
title = `${memberLabel} ${periodPart}`;
|
|
2813
|
+
dimensionData = {
|
|
2814
|
+
dimensionId: newColumnId,
|
|
2815
|
+
axisId: dimension.id,
|
|
2816
|
+
memberId: firstMember.id,
|
|
2817
|
+
memberValue: memberLabel,
|
|
2818
|
+
memberLabel,
|
|
2819
|
+
axis: axisLabel,
|
|
2820
|
+
axisLabel,
|
|
2821
|
+
memberKey: `${axisLabel} | ${memberLabel}`,
|
|
2822
|
+
dimensionIdKey: `${dimension.id} | ${firstMember.id}`
|
|
2823
|
+
};
|
|
2824
|
+
console.log(`📊 Applied hypercube dimension to new column: ${dimensionData.memberKey}`);
|
|
2825
|
+
}
|
|
2826
|
+
}
|
|
2827
|
+
}
|
|
2828
|
+
}
|
|
2829
|
+
const newColumn = {
|
|
2830
|
+
id: newColumnId,
|
|
2831
|
+
title,
|
|
2832
|
+
description,
|
|
2833
|
+
type: dimensionData.memberKey ? "dimension" : "dimension",
|
|
2834
|
+
order: this._columns.length,
|
|
2835
|
+
removable: true,
|
|
2836
|
+
dimensionData
|
|
2837
|
+
};
|
|
2838
|
+
if (this._currentSchema) {
|
|
2839
|
+
const targetSection = this._currentSchema.sections.find((section) => section.id === sectionId);
|
|
2840
|
+
if (targetSection) {
|
|
2841
|
+
if (!targetSection.columns) {
|
|
2842
|
+
targetSection.columns = [...this._columns];
|
|
2843
|
+
}
|
|
2844
|
+
targetSection.columns = [...targetSection.columns, newColumn];
|
|
2845
|
+
}
|
|
2846
|
+
}
|
|
2847
|
+
this._replicateFieldsForNewColumn(newColumnId, request, sectionId);
|
|
2848
|
+
this._dirty = true;
|
|
2849
|
+
this.requestUpdate();
|
|
2850
|
+
this.dispatchEvent(new CustomEvent("column-add", {
|
|
2851
|
+
detail: { column: newColumn },
|
|
2852
|
+
bubbles: true
|
|
2853
|
+
}));
|
|
2854
|
+
}
|
|
2855
|
+
_removeColumnData(columnId, sectionId) {
|
|
2856
|
+
if (!this._currentSchema)
|
|
2857
|
+
return;
|
|
2858
|
+
if (sectionId) {
|
|
2859
|
+
const targetSection = this._currentSchema.sections.find((section) => section.id === sectionId);
|
|
2860
|
+
if (targetSection) {
|
|
2861
|
+
this._removeColumnDataFromConcepts(targetSection.concepts, columnId);
|
|
2862
|
+
}
|
|
2863
|
+
} else {
|
|
2864
|
+
for (const conceptId in this._formData) {
|
|
2865
|
+
if (this._formData[conceptId][columnId] !== void 0) {
|
|
2866
|
+
delete this._formData[conceptId][columnId];
|
|
2867
|
+
}
|
|
2868
|
+
}
|
|
2869
|
+
}
|
|
2870
|
+
}
|
|
2871
|
+
_removeColumnDataFromConcepts(concepts, columnId) {
|
|
2872
|
+
concepts.forEach((concept) => {
|
|
2873
|
+
if (this._formData[concept.id] && this._formData[concept.id][columnId] !== void 0) {
|
|
2874
|
+
delete this._formData[concept.id][columnId];
|
|
2875
|
+
}
|
|
2876
|
+
if (concept.fields) {
|
|
2877
|
+
concept.fields = concept.fields.filter((field) => field.columnId !== columnId);
|
|
2878
|
+
}
|
|
2879
|
+
if (concept.children) {
|
|
2880
|
+
this._removeColumnDataFromConcepts(concept.children, columnId);
|
|
2881
|
+
}
|
|
2882
|
+
});
|
|
2883
|
+
}
|
|
2884
|
+
_shouldCreateFieldForConcept(concept, request) {
|
|
2885
|
+
if (concept.abstract) {
|
|
2886
|
+
return false;
|
|
2887
|
+
}
|
|
2888
|
+
if (concept.periodType) {
|
|
2889
|
+
if (request.periodType === "instant" && concept.periodType !== "instant") {
|
|
2890
|
+
return false;
|
|
2891
|
+
}
|
|
2892
|
+
if (request.periodType === "duration" && concept.periodType !== "duration") {
|
|
2893
|
+
return false;
|
|
2894
|
+
}
|
|
2895
|
+
}
|
|
2896
|
+
return true;
|
|
2897
|
+
}
|
|
2898
|
+
_replicateFieldsForNewColumn(columnId, request, sectionId) {
|
|
2899
|
+
if (!this._currentSchema)
|
|
2900
|
+
return;
|
|
2901
|
+
const formBuilder = new XBRLFormBuilder();
|
|
2902
|
+
const targetSection = this._currentSchema.sections.find((section) => section.id === sectionId);
|
|
2903
|
+
if (targetSection) {
|
|
2904
|
+
this._replicateFieldsForSection(targetSection.concepts, columnId, request, formBuilder);
|
|
2905
|
+
}
|
|
2906
|
+
}
|
|
2907
|
+
_replicateFieldsForSection(concepts, columnId, request, formBuilder) {
|
|
2908
|
+
concepts.forEach((concept) => {
|
|
2909
|
+
var _a;
|
|
2910
|
+
if (this._shouldCreateFieldForConcept(concept, request)) {
|
|
2911
|
+
const existingField = (_a = concept.fields) == null ? void 0 : _a[0];
|
|
2912
|
+
let field;
|
|
2913
|
+
if (existingField) {
|
|
2914
|
+
field = {
|
|
2915
|
+
id: `${concept.id}_${columnId}`,
|
|
2916
|
+
conceptId: concept.id,
|
|
2917
|
+
columnId,
|
|
2918
|
+
type: existingField.type,
|
|
2919
|
+
label: existingField.label,
|
|
2920
|
+
placeholder: existingField.placeholder,
|
|
2921
|
+
required: existingField.required,
|
|
2922
|
+
disabled: existingField.disabled,
|
|
2923
|
+
validation: existingField.validation,
|
|
2924
|
+
defaultValue: existingField.defaultValue,
|
|
2925
|
+
// Set period dates from the add column request
|
|
2926
|
+
periodStartDate: request.periodType === "instant" ? request.instantDate : request.startDate,
|
|
2927
|
+
periodEndDate: request.periodType === "instant" ? request.instantDate : request.endDate
|
|
2928
|
+
};
|
|
2929
|
+
} else {
|
|
2930
|
+
field = {
|
|
2931
|
+
id: `${concept.id}_${columnId}`,
|
|
2932
|
+
conceptId: concept.id,
|
|
2933
|
+
columnId,
|
|
2934
|
+
type: "text",
|
|
2935
|
+
label: concept.label || concept.name,
|
|
2936
|
+
placeholder: `Enter ${concept.name}`,
|
|
2937
|
+
required: false,
|
|
2938
|
+
disabled: false,
|
|
2939
|
+
validation: [],
|
|
2940
|
+
defaultValue: "",
|
|
2941
|
+
// Set period dates from the add column request
|
|
2942
|
+
periodStartDate: request.periodType === "instant" ? request.instantDate : request.startDate,
|
|
2943
|
+
periodEndDate: request.periodType === "instant" ? request.instantDate : request.endDate
|
|
2944
|
+
};
|
|
2945
|
+
}
|
|
2946
|
+
if (!concept.fields) {
|
|
2947
|
+
concept.fields = [];
|
|
2948
|
+
}
|
|
2949
|
+
concept.fields.push(field);
|
|
2950
|
+
}
|
|
2951
|
+
if (concept.children) {
|
|
2952
|
+
this._replicateFieldsForSection(concept.children, columnId, request, formBuilder);
|
|
2953
|
+
}
|
|
2954
|
+
});
|
|
2955
|
+
}
|
|
1891
2956
|
_addColumn() {
|
|
1892
2957
|
const newColumnId = `dim-${Date.now()}`;
|
|
1893
2958
|
const newColumn = {
|
|
@@ -1913,15 +2978,95 @@ let JupiterDynamicForm = class extends LitElement {
|
|
|
1913
2978
|
_handleSubmit() {
|
|
1914
2979
|
this._submitted = true;
|
|
1915
2980
|
this._validateForm();
|
|
2981
|
+
const submissionData = this._generateSubmissionData();
|
|
1916
2982
|
this.dispatchEvent(new CustomEvent("form-submit", {
|
|
1917
2983
|
detail: {
|
|
1918
2984
|
data: this._formData,
|
|
2985
|
+
submissionData,
|
|
2986
|
+
valid: this._valid,
|
|
2987
|
+
errors: this._errors
|
|
2988
|
+
},
|
|
2989
|
+
bubbles: true
|
|
2990
|
+
}));
|
|
2991
|
+
}
|
|
2992
|
+
_handleSaveDraft() {
|
|
2993
|
+
const draftData = this._generateSubmissionData();
|
|
2994
|
+
this.dispatchEvent(new CustomEvent("form-save-draft", {
|
|
2995
|
+
detail: {
|
|
2996
|
+
data: this._formData,
|
|
2997
|
+
draftData,
|
|
1919
2998
|
valid: this._valid,
|
|
1920
2999
|
errors: this._errors
|
|
1921
3000
|
},
|
|
1922
3001
|
bubbles: true
|
|
1923
3002
|
}));
|
|
1924
3003
|
}
|
|
3004
|
+
_generateSubmissionData() {
|
|
3005
|
+
const submissionData = [];
|
|
3006
|
+
if (!this._currentSchema) {
|
|
3007
|
+
return submissionData;
|
|
3008
|
+
}
|
|
3009
|
+
this._currentSchema.sections.forEach((section) => {
|
|
3010
|
+
this._processConceptsForSubmission(section.concepts, submissionData, section);
|
|
3011
|
+
});
|
|
3012
|
+
return submissionData;
|
|
3013
|
+
}
|
|
3014
|
+
_findColumnById(columnId) {
|
|
3015
|
+
if (!this._currentSchema) {
|
|
3016
|
+
return void 0;
|
|
3017
|
+
}
|
|
3018
|
+
for (const section of this._currentSchema.sections) {
|
|
3019
|
+
if (section.columns) {
|
|
3020
|
+
const column = section.columns.find((col) => col.id === columnId);
|
|
3021
|
+
if (column) {
|
|
3022
|
+
return column;
|
|
3023
|
+
}
|
|
3024
|
+
}
|
|
3025
|
+
}
|
|
3026
|
+
return void 0;
|
|
3027
|
+
}
|
|
3028
|
+
_processConceptsForSubmission(concepts, submissionData, section) {
|
|
3029
|
+
concepts.forEach((concept) => {
|
|
3030
|
+
if (concept.fields && concept.fields.length > 0) {
|
|
3031
|
+
concept.fields.forEach((field) => {
|
|
3032
|
+
var _a, _b, _c;
|
|
3033
|
+
const conceptData = this._formData[concept.id];
|
|
3034
|
+
const fieldValue = conceptData == null ? void 0 : conceptData[field.columnId];
|
|
3035
|
+
if (fieldValue !== void 0 && fieldValue !== null && fieldValue !== "") {
|
|
3036
|
+
const column = this._findColumnById(field.columnId);
|
|
3037
|
+
const submissionEntry = {
|
|
3038
|
+
conceptId: concept.id,
|
|
3039
|
+
value: fieldValue,
|
|
3040
|
+
period: {
|
|
3041
|
+
type: concept.periodType || "duration"
|
|
3042
|
+
}
|
|
3043
|
+
};
|
|
3044
|
+
if (concept.periodType === "instant") {
|
|
3045
|
+
submissionEntry.period.date = field.periodStartDate || this.periodStartDate;
|
|
3046
|
+
} else {
|
|
3047
|
+
submissionEntry.period.startDate = field.periodStartDate || this.periodStartDate;
|
|
3048
|
+
submissionEntry.period.endDate = field.periodEndDate || this.periodEndDate;
|
|
3049
|
+
}
|
|
3050
|
+
if ((column == null ? void 0 : column.type) === "dimension" && ((_a = column.dimensionData) == null ? void 0 : _a.dimensionIdKey)) {
|
|
3051
|
+
submissionEntry.dimension = column.dimensionData.dimensionIdKey;
|
|
3052
|
+
} else if ((_b = section == null ? void 0 : section.columns) == null ? void 0 : _b.length) {
|
|
3053
|
+
const sectionDimensionColumn = section.columns.find((col) => {
|
|
3054
|
+
var _a2;
|
|
3055
|
+
return col.type === "dimension" && ((_a2 = col.dimensionData) == null ? void 0 : _a2.dimensionIdKey);
|
|
3056
|
+
});
|
|
3057
|
+
if ((_c = sectionDimensionColumn == null ? void 0 : sectionDimensionColumn.dimensionData) == null ? void 0 : _c.dimensionIdKey) {
|
|
3058
|
+
submissionEntry.dimension = sectionDimensionColumn.dimensionData.dimensionIdKey;
|
|
3059
|
+
}
|
|
3060
|
+
}
|
|
3061
|
+
submissionData.push(submissionEntry);
|
|
3062
|
+
}
|
|
3063
|
+
});
|
|
3064
|
+
}
|
|
3065
|
+
if (concept.children) {
|
|
3066
|
+
this._processConceptsForSubmission(concept.children, submissionData, section);
|
|
3067
|
+
}
|
|
3068
|
+
});
|
|
3069
|
+
}
|
|
1925
3070
|
_handleReset() {
|
|
1926
3071
|
this._formData = { ...this.initialData };
|
|
1927
3072
|
this._touched.clear();
|
|
@@ -1982,19 +3127,6 @@ let JupiterDynamicForm = class extends LitElement {
|
|
|
1982
3127
|
` : ""}
|
|
1983
3128
|
</div>
|
|
1984
3129
|
|
|
1985
|
-
<!-- Add Column Section -->
|
|
1986
|
-
${config.enableColumnManagement !== false ? html`
|
|
1987
|
-
<div class="add-column-container">
|
|
1988
|
-
<button
|
|
1989
|
-
class="add-column-btn"
|
|
1990
|
-
@click="${this._addColumn}"
|
|
1991
|
-
?disabled="${this.disabled || this.readonly || config.maxColumns && this._columns.length >= config.maxColumns}"
|
|
1992
|
-
>
|
|
1993
|
-
Add Dimension Column
|
|
1994
|
-
</button>
|
|
1995
|
-
</div>
|
|
1996
|
-
` : ""}
|
|
1997
|
-
|
|
1998
3130
|
<!-- Form Content -->
|
|
1999
3131
|
<div class="form-sections">
|
|
2000
3132
|
<!-- Validation Summary -->
|
|
@@ -2022,26 +3154,27 @@ let JupiterDynamicForm = class extends LitElement {
|
|
|
2022
3154
|
@section-expand="${this._handleSectionExpand}"
|
|
2023
3155
|
@concept-expand="${this._handleConceptExpand}"
|
|
2024
3156
|
@column-remove="${this._handleColumnRemove}"
|
|
3157
|
+
@column-add-request="${this._handleColumnAddRequest}"
|
|
2025
3158
|
></jupiter-form-section>
|
|
2026
3159
|
`)}
|
|
2027
3160
|
</div>
|
|
2028
3161
|
|
|
2029
|
-
<!-- Form Actions -->
|
|
3162
|
+
<!-- Form Actions - Fixed Footer -->
|
|
2030
3163
|
<div class="form-actions">
|
|
2031
3164
|
<button
|
|
2032
|
-
class="btn-
|
|
2033
|
-
@click="${this.
|
|
3165
|
+
class="btn-secondary"
|
|
3166
|
+
@click="${this._handleSaveDraft}"
|
|
2034
3167
|
?disabled="${this.disabled || this.readonly}"
|
|
2035
3168
|
>
|
|
2036
|
-
|
|
3169
|
+
Save Draft
|
|
2037
3170
|
</button>
|
|
2038
3171
|
|
|
2039
3172
|
<button
|
|
2040
|
-
class="btn-
|
|
2041
|
-
@click="${this.
|
|
2042
|
-
?disabled="${this.disabled ||
|
|
3173
|
+
class="btn-primary"
|
|
3174
|
+
@click="${this._handleSubmit}"
|
|
3175
|
+
?disabled="${this.disabled || this.readonly}"
|
|
2043
3176
|
>
|
|
2044
|
-
|
|
3177
|
+
Submit
|
|
2045
3178
|
</button>
|
|
2046
3179
|
|
|
2047
3180
|
<div class="form-meta">
|
|
@@ -2089,42 +3222,23 @@ JupiterDynamicForm.styles = css`
|
|
|
2089
3222
|
}
|
|
2090
3223
|
|
|
2091
3224
|
.form-actions {
|
|
3225
|
+
position: fixed;
|
|
3226
|
+
bottom: 0;
|
|
3227
|
+
left: 0;
|
|
3228
|
+
right: 0;
|
|
2092
3229
|
padding: 16px 24px;
|
|
2093
3230
|
border-top: 1px solid var(--jupiter-border-color, #ddd);
|
|
2094
3231
|
background: var(--jupiter-form-actions-background, #f8f9fa);
|
|
2095
3232
|
display: flex;
|
|
2096
3233
|
gap: 12px;
|
|
2097
3234
|
align-items: center;
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
.add-column-container {
|
|
2101
|
-
padding: 16px 24px;
|
|
2102
|
-
border-bottom: 1px solid var(--jupiter-border-color, #ddd);
|
|
2103
|
-
background: var(--jupiter-form-actions-background, #f8f9fa);
|
|
2104
|
-
}
|
|
2105
|
-
|
|
2106
|
-
.add-column-btn {
|
|
2107
|
-
padding: 8px 16px;
|
|
2108
|
-
background: var(--jupiter-primary-color, #1976d2);
|
|
2109
|
-
color: white;
|
|
2110
|
-
border: none;
|
|
2111
|
-
border-radius: 4px;
|
|
2112
|
-
cursor: pointer;
|
|
2113
|
-
font-size: 14px;
|
|
2114
|
-
font-weight: 500;
|
|
2115
|
-
}
|
|
2116
|
-
|
|
2117
|
-
.add-column-btn:hover {
|
|
2118
|
-
background: var(--jupiter-primary-color-dark, #1565c0);
|
|
2119
|
-
}
|
|
2120
|
-
|
|
2121
|
-
.add-column-btn:disabled {
|
|
2122
|
-
background: var(--jupiter-disabled-background, #ccc);
|
|
2123
|
-
cursor: not-allowed;
|
|
3235
|
+
z-index: 1000;
|
|
3236
|
+
box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.1);
|
|
2124
3237
|
}
|
|
2125
3238
|
|
|
2126
3239
|
.form-sections {
|
|
2127
3240
|
padding: 24px;
|
|
3241
|
+
padding-bottom: 100px; /* Add space for fixed footer */
|
|
2128
3242
|
}
|
|
2129
3243
|
|
|
2130
3244
|
.validation-summary {
|
|
@@ -2258,6 +3372,7 @@ JupiterDynamicForm = __decorateClass([
|
|
|
2258
3372
|
const version = "1.0.0";
|
|
2259
3373
|
export {
|
|
2260
3374
|
FormValidator,
|
|
3375
|
+
JupiterAddColumnDialog,
|
|
2261
3376
|
JupiterConceptTree,
|
|
2262
3377
|
JupiterDynamicForm,
|
|
2263
3378
|
JupiterFormField,
|