jupiter-dynamic-forms 1.10.1 → 1.12.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
@@ -1791,6 +1791,194 @@ class I18n {
1791
1791
  }
1792
1792
  }
1793
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
+ }
1794
1982
  const TYPE_INPUT_MAP = {
1795
1983
  // ==========================================
1796
1984
  // Dutch XBRL Types (nl-types namespace)
@@ -3778,7 +3966,7 @@ JupiterFormSection.styles = css`
3778
3966
  }
3779
3967
 
3780
3968
  .typed-member-header-field {
3781
- width: 100%;
3969
+ width: 96%;
3782
3970
  padding: 4px 6px;
3783
3971
  border: 1px solid var(--jupiter-border-color, #ddd);
3784
3972
  border-radius: 3px;
@@ -4625,6 +4813,7 @@ let JupiterDynamicForm = class extends LitElement {
4625
4813
  this.mode = "inputForm";
4626
4814
  this.financialStatementsTypeAxis = [];
4627
4815
  this._formData = {};
4816
+ this._draftLoaded = false;
4628
4817
  this._preservedFormData = {};
4629
4818
  this._typedMemberData = {};
4630
4819
  this._preservedTypedMemberData = {};
@@ -4640,6 +4829,7 @@ let JupiterDynamicForm = class extends LitElement {
4640
4829
  this._periodPreferences = {};
4641
4830
  this._activeSidePanelRoleId = null;
4642
4831
  this._adminRoleConfigs = {};
4832
+ this._skipDraftLoading = false;
4643
4833
  }
4644
4834
  connectedCallback() {
4645
4835
  super.connectedCallback();
@@ -4658,6 +4848,9 @@ let JupiterDynamicForm = class extends LitElement {
4658
4848
  }
4659
4849
  _initializeForm() {
4660
4850
  var _a;
4851
+ if (!this._draftStorageService) {
4852
+ this._draftStorageService = new DraftStorageService(false);
4853
+ }
4661
4854
  if (this.xbrlInput) {
4662
4855
  try {
4663
4856
  console.log("🔄 Initializing form from XBRL input:", this.xbrlInput);
@@ -4717,6 +4910,11 @@ let JupiterDynamicForm = class extends LitElement {
4717
4910
  if ((_a = this.xbrlInput) == null ? void 0 : _a.initialData) {
4718
4911
  this._formData = { ...this._formData, ...this.xbrlInput.initialData };
4719
4912
  }
4913
+ if (!this._skipDraftLoading) {
4914
+ this._loadDraftIfExists();
4915
+ } else {
4916
+ console.log("â­ī¸ Skipping draft loading during preference update");
4917
+ }
4720
4918
  this._validateForm();
4721
4919
  }
4722
4920
  _getDefaultSchema() {
@@ -4934,7 +5132,24 @@ let JupiterDynamicForm = class extends LitElement {
4934
5132
  if (preferencesChanged) {
4935
5133
  this._periodPreferences = periodPreferences;
4936
5134
  console.log("📊 Period preferences updated:", this._periodPreferences);
5135
+ this._skipDraftLoading = true;
4937
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
+ }
4938
5153
  } else {
4939
5154
  this._applyRoleFilter();
4940
5155
  }
@@ -4977,6 +5192,7 @@ let JupiterDynamicForm = class extends LitElement {
4977
5192
  }
4978
5193
  _handleFieldChange(event) {
4979
5194
  const { fieldId, conceptId, columnId, value } = event.detail;
5195
+ console.log(`📝 Field change: conceptId=${conceptId}, columnId=${columnId}, value=${value}, fieldId=${fieldId}`);
4980
5196
  const updatedFormData = { ...this._formData };
4981
5197
  if (!updatedFormData[conceptId]) {
4982
5198
  updatedFormData[conceptId] = {};
@@ -4984,6 +5200,7 @@ let JupiterDynamicForm = class extends LitElement {
4984
5200
  const oldValue = updatedFormData[conceptId][columnId];
4985
5201
  updatedFormData[conceptId] = { ...updatedFormData[conceptId], [columnId]: value };
4986
5202
  this._formData = updatedFormData;
5203
+ console.log(`💾 Updated formData[${conceptId}]:`, this._formData[conceptId]);
4987
5204
  this._touched.add(`${conceptId}-${columnId}`);
4988
5205
  this._dirty = true;
4989
5206
  this._validateForm();
@@ -5377,16 +5594,456 @@ let JupiterDynamicForm = class extends LitElement {
5377
5594
  console.log("✅ Form submit event dispatched");
5378
5595
  }
5379
5596
  _handleSaveDraft() {
5597
+ console.log("💾 Raw form data before submission generation:", this._formData);
5380
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);
5614
+ this.dynaformsFacts = draftData;
5615
+ this.dynaformsMetadata = metadata;
5381
5616
  this.dispatchEvent(new CustomEvent("form-save-draft", {
5382
5617
  detail: {
5383
5618
  data: this._formData,
5384
5619
  draftData,
5620
+ metadata,
5621
+ saved,
5385
5622
  valid: this._valid,
5386
- errors: this._errors
5623
+ errors: this._errors,
5624
+ // JSON data ready for external database storage
5625
+ dynaformsFacts: draftData,
5626
+ dynaformsMetadata: metadata
5387
5627
  },
5388
- bubbles: true
5628
+ bubbles: true,
5629
+ composed: true
5630
+ }));
5631
+ console.log("💾 Draft saved - localStorage + event emitted", {
5632
+ entries: draftData.length,
5633
+ saved,
5634
+ roles: this._selectedRoleIds.length,
5635
+ customColumns: metadata.customColumns.length,
5636
+ eventEmitted: true
5637
+ });
5638
+ }
5639
+ // ===========================================
5640
+ // Draft Loading & Restoration
5641
+ // ===========================================
5642
+ async _loadDraftIfExists() {
5643
+ console.log("📋 Checking for saved draft...");
5644
+ if (this.dynaformsFacts && this.dynaformsMetadata) {
5645
+ console.log("đŸ“Ļ Using external draft data from properties");
5646
+ const draft2 = {
5647
+ formData: this.dynaformsFacts,
5648
+ metadata: this.dynaformsMetadata
5649
+ };
5650
+ await this._restoreFromDraft(draft2);
5651
+ this._draftLoaded = true;
5652
+ this._draftLoadedAt = this.dynaformsMetadata.savedAt || (/* @__PURE__ */ new Date()).toISOString();
5653
+ this.dispatchEvent(new CustomEvent("form-draft-loaded", {
5654
+ detail: {
5655
+ draft: draft2,
5656
+ source: "external",
5657
+ compatible: true,
5658
+ warnings: []
5659
+ },
5660
+ bubbles: true,
5661
+ composed: true
5662
+ }));
5663
+ console.log("đŸ“Ĩ External draft loaded successfully");
5664
+ return;
5665
+ }
5666
+ if (!this._draftStorageService.hasDraft()) {
5667
+ console.log("â„šī¸ No saved draft found");
5668
+ return;
5669
+ }
5670
+ const draft = this._draftStorageService.loadDraft();
5671
+ if (!draft) {
5672
+ console.warn("âš ī¸ Failed to load draft");
5673
+ return;
5674
+ }
5675
+ const { compatible, warnings } = this._draftStorageService.validateDraftCompatibility(
5676
+ draft,
5677
+ this.periodStartDate,
5678
+ this.periodEndDate
5679
+ );
5680
+ if (warnings.length > 0) {
5681
+ console.warn("âš ī¸ Draft compatibility warnings:", warnings);
5682
+ }
5683
+ await this._restoreFromDraft(draft);
5684
+ this.dispatchEvent(new CustomEvent("form-draft-loaded", {
5685
+ detail: {
5686
+ draft,
5687
+ compatible,
5688
+ warnings
5689
+ },
5690
+ bubbles: true,
5691
+ composed: true
5389
5692
  }));
5693
+ console.log("đŸ“Ĩ Draft loaded successfully", {
5694
+ entries: draft.formData.length,
5695
+ savedAt: draft.metadata.savedAt,
5696
+ age: this._draftStorageService.getDraftAge()
5697
+ });
5698
+ }
5699
+ async _restoreFromDraft(draft) {
5700
+ var _a;
5701
+ const { formData, metadata } = draft;
5702
+ if (metadata.selectedRoleIds && metadata.selectedRoleIds.length > 0) {
5703
+ this._selectedRoleIds = metadata.selectedRoleIds;
5704
+ console.log(`🔄 Restored ${this._selectedRoleIds.length} selected roles`);
5705
+ }
5706
+ if (metadata.typedMemberData) {
5707
+ this._typedMemberData = metadata.typedMemberData;
5708
+ this._preservedTypedMemberData = {};
5709
+ console.log("🔄 Restored typed member data");
5710
+ }
5711
+ if (metadata.periodPreferences) {
5712
+ this._periodPreferences = metadata.periodPreferences;
5713
+ console.log("🔄 Restored period preferences (including previous year settings):", this._periodPreferences);
5714
+ if (this.xbrlInput) {
5715
+ console.log("🔄 Rebuilding schema with restored period preferences...");
5716
+ this._currentSchema = XBRLFormBuilder.buildFormSchema(
5717
+ this.xbrlInput,
5718
+ this.periodStartDate,
5719
+ this.periodEndDate,
5720
+ this.language,
5721
+ this._periodPreferences
5722
+ );
5723
+ this._allSections = [...this._currentSchema.sections];
5724
+ if (this.financialStatementsTypeAxis && this.financialStatementsTypeAxis.length > 0) {
5725
+ this._allSections = this._filterRolesByFinancialStatementsType(this._allSections);
5726
+ }
5727
+ console.log("✅ Schema rebuilt with restored period preferences");
5728
+ if (metadata.customColumns && metadata.customColumns.length > 0) {
5729
+ this._mergeAdditionalCustomColumns(metadata.customColumns);
5730
+ console.log(`🔄 Merged ${metadata.customColumns.length} additional custom columns`);
5731
+ }
5732
+ }
5733
+ } else {
5734
+ if (metadata.customColumns && metadata.customColumns.length > 0) {
5735
+ this._restoreCustomColumns(metadata.customColumns);
5736
+ console.log(`🔄 Restored ${metadata.customColumns.length} custom columns`);
5737
+ }
5738
+ }
5739
+ const restoredFormData = {};
5740
+ formData.forEach((entry) => {
5741
+ let { conceptId, value, columnId, period } = entry;
5742
+ if (!columnId && period) {
5743
+ columnId = this._inferColumnIdFromPeriod(period, conceptId);
5744
+ if (!columnId) {
5745
+ console.warn(`âš ī¸ Could not infer columnId for concept ${conceptId}, skipping...`);
5746
+ return;
5747
+ }
5748
+ }
5749
+ const actualConceptId = this._findActualConceptId(conceptId);
5750
+ const conceptIdToUse = actualConceptId || conceptId;
5751
+ if (!restoredFormData[conceptIdToUse]) {
5752
+ restoredFormData[conceptIdToUse] = {};
5753
+ }
5754
+ restoredFormData[conceptIdToUse][columnId] = value;
5755
+ console.log(`đŸ“Ļ Restored: ${conceptIdToUse}[${columnId}] = ${value}`);
5756
+ });
5757
+ this._formData = { ...this._formData, ...restoredFormData };
5758
+ console.log(`🔄 Restored ${Object.keys(restoredFormData).length} concepts with data`);
5759
+ if (this._selectedRoleIds.length > 0) {
5760
+ this._applyRoleFilter();
5761
+ }
5762
+ this._dirty = true;
5763
+ this._touched.clear();
5764
+ this._validateForm();
5765
+ this._allSections = [...this._allSections];
5766
+ this.requestUpdate();
5767
+ await this.updateComplete;
5768
+ await new Promise((resolve) => setTimeout(resolve, 100));
5769
+ const fieldCount = ((_a = this.shadowRoot) == null ? void 0 : _a.querySelectorAll("input, textarea, select").length) || 0;
5770
+ console.log(`🔍 Found ${fieldCount} fields in DOM after update`);
5771
+ if (fieldCount > 0) {
5772
+ this._populateFieldValues(restoredFormData);
5773
+ } else {
5774
+ console.error("❌ No fields found in DOM even after updateComplete");
5775
+ }
5776
+ console.log("✅ Draft restoration completed");
5777
+ }
5778
+ _findActualConceptId(conceptId) {
5779
+ for (const section2 of this._allSections) {
5780
+ const found = this._findActualConceptIdInTree(section2.concepts, conceptId);
5781
+ if (found)
5782
+ return found;
5783
+ }
5784
+ return null;
5785
+ }
5786
+ _findActualConceptIdInTree(concepts, conceptId) {
5787
+ for (const concept of concepts) {
5788
+ if (concept.originalConceptId === conceptId || concept.id === conceptId) {
5789
+ return concept.id;
5790
+ }
5791
+ if (concept.children) {
5792
+ const found = this._findActualConceptIdInTree(concept.children, conceptId);
5793
+ if (found)
5794
+ return found;
5795
+ }
5796
+ }
5797
+ return null;
5798
+ }
5799
+ _inferColumnIdFromPeriod(period, conceptId) {
5800
+ for (const section2 of this._allSections) {
5801
+ const concept = this._findConceptInSection(section2.concepts, conceptId);
5802
+ if (concept && section2.columns) {
5803
+ for (const column2 of section2.columns) {
5804
+ const isInstant = period.type === "instant";
5805
+ const isDuration = period.type === "duration";
5806
+ if (isInstant && period.date) {
5807
+ if (column2.periodStartDate === period.date || column2.periodStartDate === column2.periodEndDate && column2.periodStartDate === period.date) {
5808
+ console.log(`✓ Inferred columnId: ${column2.id} for concept ${conceptId}`);
5809
+ return column2.id;
5810
+ }
5811
+ } else if (isDuration && period.startDate && period.endDate) {
5812
+ if (column2.periodStartDate === period.startDate && column2.periodEndDate === period.endDate) {
5813
+ console.log(`✓ Inferred columnId: ${column2.id} for concept ${conceptId}`);
5814
+ return column2.id;
5815
+ }
5816
+ }
5817
+ }
5818
+ if (period.type === "instant") {
5819
+ const instantCol = section2.columns.find((c2) => c2.id === "instant");
5820
+ if (instantCol)
5821
+ return instantCol.id;
5822
+ } else {
5823
+ const durationCol = section2.columns.find((c2) => c2.id === "duration");
5824
+ if (durationCol)
5825
+ return durationCol.id;
5826
+ }
5827
+ }
5828
+ }
5829
+ return null;
5830
+ }
5831
+ _findConceptInSection(concepts, conceptId) {
5832
+ for (const concept of concepts) {
5833
+ if (concept.id === conceptId || concept.originalConceptId === conceptId) {
5834
+ return concept;
5835
+ }
5836
+ if (concept.children) {
5837
+ const found = this._findConceptInSection(concept.children, conceptId);
5838
+ if (found)
5839
+ return found;
5840
+ }
5841
+ }
5842
+ return null;
5843
+ }
5844
+ _populateFieldValues(formData) {
5845
+ let populatedCount = 0;
5846
+ let notFoundCount = 0;
5847
+ console.log("🔍 Starting field population...");
5848
+ console.log("đŸ“Ļ Form data to populate:", formData);
5849
+ Object.keys(formData).forEach((conceptId) => {
5850
+ const conceptData = formData[conceptId];
5851
+ Object.keys(conceptData).forEach((columnId) => {
5852
+ var _a, _b;
5853
+ const value = conceptData[columnId];
5854
+ const fieldId = `${conceptId}__${columnId}`;
5855
+ console.log(`🔍 Looking for field: ${fieldId}`);
5856
+ const fieldElement = (_a = this.shadowRoot) == null ? void 0 : _a.querySelector(`#${CSS.escape(fieldId)}`);
5857
+ if (fieldElement) {
5858
+ if (fieldElement instanceof HTMLInputElement || fieldElement instanceof HTMLTextAreaElement || fieldElement instanceof HTMLSelectElement) {
5859
+ if (fieldElement.type === "checkbox") {
5860
+ fieldElement.checked = Boolean(value);
5861
+ } else {
5862
+ fieldElement.value = value !== null && value !== void 0 ? String(value) : "";
5863
+ }
5864
+ console.log(` ✅ Populated field ${fieldId} with value:`, value);
5865
+ populatedCount++;
5866
+ }
5867
+ } else {
5868
+ console.warn(` ❌ Field element NOT FOUND: ${fieldId}`);
5869
+ 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])));
5870
+ notFoundCount++;
5871
+ }
5872
+ });
5873
+ });
5874
+ console.log(`✅ Field population complete: ${populatedCount} populated, ${notFoundCount} not found`);
5875
+ }
5876
+ _restoreCustomColumns(customColumns) {
5877
+ const columnsBySection = /* @__PURE__ */ new Map();
5878
+ customColumns.forEach((col) => {
5879
+ if (!columnsBySection.has(col.sectionId)) {
5880
+ columnsBySection.set(col.sectionId, []);
5881
+ }
5882
+ columnsBySection.get(col.sectionId).push(col);
5883
+ });
5884
+ this._allSections.forEach((section2) => {
5885
+ const savedColumns = columnsBySection.get(section2.id);
5886
+ if (savedColumns) {
5887
+ section2.columns = savedColumns.map((col) => ({
5888
+ id: col.columnId,
5889
+ title: col.label,
5890
+ type: col.dimensionData ? "dimension" : "base",
5891
+ periodStartDate: col.startDate || col.date,
5892
+ periodEndDate: col.endDate || col.date,
5893
+ dimensionData: col.dimensionData,
5894
+ order: 0,
5895
+ removable: col.columnId !== "duration" && col.columnId !== "instant"
5896
+ }));
5897
+ this._regenerateFieldsForSection(section2);
5898
+ console.log(` └─ Restored ${savedColumns.length} columns for section ${section2.id}`);
5899
+ }
5900
+ });
5901
+ if (this._currentSchema) {
5902
+ this._currentSchema = {
5903
+ ...this._currentSchema,
5904
+ sections: this._allSections
5905
+ };
5906
+ }
5907
+ }
5908
+ /**
5909
+ * Merge additional custom columns that were manually added by user
5910
+ * This preserves default columns (duration, instant, previous year) generated by schema builder
5911
+ * and only adds custom columns that don't already exist
5912
+ */
5913
+ _mergeAdditionalCustomColumns(customColumns) {
5914
+ const columnsBySection = /* @__PURE__ */ new Map();
5915
+ customColumns.forEach((col) => {
5916
+ const isManuallyAdded = col.columnId.startsWith("col-");
5917
+ if (isManuallyAdded) {
5918
+ if (!columnsBySection.has(col.sectionId)) {
5919
+ columnsBySection.set(col.sectionId, []);
5920
+ }
5921
+ columnsBySection.get(col.sectionId).push(col);
5922
+ }
5923
+ });
5924
+ this._allSections.forEach((section2) => {
5925
+ const customColumnsForSection = columnsBySection.get(section2.id);
5926
+ if (customColumnsForSection && customColumnsForSection.length > 0) {
5927
+ if (!section2.columns) {
5928
+ section2.columns = [];
5929
+ }
5930
+ customColumnsForSection.forEach((col) => {
5931
+ const existingColumn = section2.columns.find((c2) => c2.id === col.columnId);
5932
+ if (!existingColumn) {
5933
+ const newColumn = {
5934
+ id: col.columnId,
5935
+ title: col.label,
5936
+ type: col.dimensionData ? "dimension" : "base",
5937
+ periodStartDate: col.startDate || col.date,
5938
+ periodEndDate: col.endDate || col.date,
5939
+ dimensionData: col.dimensionData,
5940
+ order: section2.columns.length,
5941
+ removable: true
5942
+ };
5943
+ section2.columns.push(newColumn);
5944
+ console.log(` └─ Added custom column ${col.columnId} to section ${section2.id}`);
5945
+ }
5946
+ });
5947
+ this._regenerateFieldsForSection(section2);
5948
+ }
5949
+ });
5950
+ if (this._currentSchema) {
5951
+ this._currentSchema = {
5952
+ ...this._currentSchema,
5953
+ sections: this._allSections
5954
+ };
5955
+ }
5956
+ }
5957
+ _regenerateFieldsForSection(section2) {
5958
+ if (!section2.columns)
5959
+ return;
5960
+ const sectionPreferences = this._periodPreferences[section2.id] || {
5961
+ showDuration: true,
5962
+ showInstant: true,
5963
+ showPreviousYear: false
5964
+ };
5965
+ const regenerateConcepts = (concepts) => {
5966
+ concepts.forEach((concept) => {
5967
+ concept.fields = [];
5968
+ const shouldShowConcept = this._shouldShowConceptBasedOnPeriodPreferences(
5969
+ concept,
5970
+ sectionPreferences
5971
+ );
5972
+ if (shouldShowConcept) {
5973
+ section2.columns.forEach((column2) => {
5974
+ const conceptPeriodType = concept.periodType;
5975
+ const columnPeriodType = this._inferColumnPeriodType(column2);
5976
+ if (concept.abstract)
5977
+ return;
5978
+ if (conceptPeriodType && columnPeriodType) {
5979
+ if (conceptPeriodType !== columnPeriodType) {
5980
+ return;
5981
+ }
5982
+ }
5983
+ concept.fields.push({
5984
+ id: `${concept.id}_${column2.id}`,
5985
+ conceptId: concept.id,
5986
+ columnId: column2.id,
5987
+ type: this._mapConceptTypeToFieldType(concept.type),
5988
+ label: concept.label,
5989
+ periodStartDate: column2.periodStartDate,
5990
+ periodEndDate: column2.periodEndDate
5991
+ });
5992
+ });
5993
+ }
5994
+ if (concept.children) {
5995
+ regenerateConcepts(concept.children);
5996
+ }
5997
+ });
5998
+ };
5999
+ regenerateConcepts(section2.concepts);
6000
+ }
6001
+ /**
6002
+ * Check if a concept should be shown based on period preferences
6003
+ */
6004
+ _shouldShowConceptBasedOnPeriodPreferences(concept, preferences) {
6005
+ if (concept.abstract) {
6006
+ return true;
6007
+ }
6008
+ if (!concept.periodType) {
6009
+ return true;
6010
+ }
6011
+ if (concept.periodType === "duration" && !preferences.showDuration) {
6012
+ return false;
6013
+ }
6014
+ if (concept.periodType === "instant" && !preferences.showInstant) {
6015
+ return false;
6016
+ }
6017
+ return true;
6018
+ }
6019
+ _inferColumnPeriodType(column2) {
6020
+ if (column2.periodStartDate && column2.periodEndDate) {
6021
+ return column2.periodStartDate === column2.periodEndDate ? "instant" : "duration";
6022
+ }
6023
+ if (column2.periodStartDate && !column2.periodEndDate) {
6024
+ return "instant";
6025
+ }
6026
+ return void 0;
6027
+ }
6028
+ _mapConceptTypeToFieldType(conceptType) {
6029
+ if (!conceptType)
6030
+ return "text";
6031
+ if (conceptType.includes("monetary") || conceptType.includes("Monetary")) {
6032
+ return "number";
6033
+ }
6034
+ if (conceptType.includes("date") || conceptType.includes("Date")) {
6035
+ return "date";
6036
+ }
6037
+ if (conceptType.includes("boolean") || conceptType.includes("Boolean")) {
6038
+ return "boolean";
6039
+ }
6040
+ if (conceptType.includes("integer") || conceptType.includes("Integer")) {
6041
+ return "number";
6042
+ }
6043
+ if (conceptType.includes("decimal") || conceptType.includes("Decimal")) {
6044
+ return "number";
6045
+ }
6046
+ return "text";
5390
6047
  }
5391
6048
  _generateSubmissionData() {
5392
6049
  const submissionData = [];
@@ -5427,20 +6084,6 @@ let JupiterDynamicForm = class extends LitElement {
5427
6084
  }
5428
6085
  return null;
5429
6086
  }
5430
- _findConceptInSection(concepts, conceptId) {
5431
- for (const concept of concepts) {
5432
- if (concept.id === conceptId) {
5433
- return concept;
5434
- }
5435
- if (concept.children) {
5436
- const found = this._findConceptInSection(concept.children, conceptId);
5437
- if (found) {
5438
- return found;
5439
- }
5440
- }
5441
- }
5442
- return null;
5443
- }
5444
6087
  _findSectionForConcept(conceptId) {
5445
6088
  for (const section2 of this._allSections) {
5446
6089
  const concept = this._findConceptInSection(section2.concepts, conceptId);
@@ -5457,10 +6100,10 @@ let JupiterDynamicForm = class extends LitElement {
5457
6100
  return;
5458
6101
  const isInstant = concept.periodType === "instant";
5459
6102
  const column2 = this._findColumnByIdInAllSections(columnId);
5460
- alert("hi");
5461
6103
  console.log(`🔍 [Submission] Concept: ${concept.id}, Column: ${columnId}, Column Period: ${(column2 == null ? void 0 : column2.periodStartDate) || "none"} - ${(column2 == null ? void 0 : column2.periodEndDate) || "none"}`);
5462
6104
  const entry = {
5463
6105
  conceptId: concept.originalConceptId || concept.id,
6106
+ columnId,
5464
6107
  value,
5465
6108
  period: {
5466
6109
  type: concept.periodType || "duration",
@@ -5614,6 +6257,8 @@ let JupiterDynamicForm = class extends LitElement {
5614
6257
  const column2 = this._findColumnByIdInSection(field.columnId, section2);
5615
6258
  const submissionEntry = {
5616
6259
  conceptId: concept.id,
6260
+ columnId: field.columnId,
6261
+ // CRITICAL: Include columnId for draft restoration
5617
6262
  value: fieldValue,
5618
6263
  period: {
5619
6264
  type: concept.periodType || "duration"
@@ -6370,9 +7015,21 @@ __decorateClass([
6370
7015
  __decorateClass([
6371
7016
  n2({ type: Array })
6372
7017
  ], JupiterDynamicForm.prototype, "financialStatementsTypeAxis", 2);
7018
+ __decorateClass([
7019
+ n2({ type: Object, attribute: "dynaforms-metadata" })
7020
+ ], JupiterDynamicForm.prototype, "dynaformsMetadata", 2);
7021
+ __decorateClass([
7022
+ n2({ type: Object, attribute: "dynaforms-facts" })
7023
+ ], JupiterDynamicForm.prototype, "dynaformsFacts", 2);
6373
7024
  __decorateClass([
6374
7025
  r()
6375
7026
  ], JupiterDynamicForm.prototype, "_formData", 2);
7027
+ __decorateClass([
7028
+ r()
7029
+ ], JupiterDynamicForm.prototype, "_draftLoaded", 2);
7030
+ __decorateClass([
7031
+ r()
7032
+ ], JupiterDynamicForm.prototype, "_draftLoadedAt", 2);
6376
7033
  __decorateClass([
6377
7034
  r()
6378
7035
  ], JupiterDynamicForm.prototype, "_preservedFormData", 2);