jupiter-dynamic-forms 1.10.1 â 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/README.md +57 -9
- package/dist/core/DynamicFormRefactored.d.ts +18 -0
- package/dist/core/DynamicFormRefactored.d.ts.map +1 -1
- package/dist/core/dynamic-form.d.ts +27 -1
- package/dist/core/dynamic-form.d.ts.map +1 -1
- package/dist/index.js +101 -101
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +670 -17
- package/dist/index.mjs.map +1 -1
- package/dist/schema/types.d.ts +1 -0
- package/dist/schema/types.d.ts.map +1 -1
- package/package.json +1 -1
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:
|
|
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,452 @@ 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);
|
|
5381
5614
|
this.dispatchEvent(new CustomEvent("form-save-draft", {
|
|
5382
5615
|
detail: {
|
|
5383
5616
|
data: this._formData,
|
|
5384
5617
|
draftData,
|
|
5618
|
+
metadata,
|
|
5619
|
+
saved,
|
|
5385
5620
|
valid: this._valid,
|
|
5386
|
-
errors: this._errors
|
|
5621
|
+
errors: this._errors,
|
|
5622
|
+
// Provide data in format for external storage
|
|
5623
|
+
dynaformsFacts: draftData,
|
|
5624
|
+
dynaformsMetadata: metadata
|
|
5387
5625
|
},
|
|
5388
5626
|
bubbles: true
|
|
5389
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";
|
|
5390
6043
|
}
|
|
5391
6044
|
_generateSubmissionData() {
|
|
5392
6045
|
const submissionData = [];
|
|
@@ -5427,20 +6080,6 @@ let JupiterDynamicForm = class extends LitElement {
|
|
|
5427
6080
|
}
|
|
5428
6081
|
return null;
|
|
5429
6082
|
}
|
|
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
6083
|
_findSectionForConcept(conceptId) {
|
|
5445
6084
|
for (const section2 of this._allSections) {
|
|
5446
6085
|
const concept = this._findConceptInSection(section2.concepts, conceptId);
|
|
@@ -5457,10 +6096,10 @@ let JupiterDynamicForm = class extends LitElement {
|
|
|
5457
6096
|
return;
|
|
5458
6097
|
const isInstant = concept.periodType === "instant";
|
|
5459
6098
|
const column2 = this._findColumnByIdInAllSections(columnId);
|
|
5460
|
-
alert("hi");
|
|
5461
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"}`);
|
|
5462
6100
|
const entry = {
|
|
5463
6101
|
conceptId: concept.originalConceptId || concept.id,
|
|
6102
|
+
columnId,
|
|
5464
6103
|
value,
|
|
5465
6104
|
period: {
|
|
5466
6105
|
type: concept.periodType || "duration",
|
|
@@ -5614,6 +6253,8 @@ let JupiterDynamicForm = class extends LitElement {
|
|
|
5614
6253
|
const column2 = this._findColumnByIdInSection(field.columnId, section2);
|
|
5615
6254
|
const submissionEntry = {
|
|
5616
6255
|
conceptId: concept.id,
|
|
6256
|
+
columnId: field.columnId,
|
|
6257
|
+
// CRITICAL: Include columnId for draft restoration
|
|
5617
6258
|
value: fieldValue,
|
|
5618
6259
|
period: {
|
|
5619
6260
|
type: concept.periodType || "duration"
|
|
@@ -6370,9 +7011,21 @@ __decorateClass([
|
|
|
6370
7011
|
__decorateClass([
|
|
6371
7012
|
n2({ type: Array })
|
|
6372
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);
|
|
6373
7020
|
__decorateClass([
|
|
6374
7021
|
r()
|
|
6375
7022
|
], JupiterDynamicForm.prototype, "_formData", 2);
|
|
7023
|
+
__decorateClass([
|
|
7024
|
+
r()
|
|
7025
|
+
], JupiterDynamicForm.prototype, "_draftLoaded", 2);
|
|
7026
|
+
__decorateClass([
|
|
7027
|
+
r()
|
|
7028
|
+
], JupiterDynamicForm.prototype, "_draftLoadedAt", 2);
|
|
6376
7029
|
__decorateClass([
|
|
6377
7030
|
r()
|
|
6378
7031
|
], JupiterDynamicForm.prototype, "_preservedFormData", 2);
|