jupiter-dynamic-forms 1.10.0 → 1.11.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
@@ -1574,6 +1574,7 @@ const filter$1 = {
1574
1574
  selectRoles: "Select Roles",
1575
1575
  filterRoles: "Filter Roles",
1576
1576
  title: "Filter Roles",
1577
+ description: "Select the roles you want to display in the form. You can search and choose specific roles to focus on or manage all available roles.",
1577
1578
  searchPlaceholder: "Search roles by name, ID, or URI...",
1578
1579
  clearSearch: "Clear search",
1579
1580
  showingResults: "Showing",
@@ -1651,6 +1652,7 @@ const filter = {
1651
1652
  selectRoles: "Rollen selecteren",
1652
1653
  filterRoles: "Rollen filteren",
1653
1654
  title: "Rollen filteren",
1655
+ description: "Selecteer de rollen die u in het formulier wilt weergeven. U kunt zoeken en specifieke rollen kiezen om op te focussen of alle beschikbare rollen beheren.",
1654
1656
  searchPlaceholder: "Zoek rollen op naam, ID of URI...",
1655
1657
  clearSearch: "Zoekopdracht wissen",
1656
1658
  showingResults: "Weergeven",
@@ -1789,6 +1791,194 @@ class I18n {
1789
1791
  }
1790
1792
  }
1791
1793
  I18n.currentLanguage = "en";
1794
+ class DraftStorageService {
1795
+ constructor(useSessionStorage = false) {
1796
+ this.DRAFT_DATA_KEY = "jupiter-form-draft-data";
1797
+ this.DRAFT_METADATA_KEY = "jupiter-form-draft-metadata";
1798
+ this.STORAGE_VERSION = "1.0";
1799
+ this._storage = useSessionStorage ? sessionStorage : localStorage;
1800
+ console.log(`💾 DraftStorageService initialized (using ${useSessionStorage ? "sessionStorage" : "localStorage"})`);
1801
+ }
1802
+ // ===========================================
1803
+ // Public API Methods
1804
+ // ===========================================
1805
+ /**
1806
+ * Save complete draft including data and metadata
1807
+ */
1808
+ saveDraft(submissionData, metadata) {
1809
+ try {
1810
+ const draft = {
1811
+ formData: submissionData,
1812
+ metadata: {
1813
+ ...metadata,
1814
+ savedAt: (/* @__PURE__ */ new Date()).toISOString()
1815
+ },
1816
+ version: this.STORAGE_VERSION
1817
+ };
1818
+ this._storage.setItem(this.DRAFT_DATA_KEY, JSON.stringify(draft.formData));
1819
+ this._storage.setItem(this.DRAFT_METADATA_KEY, JSON.stringify(draft.metadata));
1820
+ console.log("✅ Draft saved successfully", {
1821
+ entries: submissionData.length,
1822
+ timestamp: draft.metadata.savedAt,
1823
+ roles: metadata.selectedRoleIds.length,
1824
+ customColumns: metadata.customColumns.length
1825
+ });
1826
+ return true;
1827
+ } catch (error) {
1828
+ console.error("❌ Failed to save draft:", error);
1829
+ return false;
1830
+ }
1831
+ }
1832
+ /**
1833
+ * Load saved draft
1834
+ */
1835
+ loadDraft() {
1836
+ try {
1837
+ const dataStr = this._storage.getItem(this.DRAFT_DATA_KEY);
1838
+ const metadataStr = this._storage.getItem(this.DRAFT_METADATA_KEY);
1839
+ if (!dataStr || !metadataStr) {
1840
+ console.log("â„šī¸ No saved draft found");
1841
+ return null;
1842
+ }
1843
+ const formData = JSON.parse(dataStr);
1844
+ const metadata = JSON.parse(metadataStr);
1845
+ console.log("✅ Draft loaded successfully", {
1846
+ entries: formData.length,
1847
+ savedAt: metadata.savedAt,
1848
+ roles: metadata.selectedRoleIds.length,
1849
+ customColumns: metadata.customColumns.length
1850
+ });
1851
+ return {
1852
+ formData,
1853
+ metadata,
1854
+ version: this.STORAGE_VERSION
1855
+ };
1856
+ } catch (error) {
1857
+ console.error("❌ Failed to load draft:", error);
1858
+ return null;
1859
+ }
1860
+ }
1861
+ /**
1862
+ * Check if a draft exists
1863
+ */
1864
+ hasDraft() {
1865
+ return this._storage.getItem(this.DRAFT_DATA_KEY) !== null && this._storage.getItem(this.DRAFT_METADATA_KEY) !== null;
1866
+ }
1867
+ /**
1868
+ * Get draft metadata only (without full data)
1869
+ */
1870
+ getDraftMetadata() {
1871
+ try {
1872
+ const metadataStr = this._storage.getItem(this.DRAFT_METADATA_KEY);
1873
+ if (!metadataStr)
1874
+ return null;
1875
+ return JSON.parse(metadataStr);
1876
+ } catch (error) {
1877
+ console.error("❌ Failed to load draft metadata:", error);
1878
+ return null;
1879
+ }
1880
+ }
1881
+ /**
1882
+ * Clear saved draft
1883
+ */
1884
+ clearDraft() {
1885
+ try {
1886
+ this._storage.removeItem(this.DRAFT_DATA_KEY);
1887
+ this._storage.removeItem(this.DRAFT_METADATA_KEY);
1888
+ console.log("đŸ—‘ī¸ Draft cleared successfully");
1889
+ return true;
1890
+ } catch (error) {
1891
+ console.error("❌ Failed to clear draft:", error);
1892
+ return false;
1893
+ }
1894
+ }
1895
+ /**
1896
+ * Get draft age in milliseconds
1897
+ */
1898
+ getDraftAge() {
1899
+ const metadata = this.getDraftMetadata();
1900
+ if (!metadata)
1901
+ return null;
1902
+ const savedAt = new Date(metadata.savedAt);
1903
+ const now = /* @__PURE__ */ new Date();
1904
+ return now.getTime() - savedAt.getTime();
1905
+ }
1906
+ /**
1907
+ * Check if draft is older than specified time (in milliseconds)
1908
+ */
1909
+ isDraftStale(maxAge) {
1910
+ const age = this.getDraftAge();
1911
+ return age !== null && age > maxAge;
1912
+ }
1913
+ /**
1914
+ * Extract custom columns from all sections
1915
+ */
1916
+ extractCustomColumns(allSections) {
1917
+ const customColumns = [];
1918
+ allSections.forEach((section2) => {
1919
+ if (!section2.columns || !Array.isArray(section2.columns)) {
1920
+ return;
1921
+ }
1922
+ section2.columns.forEach((column2) => {
1923
+ customColumns.push({
1924
+ sectionId: section2.id,
1925
+ columnId: column2.id,
1926
+ label: column2.title,
1927
+ // FormColumn uses 'title' not 'label'
1928
+ periodType: this._inferPeriodTypeFromColumn(column2),
1929
+ date: column2.periodStartDate,
1930
+ // Use periodStartDate for instant
1931
+ startDate: column2.periodStartDate,
1932
+ endDate: column2.periodEndDate,
1933
+ dimensionData: column2.dimensionData
1934
+ });
1935
+ });
1936
+ });
1937
+ return customColumns;
1938
+ }
1939
+ /**
1940
+ * Infer period type from column data
1941
+ */
1942
+ _inferPeriodTypeFromColumn(column2) {
1943
+ if (column2.periodStartDate && column2.periodEndDate) {
1944
+ return "duration";
1945
+ }
1946
+ return "instant";
1947
+ }
1948
+ /**
1949
+ * Create metadata snapshot from current form state
1950
+ */
1951
+ createMetadataSnapshot(periodStartDate, periodEndDate, language, selectedRoleIds, allSections, typedMemberData, periodPreferences) {
1952
+ return {
1953
+ periodStartDate,
1954
+ periodEndDate,
1955
+ language,
1956
+ selectedRoleIds,
1957
+ customColumns: this.extractCustomColumns(allSections),
1958
+ typedMemberData,
1959
+ periodPreferences,
1960
+ schemaVersion: this.STORAGE_VERSION
1961
+ };
1962
+ }
1963
+ /**
1964
+ * Validate draft compatibility with current schema
1965
+ */
1966
+ validateDraftCompatibility(draft, currentPeriodStart, currentPeriodEnd) {
1967
+ const warnings = [];
1968
+ if (draft.metadata.periodStartDate !== currentPeriodStart) {
1969
+ warnings.push(`Draft period start (${draft.metadata.periodStartDate}) differs from current (${currentPeriodStart})`);
1970
+ }
1971
+ if (draft.metadata.periodEndDate !== currentPeriodEnd) {
1972
+ warnings.push(`Draft period end (${draft.metadata.periodEndDate}) differs from current (${currentPeriodEnd})`);
1973
+ }
1974
+ const age = this.getDraftAge();
1975
+ if (age && age > 7 * 24 * 60 * 60 * 1e3) {
1976
+ warnings.push(`Draft is ${Math.floor(age / (24 * 60 * 60 * 1e3))} days old`);
1977
+ }
1978
+ const compatible = warnings.length === 0;
1979
+ return { compatible, warnings };
1980
+ }
1981
+ }
1792
1982
  const TYPE_INPUT_MAP = {
1793
1983
  // ==========================================
1794
1984
  // Dutch XBRL Types (nl-types namespace)
@@ -3776,7 +3966,7 @@ JupiterFormSection.styles = css`
3776
3966
  }
3777
3967
 
3778
3968
  .typed-member-header-field {
3779
- width: 100%;
3969
+ width: 96%;
3780
3970
  padding: 4px 6px;
3781
3971
  border: 1px solid var(--jupiter-border-color, #ddd);
3782
3972
  border-radius: 3px;
@@ -4088,8 +4278,7 @@ let JupiterFilterRolesDialog = class extends LitElement {
4088
4278
  <!-- Dialog Content -->
4089
4279
  <div class="dialog-content">
4090
4280
  <p class="description">
4091
- Select the roles you want to display in the form. You can search and choose specific roles
4092
- to focus on or manage all ${totalCount} available roles.
4281
+ ${I18n.t("filter.description")}
4093
4282
  </p>
4094
4283
 
4095
4284
  <!-- Search Input -->
@@ -4624,6 +4813,7 @@ let JupiterDynamicForm = class extends LitElement {
4624
4813
  this.mode = "inputForm";
4625
4814
  this.financialStatementsTypeAxis = [];
4626
4815
  this._formData = {};
4816
+ this._draftLoaded = false;
4627
4817
  this._preservedFormData = {};
4628
4818
  this._typedMemberData = {};
4629
4819
  this._preservedTypedMemberData = {};
@@ -4639,6 +4829,7 @@ let JupiterDynamicForm = class extends LitElement {
4639
4829
  this._periodPreferences = {};
4640
4830
  this._activeSidePanelRoleId = null;
4641
4831
  this._adminRoleConfigs = {};
4832
+ this._skipDraftLoading = false;
4642
4833
  }
4643
4834
  connectedCallback() {
4644
4835
  super.connectedCallback();
@@ -4657,6 +4848,9 @@ let JupiterDynamicForm = class extends LitElement {
4657
4848
  }
4658
4849
  _initializeForm() {
4659
4850
  var _a;
4851
+ if (!this._draftStorageService) {
4852
+ this._draftStorageService = new DraftStorageService(false);
4853
+ }
4660
4854
  if (this.xbrlInput) {
4661
4855
  try {
4662
4856
  console.log("🔄 Initializing form from XBRL input:", this.xbrlInput);
@@ -4716,6 +4910,11 @@ let JupiterDynamicForm = class extends LitElement {
4716
4910
  if ((_a = this.xbrlInput) == null ? void 0 : _a.initialData) {
4717
4911
  this._formData = { ...this._formData, ...this.xbrlInput.initialData };
4718
4912
  }
4913
+ if (!this._skipDraftLoading) {
4914
+ this._loadDraftIfExists();
4915
+ } else {
4916
+ console.log("â­ī¸ Skipping draft loading during preference update");
4917
+ }
4719
4918
  this._validateForm();
4720
4919
  }
4721
4920
  _getDefaultSchema() {
@@ -4933,7 +5132,24 @@ let JupiterDynamicForm = class extends LitElement {
4933
5132
  if (preferencesChanged) {
4934
5133
  this._periodPreferences = periodPreferences;
4935
5134
  console.log("📊 Period preferences updated:", this._periodPreferences);
5135
+ this._skipDraftLoading = true;
4936
5136
  this._initializeForm();
5137
+ this._skipDraftLoading = false;
5138
+ if (this._draftStorageService.hasDraft()) {
5139
+ console.log("💾 Updating draft with new period preferences...");
5140
+ const draftData = this._generateSubmissionData();
5141
+ const metadata = this._draftStorageService.createMetadataSnapshot(
5142
+ this.periodStartDate,
5143
+ this.periodEndDate,
5144
+ this.language,
5145
+ this._selectedRoleIds,
5146
+ this._allSections,
5147
+ this._typedMemberData,
5148
+ this._periodPreferences
5149
+ );
5150
+ this._draftStorageService.saveDraft(draftData, metadata);
5151
+ console.log("✅ Draft updated with new period preferences");
5152
+ }
4937
5153
  } else {
4938
5154
  this._applyRoleFilter();
4939
5155
  }
@@ -4976,6 +5192,7 @@ let JupiterDynamicForm = class extends LitElement {
4976
5192
  }
4977
5193
  _handleFieldChange(event) {
4978
5194
  const { fieldId, conceptId, columnId, value } = event.detail;
5195
+ console.log(`📝 Field change: conceptId=${conceptId}, columnId=${columnId}, value=${value}, fieldId=${fieldId}`);
4979
5196
  const updatedFormData = { ...this._formData };
4980
5197
  if (!updatedFormData[conceptId]) {
4981
5198
  updatedFormData[conceptId] = {};
@@ -4983,6 +5200,7 @@ let JupiterDynamicForm = class extends LitElement {
4983
5200
  const oldValue = updatedFormData[conceptId][columnId];
4984
5201
  updatedFormData[conceptId] = { ...updatedFormData[conceptId], [columnId]: value };
4985
5202
  this._formData = updatedFormData;
5203
+ console.log(`💾 Updated formData[${conceptId}]:`, this._formData[conceptId]);
4986
5204
  this._touched.add(`${conceptId}-${columnId}`);
4987
5205
  this._dirty = true;
4988
5206
  this._validateForm();
@@ -5376,16 +5594,452 @@ let JupiterDynamicForm = class extends LitElement {
5376
5594
  console.log("✅ Form submit event dispatched");
5377
5595
  }
5378
5596
  _handleSaveDraft() {
5597
+ console.log("💾 Raw form data before submission generation:", this._formData);
5379
5598
  const draftData = this._generateSubmissionData();
5599
+ console.log("📤 Generated submission data:", draftData);
5600
+ console.log("📊 Submission data breakdown:");
5601
+ draftData.forEach((entry, index) => {
5602
+ console.log(` [${index}] conceptId: ${entry.conceptId}, columnId: ${entry.columnId}, value: ${entry.value}`);
5603
+ });
5604
+ const metadata = this._draftStorageService.createMetadataSnapshot(
5605
+ this.periodStartDate,
5606
+ this.periodEndDate,
5607
+ this.language,
5608
+ this._selectedRoleIds,
5609
+ this._allSections,
5610
+ this._typedMemberData,
5611
+ this._periodPreferences
5612
+ );
5613
+ const saved = this._draftStorageService.saveDraft(draftData, metadata);
5380
5614
  this.dispatchEvent(new CustomEvent("form-save-draft", {
5381
5615
  detail: {
5382
5616
  data: this._formData,
5383
5617
  draftData,
5618
+ metadata,
5619
+ saved,
5384
5620
  valid: this._valid,
5385
- errors: this._errors
5621
+ errors: this._errors,
5622
+ // Provide data in format for external storage
5623
+ dynaformsFacts: draftData,
5624
+ dynaformsMetadata: metadata
5386
5625
  },
5387
5626
  bubbles: true
5388
5627
  }));
5628
+ console.log("💾 Draft saved to localStorage", {
5629
+ entries: draftData.length,
5630
+ saved,
5631
+ roles: this._selectedRoleIds.length,
5632
+ customColumns: metadata.customColumns.length
5633
+ });
5634
+ }
5635
+ // ===========================================
5636
+ // Draft Loading & Restoration
5637
+ // ===========================================
5638
+ async _loadDraftIfExists() {
5639
+ console.log("📋 Checking for saved draft...");
5640
+ if (this.dynaformsFacts && this.dynaformsMetadata) {
5641
+ console.log("đŸ“Ļ Using external draft data from properties");
5642
+ const draft2 = {
5643
+ formData: this.dynaformsFacts,
5644
+ metadata: this.dynaformsMetadata
5645
+ };
5646
+ await this._restoreFromDraft(draft2);
5647
+ this._draftLoaded = true;
5648
+ this._draftLoadedAt = this.dynaformsMetadata.savedAt || (/* @__PURE__ */ new Date()).toISOString();
5649
+ this.dispatchEvent(new CustomEvent("form-draft-loaded", {
5650
+ detail: {
5651
+ draft: draft2,
5652
+ source: "external",
5653
+ compatible: true,
5654
+ warnings: []
5655
+ },
5656
+ bubbles: true,
5657
+ composed: true
5658
+ }));
5659
+ console.log("đŸ“Ĩ External draft loaded successfully");
5660
+ return;
5661
+ }
5662
+ if (!this._draftStorageService.hasDraft()) {
5663
+ console.log("â„šī¸ No saved draft found");
5664
+ return;
5665
+ }
5666
+ const draft = this._draftStorageService.loadDraft();
5667
+ if (!draft) {
5668
+ console.warn("âš ī¸ Failed to load draft");
5669
+ return;
5670
+ }
5671
+ const { compatible, warnings } = this._draftStorageService.validateDraftCompatibility(
5672
+ draft,
5673
+ this.periodStartDate,
5674
+ this.periodEndDate
5675
+ );
5676
+ if (warnings.length > 0) {
5677
+ console.warn("âš ī¸ Draft compatibility warnings:", warnings);
5678
+ }
5679
+ await this._restoreFromDraft(draft);
5680
+ this.dispatchEvent(new CustomEvent("form-draft-loaded", {
5681
+ detail: {
5682
+ draft,
5683
+ compatible,
5684
+ warnings
5685
+ },
5686
+ bubbles: true,
5687
+ composed: true
5688
+ }));
5689
+ console.log("đŸ“Ĩ Draft loaded successfully", {
5690
+ entries: draft.formData.length,
5691
+ savedAt: draft.metadata.savedAt,
5692
+ age: this._draftStorageService.getDraftAge()
5693
+ });
5694
+ }
5695
+ async _restoreFromDraft(draft) {
5696
+ var _a;
5697
+ const { formData, metadata } = draft;
5698
+ if (metadata.selectedRoleIds && metadata.selectedRoleIds.length > 0) {
5699
+ this._selectedRoleIds = metadata.selectedRoleIds;
5700
+ console.log(`🔄 Restored ${this._selectedRoleIds.length} selected roles`);
5701
+ }
5702
+ if (metadata.typedMemberData) {
5703
+ this._typedMemberData = metadata.typedMemberData;
5704
+ this._preservedTypedMemberData = {};
5705
+ console.log("🔄 Restored typed member data");
5706
+ }
5707
+ if (metadata.periodPreferences) {
5708
+ this._periodPreferences = metadata.periodPreferences;
5709
+ console.log("🔄 Restored period preferences (including previous year settings):", this._periodPreferences);
5710
+ if (this.xbrlInput) {
5711
+ console.log("🔄 Rebuilding schema with restored period preferences...");
5712
+ this._currentSchema = XBRLFormBuilder.buildFormSchema(
5713
+ this.xbrlInput,
5714
+ this.periodStartDate,
5715
+ this.periodEndDate,
5716
+ this.language,
5717
+ this._periodPreferences
5718
+ );
5719
+ this._allSections = [...this._currentSchema.sections];
5720
+ if (this.financialStatementsTypeAxis && this.financialStatementsTypeAxis.length > 0) {
5721
+ this._allSections = this._filterRolesByFinancialStatementsType(this._allSections);
5722
+ }
5723
+ console.log("✅ Schema rebuilt with restored period preferences");
5724
+ if (metadata.customColumns && metadata.customColumns.length > 0) {
5725
+ this._mergeAdditionalCustomColumns(metadata.customColumns);
5726
+ console.log(`🔄 Merged ${metadata.customColumns.length} additional custom columns`);
5727
+ }
5728
+ }
5729
+ } else {
5730
+ if (metadata.customColumns && metadata.customColumns.length > 0) {
5731
+ this._restoreCustomColumns(metadata.customColumns);
5732
+ console.log(`🔄 Restored ${metadata.customColumns.length} custom columns`);
5733
+ }
5734
+ }
5735
+ const restoredFormData = {};
5736
+ formData.forEach((entry) => {
5737
+ let { conceptId, value, columnId, period } = entry;
5738
+ if (!columnId && period) {
5739
+ columnId = this._inferColumnIdFromPeriod(period, conceptId);
5740
+ if (!columnId) {
5741
+ console.warn(`âš ī¸ Could not infer columnId for concept ${conceptId}, skipping...`);
5742
+ return;
5743
+ }
5744
+ }
5745
+ const actualConceptId = this._findActualConceptId(conceptId);
5746
+ const conceptIdToUse = actualConceptId || conceptId;
5747
+ if (!restoredFormData[conceptIdToUse]) {
5748
+ restoredFormData[conceptIdToUse] = {};
5749
+ }
5750
+ restoredFormData[conceptIdToUse][columnId] = value;
5751
+ console.log(`đŸ“Ļ Restored: ${conceptIdToUse}[${columnId}] = ${value}`);
5752
+ });
5753
+ this._formData = { ...this._formData, ...restoredFormData };
5754
+ console.log(`🔄 Restored ${Object.keys(restoredFormData).length} concepts with data`);
5755
+ if (this._selectedRoleIds.length > 0) {
5756
+ this._applyRoleFilter();
5757
+ }
5758
+ this._dirty = true;
5759
+ this._touched.clear();
5760
+ this._validateForm();
5761
+ this._allSections = [...this._allSections];
5762
+ this.requestUpdate();
5763
+ await this.updateComplete;
5764
+ await new Promise((resolve) => setTimeout(resolve, 100));
5765
+ const fieldCount = ((_a = this.shadowRoot) == null ? void 0 : _a.querySelectorAll("input, textarea, select").length) || 0;
5766
+ console.log(`🔍 Found ${fieldCount} fields in DOM after update`);
5767
+ if (fieldCount > 0) {
5768
+ this._populateFieldValues(restoredFormData);
5769
+ } else {
5770
+ console.error("❌ No fields found in DOM even after updateComplete");
5771
+ }
5772
+ console.log("✅ Draft restoration completed");
5773
+ }
5774
+ _findActualConceptId(conceptId) {
5775
+ for (const section2 of this._allSections) {
5776
+ const found = this._findActualConceptIdInTree(section2.concepts, conceptId);
5777
+ if (found)
5778
+ return found;
5779
+ }
5780
+ return null;
5781
+ }
5782
+ _findActualConceptIdInTree(concepts, conceptId) {
5783
+ for (const concept of concepts) {
5784
+ if (concept.originalConceptId === conceptId || concept.id === conceptId) {
5785
+ return concept.id;
5786
+ }
5787
+ if (concept.children) {
5788
+ const found = this._findActualConceptIdInTree(concept.children, conceptId);
5789
+ if (found)
5790
+ return found;
5791
+ }
5792
+ }
5793
+ return null;
5794
+ }
5795
+ _inferColumnIdFromPeriod(period, conceptId) {
5796
+ for (const section2 of this._allSections) {
5797
+ const concept = this._findConceptInSection(section2.concepts, conceptId);
5798
+ if (concept && section2.columns) {
5799
+ for (const column2 of section2.columns) {
5800
+ const isInstant = period.type === "instant";
5801
+ const isDuration = period.type === "duration";
5802
+ if (isInstant && period.date) {
5803
+ if (column2.periodStartDate === period.date || column2.periodStartDate === column2.periodEndDate && column2.periodStartDate === period.date) {
5804
+ console.log(`✓ Inferred columnId: ${column2.id} for concept ${conceptId}`);
5805
+ return column2.id;
5806
+ }
5807
+ } else if (isDuration && period.startDate && period.endDate) {
5808
+ if (column2.periodStartDate === period.startDate && column2.periodEndDate === period.endDate) {
5809
+ console.log(`✓ Inferred columnId: ${column2.id} for concept ${conceptId}`);
5810
+ return column2.id;
5811
+ }
5812
+ }
5813
+ }
5814
+ if (period.type === "instant") {
5815
+ const instantCol = section2.columns.find((c2) => c2.id === "instant");
5816
+ if (instantCol)
5817
+ return instantCol.id;
5818
+ } else {
5819
+ const durationCol = section2.columns.find((c2) => c2.id === "duration");
5820
+ if (durationCol)
5821
+ return durationCol.id;
5822
+ }
5823
+ }
5824
+ }
5825
+ return null;
5826
+ }
5827
+ _findConceptInSection(concepts, conceptId) {
5828
+ for (const concept of concepts) {
5829
+ if (concept.id === conceptId || concept.originalConceptId === conceptId) {
5830
+ return concept;
5831
+ }
5832
+ if (concept.children) {
5833
+ const found = this._findConceptInSection(concept.children, conceptId);
5834
+ if (found)
5835
+ return found;
5836
+ }
5837
+ }
5838
+ return null;
5839
+ }
5840
+ _populateFieldValues(formData) {
5841
+ let populatedCount = 0;
5842
+ let notFoundCount = 0;
5843
+ console.log("🔍 Starting field population...");
5844
+ console.log("đŸ“Ļ Form data to populate:", formData);
5845
+ Object.keys(formData).forEach((conceptId) => {
5846
+ const conceptData = formData[conceptId];
5847
+ Object.keys(conceptData).forEach((columnId) => {
5848
+ var _a, _b;
5849
+ const value = conceptData[columnId];
5850
+ const fieldId = `${conceptId}__${columnId}`;
5851
+ console.log(`🔍 Looking for field: ${fieldId}`);
5852
+ const fieldElement = (_a = this.shadowRoot) == null ? void 0 : _a.querySelector(`#${CSS.escape(fieldId)}`);
5853
+ if (fieldElement) {
5854
+ if (fieldElement instanceof HTMLInputElement || fieldElement instanceof HTMLTextAreaElement || fieldElement instanceof HTMLSelectElement) {
5855
+ if (fieldElement.type === "checkbox") {
5856
+ fieldElement.checked = Boolean(value);
5857
+ } else {
5858
+ fieldElement.value = value !== null && value !== void 0 ? String(value) : "";
5859
+ }
5860
+ console.log(` ✅ Populated field ${fieldId} with value:`, value);
5861
+ populatedCount++;
5862
+ }
5863
+ } else {
5864
+ console.warn(` ❌ Field element NOT FOUND: ${fieldId}`);
5865
+ console.warn(` Available fields in DOM:`, Array.from(((_b = this.shadowRoot) == null ? void 0 : _b.querySelectorAll("input, textarea, select")) || []).map((el) => el.id).filter((id) => id.includes(conceptId.split("__")[0])));
5866
+ notFoundCount++;
5867
+ }
5868
+ });
5869
+ });
5870
+ console.log(`✅ Field population complete: ${populatedCount} populated, ${notFoundCount} not found`);
5871
+ }
5872
+ _restoreCustomColumns(customColumns) {
5873
+ const columnsBySection = /* @__PURE__ */ new Map();
5874
+ customColumns.forEach((col) => {
5875
+ if (!columnsBySection.has(col.sectionId)) {
5876
+ columnsBySection.set(col.sectionId, []);
5877
+ }
5878
+ columnsBySection.get(col.sectionId).push(col);
5879
+ });
5880
+ this._allSections.forEach((section2) => {
5881
+ const savedColumns = columnsBySection.get(section2.id);
5882
+ if (savedColumns) {
5883
+ section2.columns = savedColumns.map((col) => ({
5884
+ id: col.columnId,
5885
+ title: col.label,
5886
+ type: col.dimensionData ? "dimension" : "base",
5887
+ periodStartDate: col.startDate || col.date,
5888
+ periodEndDate: col.endDate || col.date,
5889
+ dimensionData: col.dimensionData,
5890
+ order: 0,
5891
+ removable: col.columnId !== "duration" && col.columnId !== "instant"
5892
+ }));
5893
+ this._regenerateFieldsForSection(section2);
5894
+ console.log(` └─ Restored ${savedColumns.length} columns for section ${section2.id}`);
5895
+ }
5896
+ });
5897
+ if (this._currentSchema) {
5898
+ this._currentSchema = {
5899
+ ...this._currentSchema,
5900
+ sections: this._allSections
5901
+ };
5902
+ }
5903
+ }
5904
+ /**
5905
+ * Merge additional custom columns that were manually added by user
5906
+ * This preserves default columns (duration, instant, previous year) generated by schema builder
5907
+ * and only adds custom columns that don't already exist
5908
+ */
5909
+ _mergeAdditionalCustomColumns(customColumns) {
5910
+ const columnsBySection = /* @__PURE__ */ new Map();
5911
+ customColumns.forEach((col) => {
5912
+ const isManuallyAdded = col.columnId.startsWith("col-");
5913
+ if (isManuallyAdded) {
5914
+ if (!columnsBySection.has(col.sectionId)) {
5915
+ columnsBySection.set(col.sectionId, []);
5916
+ }
5917
+ columnsBySection.get(col.sectionId).push(col);
5918
+ }
5919
+ });
5920
+ this._allSections.forEach((section2) => {
5921
+ const customColumnsForSection = columnsBySection.get(section2.id);
5922
+ if (customColumnsForSection && customColumnsForSection.length > 0) {
5923
+ if (!section2.columns) {
5924
+ section2.columns = [];
5925
+ }
5926
+ customColumnsForSection.forEach((col) => {
5927
+ const existingColumn = section2.columns.find((c2) => c2.id === col.columnId);
5928
+ if (!existingColumn) {
5929
+ const newColumn = {
5930
+ id: col.columnId,
5931
+ title: col.label,
5932
+ type: col.dimensionData ? "dimension" : "base",
5933
+ periodStartDate: col.startDate || col.date,
5934
+ periodEndDate: col.endDate || col.date,
5935
+ dimensionData: col.dimensionData,
5936
+ order: section2.columns.length,
5937
+ removable: true
5938
+ };
5939
+ section2.columns.push(newColumn);
5940
+ console.log(` └─ Added custom column ${col.columnId} to section ${section2.id}`);
5941
+ }
5942
+ });
5943
+ this._regenerateFieldsForSection(section2);
5944
+ }
5945
+ });
5946
+ if (this._currentSchema) {
5947
+ this._currentSchema = {
5948
+ ...this._currentSchema,
5949
+ sections: this._allSections
5950
+ };
5951
+ }
5952
+ }
5953
+ _regenerateFieldsForSection(section2) {
5954
+ if (!section2.columns)
5955
+ return;
5956
+ const sectionPreferences = this._periodPreferences[section2.id] || {
5957
+ showDuration: true,
5958
+ showInstant: true,
5959
+ showPreviousYear: false
5960
+ };
5961
+ const regenerateConcepts = (concepts) => {
5962
+ concepts.forEach((concept) => {
5963
+ concept.fields = [];
5964
+ const shouldShowConcept = this._shouldShowConceptBasedOnPeriodPreferences(
5965
+ concept,
5966
+ sectionPreferences
5967
+ );
5968
+ if (shouldShowConcept) {
5969
+ section2.columns.forEach((column2) => {
5970
+ const conceptPeriodType = concept.periodType;
5971
+ const columnPeriodType = this._inferColumnPeriodType(column2);
5972
+ if (concept.abstract)
5973
+ return;
5974
+ if (conceptPeriodType && columnPeriodType) {
5975
+ if (conceptPeriodType !== columnPeriodType) {
5976
+ return;
5977
+ }
5978
+ }
5979
+ concept.fields.push({
5980
+ id: `${concept.id}_${column2.id}`,
5981
+ conceptId: concept.id,
5982
+ columnId: column2.id,
5983
+ type: this._mapConceptTypeToFieldType(concept.type),
5984
+ label: concept.label,
5985
+ periodStartDate: column2.periodStartDate,
5986
+ periodEndDate: column2.periodEndDate
5987
+ });
5988
+ });
5989
+ }
5990
+ if (concept.children) {
5991
+ regenerateConcepts(concept.children);
5992
+ }
5993
+ });
5994
+ };
5995
+ regenerateConcepts(section2.concepts);
5996
+ }
5997
+ /**
5998
+ * Check if a concept should be shown based on period preferences
5999
+ */
6000
+ _shouldShowConceptBasedOnPeriodPreferences(concept, preferences) {
6001
+ if (concept.abstract) {
6002
+ return true;
6003
+ }
6004
+ if (!concept.periodType) {
6005
+ return true;
6006
+ }
6007
+ if (concept.periodType === "duration" && !preferences.showDuration) {
6008
+ return false;
6009
+ }
6010
+ if (concept.periodType === "instant" && !preferences.showInstant) {
6011
+ return false;
6012
+ }
6013
+ return true;
6014
+ }
6015
+ _inferColumnPeriodType(column2) {
6016
+ if (column2.periodStartDate && column2.periodEndDate) {
6017
+ return column2.periodStartDate === column2.periodEndDate ? "instant" : "duration";
6018
+ }
6019
+ if (column2.periodStartDate && !column2.periodEndDate) {
6020
+ return "instant";
6021
+ }
6022
+ return void 0;
6023
+ }
6024
+ _mapConceptTypeToFieldType(conceptType) {
6025
+ if (!conceptType)
6026
+ return "text";
6027
+ if (conceptType.includes("monetary") || conceptType.includes("Monetary")) {
6028
+ return "number";
6029
+ }
6030
+ if (conceptType.includes("date") || conceptType.includes("Date")) {
6031
+ return "date";
6032
+ }
6033
+ if (conceptType.includes("boolean") || conceptType.includes("Boolean")) {
6034
+ return "boolean";
6035
+ }
6036
+ if (conceptType.includes("integer") || conceptType.includes("Integer")) {
6037
+ return "number";
6038
+ }
6039
+ if (conceptType.includes("decimal") || conceptType.includes("Decimal")) {
6040
+ return "number";
6041
+ }
6042
+ return "text";
5389
6043
  }
5390
6044
  _generateSubmissionData() {
5391
6045
  const submissionData = [];
@@ -5426,20 +6080,6 @@ let JupiterDynamicForm = class extends LitElement {
5426
6080
  }
5427
6081
  return null;
5428
6082
  }
5429
- _findConceptInSection(concepts, conceptId) {
5430
- for (const concept of concepts) {
5431
- if (concept.id === conceptId) {
5432
- return concept;
5433
- }
5434
- if (concept.children) {
5435
- const found = this._findConceptInSection(concept.children, conceptId);
5436
- if (found) {
5437
- return found;
5438
- }
5439
- }
5440
- }
5441
- return null;
5442
- }
5443
6083
  _findSectionForConcept(conceptId) {
5444
6084
  for (const section2 of this._allSections) {
5445
6085
  const concept = this._findConceptInSection(section2.concepts, conceptId);
@@ -5456,10 +6096,10 @@ let JupiterDynamicForm = class extends LitElement {
5456
6096
  return;
5457
6097
  const isInstant = concept.periodType === "instant";
5458
6098
  const column2 = this._findColumnByIdInAllSections(columnId);
5459
- alert("hi");
5460
6099
  console.log(`🔍 [Submission] Concept: ${concept.id}, Column: ${columnId}, Column Period: ${(column2 == null ? void 0 : column2.periodStartDate) || "none"} - ${(column2 == null ? void 0 : column2.periodEndDate) || "none"}`);
5461
6100
  const entry = {
5462
6101
  conceptId: concept.originalConceptId || concept.id,
6102
+ columnId,
5463
6103
  value,
5464
6104
  period: {
5465
6105
  type: concept.periodType || "duration",
@@ -5613,6 +6253,8 @@ let JupiterDynamicForm = class extends LitElement {
5613
6253
  const column2 = this._findColumnByIdInSection(field.columnId, section2);
5614
6254
  const submissionEntry = {
5615
6255
  conceptId: concept.id,
6256
+ columnId: field.columnId,
6257
+ // CRITICAL: Include columnId for draft restoration
5616
6258
  value: fieldValue,
5617
6259
  period: {
5618
6260
  type: concept.periodType || "duration"
@@ -6369,9 +7011,21 @@ __decorateClass([
6369
7011
  __decorateClass([
6370
7012
  n2({ type: Array })
6371
7013
  ], JupiterDynamicForm.prototype, "financialStatementsTypeAxis", 2);
7014
+ __decorateClass([
7015
+ n2({ type: Object, attribute: "dynaforms-metadata" })
7016
+ ], JupiterDynamicForm.prototype, "dynaformsMetadata", 2);
7017
+ __decorateClass([
7018
+ n2({ type: Object, attribute: "dynaforms-facts" })
7019
+ ], JupiterDynamicForm.prototype, "dynaformsFacts", 2);
6372
7020
  __decorateClass([
6373
7021
  r()
6374
7022
  ], JupiterDynamicForm.prototype, "_formData", 2);
7023
+ __decorateClass([
7024
+ r()
7025
+ ], JupiterDynamicForm.prototype, "_draftLoaded", 2);
7026
+ __decorateClass([
7027
+ r()
7028
+ ], JupiterDynamicForm.prototype, "_draftLoadedAt", 2);
6375
7029
  __decorateClass([
6376
7030
  r()
6377
7031
  ], JupiterDynamicForm.prototype, "_preservedFormData", 2);