jupiter-dynamic-forms 1.17.6 â 1.17.7
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
|
@@ -627,9 +627,10 @@ class XBRLFormBuilder {
|
|
|
627
627
|
const availableColumnIds = columns.map((col) => col.id);
|
|
628
628
|
const roleInfo = { periodTypes, availableColumnIds, availableColumns: columns };
|
|
629
629
|
const conceptTrees = [];
|
|
630
|
+
const conceptIdOccurrences = /* @__PURE__ */ new Map();
|
|
630
631
|
if ((_a = role.presentationLinkbase) == null ? void 0 : _a.concepts) {
|
|
631
632
|
role.presentationLinkbase.concepts.forEach((concept) => {
|
|
632
|
-
const conceptTree = this.buildConceptTree(concept, 0, periodStartDate, periodEndDate, roleInfo, role.id, language);
|
|
633
|
+
const conceptTree = this.buildConceptTree(concept, 0, periodStartDate, periodEndDate, roleInfo, role.id, language, conceptIdOccurrences);
|
|
633
634
|
if (conceptTree) {
|
|
634
635
|
conceptTrees.push(conceptTree);
|
|
635
636
|
}
|
|
@@ -663,8 +664,10 @@ class XBRLFormBuilder {
|
|
|
663
664
|
/**
|
|
664
665
|
* Build concept tree from XBRL presentation concept
|
|
665
666
|
*/
|
|
666
|
-
static buildConceptTree(concept, level, periodStartDate, periodEndDate, roleInfo, sectionId, language = "en") {
|
|
667
|
+
static buildConceptTree(concept, level, periodStartDate, periodEndDate, roleInfo, sectionId, language = "en", conceptIdOccurrences, ancestorPeriodHint) {
|
|
668
|
+
var _a, _b;
|
|
667
669
|
const label = this.getPreferredLabel(concept.labels, language);
|
|
670
|
+
const childPeriodHint = ((_a = concept.preferredLabel) == null ? void 0 : _a.includes("periodStartLabel")) ? "start" : ((_b = concept.preferredLabel) == null ? void 0 : _b.includes("periodEndLabel")) ? "end" : ancestorPeriodHint;
|
|
668
671
|
const fields = [];
|
|
669
672
|
if (!concept.elementAbstract) {
|
|
670
673
|
let columnIds = [];
|
|
@@ -674,11 +677,11 @@ class XBRLFormBuilder {
|
|
|
674
677
|
columnIds = ["duration"];
|
|
675
678
|
}
|
|
676
679
|
columnIds.forEach((columnId) => {
|
|
677
|
-
var
|
|
678
|
-
const column2 = (
|
|
680
|
+
var _a2;
|
|
681
|
+
const column2 = (_a2 = roleInfo == null ? void 0 : roleInfo.availableColumns) == null ? void 0 : _a2.find((c2) => c2.id === columnId);
|
|
679
682
|
const colStartDate = (column2 == null ? void 0 : column2.periodStartDate) || periodStartDate;
|
|
680
683
|
const colEndDate = (column2 == null ? void 0 : column2.periodEndDate) || periodEndDate;
|
|
681
|
-
const field2 = this.createFieldFromConcept(concept, colStartDate, colEndDate, columnId);
|
|
684
|
+
const field2 = this.createFieldFromConcept(concept, colStartDate, colEndDate, columnId, ancestorPeriodHint);
|
|
682
685
|
if (field2)
|
|
683
686
|
fields.push(field2);
|
|
684
687
|
});
|
|
@@ -686,7 +689,7 @@ class XBRLFormBuilder {
|
|
|
686
689
|
const children = [];
|
|
687
690
|
if (concept.children && concept.children.length > 0) {
|
|
688
691
|
concept.children.forEach((child) => {
|
|
689
|
-
const childTree = this.buildConceptTree(child, level + 1, periodStartDate, periodEndDate, roleInfo, sectionId, language);
|
|
692
|
+
const childTree = this.buildConceptTree(child, level + 1, periodStartDate, periodEndDate, roleInfo, sectionId, language, conceptIdOccurrences, childPeriodHint);
|
|
690
693
|
if (childTree) {
|
|
691
694
|
children.push(childTree);
|
|
692
695
|
}
|
|
@@ -696,9 +699,16 @@ class XBRLFormBuilder {
|
|
|
696
699
|
if (!hasContent) {
|
|
697
700
|
return null;
|
|
698
701
|
}
|
|
702
|
+
let conceptId = this.createUniqueConceptId(concept, sectionId);
|
|
703
|
+
if (conceptIdOccurrences) {
|
|
704
|
+
const count = conceptIdOccurrences.get(conceptId) ?? 0;
|
|
705
|
+
conceptIdOccurrences.set(conceptId, count + 1);
|
|
706
|
+
if (count > 0) {
|
|
707
|
+
conceptId = `${conceptId}__occ${count + 1}`;
|
|
708
|
+
}
|
|
709
|
+
}
|
|
699
710
|
return {
|
|
700
|
-
id:
|
|
701
|
-
// Use unique ID for form management
|
|
711
|
+
id: conceptId,
|
|
702
712
|
originalConceptId: concept.id,
|
|
703
713
|
// Store original for submission data
|
|
704
714
|
name: concept.conceptName,
|
|
@@ -724,7 +734,7 @@ class XBRLFormBuilder {
|
|
|
724
734
|
/**
|
|
725
735
|
* Create form field from XBRL concept
|
|
726
736
|
*/
|
|
727
|
-
static createFieldFromConcept(concept, periodStartDate, periodEndDate, forcedColumnId) {
|
|
737
|
+
static createFieldFromConcept(concept, periodStartDate, periodEndDate, forcedColumnId, ancestorPeriodHint) {
|
|
728
738
|
var _a;
|
|
729
739
|
const fieldType = this.mapXBRLTypeToFieldType(concept.type);
|
|
730
740
|
const label = this.getPreferredLabel(concept.labels);
|
|
@@ -750,7 +760,7 @@ class XBRLFormBuilder {
|
|
|
750
760
|
// Validate and set the period type
|
|
751
761
|
periodStartDate: periodStartDate || "2025-01-01",
|
|
752
762
|
periodEndDate: periodEndDate || "2025-12-31",
|
|
753
|
-
periodInstantDate: concept.periodType === "instant" ? ((_a = concept.preferredLabel) == null ? void 0 : _a.includes("periodStartLabel")) ? this.subtractOneDay(periodStartDate || "2025-01-01") : periodEndDate || periodStartDate || "2025-01-01" : void 0
|
|
763
|
+
periodInstantDate: concept.periodType === "instant" ? ((_a = concept.preferredLabel) == null ? void 0 : _a.includes("periodStartLabel")) || ancestorPeriodHint === "start" ? this.subtractOneDay(periodStartDate || "2025-01-01") : periodEndDate || periodStartDate || "2025-01-01" : void 0
|
|
754
764
|
};
|
|
755
765
|
if (concept.id === "nl-cd_DescriptionLocationNL__a64trl") {
|
|
756
766
|
console.log(`đī¸ [Field Creation] Concept: ${concept.id}, periodType from concept: ${concept.periodType}, Field periodType: ${field2.periodType}, ColumnId: ${columnId}`);
|
|
@@ -2139,7 +2149,7 @@ class DraftStorageService {
|
|
|
2139
2149
|
/**
|
|
2140
2150
|
* Create metadata snapshot from current form state
|
|
2141
2151
|
*/
|
|
2142
|
-
createMetadataSnapshot(periodStartDate, periodEndDate, language, selectedRoleIds, allSections, typedMemberData, periodPreferences, periodData, unitData, reportingLanguage = "en", repeatCounts, decimalsData) {
|
|
2152
|
+
createMetadataSnapshot(periodStartDate, periodEndDate, language, selectedRoleIds, allSections, typedMemberData, periodPreferences, periodData, unitData, reportingLanguage = "en", repeatCounts, decimalsData, roleCompletedStates) {
|
|
2143
2153
|
return {
|
|
2144
2154
|
periodStartDate,
|
|
2145
2155
|
periodEndDate,
|
|
@@ -2154,6 +2164,7 @@ class DraftStorageService {
|
|
|
2154
2164
|
unitData,
|
|
2155
2165
|
decimalsData,
|
|
2156
2166
|
repeatCounts,
|
|
2167
|
+
roleCompletedStates,
|
|
2157
2168
|
schemaVersion: this.STORAGE_VERSION
|
|
2158
2169
|
};
|
|
2159
2170
|
}
|
|
@@ -8203,6 +8214,7 @@ let JupiterDynamicForm = class extends LitElement {
|
|
|
8203
8214
|
this._sidePanelCollapsed = false;
|
|
8204
8215
|
this._adminRoleConfigs = {};
|
|
8205
8216
|
this._roleBorderStatuses = /* @__PURE__ */ new Map();
|
|
8217
|
+
this._roleCompletedStates = /* @__PURE__ */ new Map();
|
|
8206
8218
|
this._showRoleContextMenu = false;
|
|
8207
8219
|
this._contextMenuX = 0;
|
|
8208
8220
|
this._contextMenuY = 0;
|
|
@@ -9921,6 +9933,7 @@ let JupiterDynamicForm = class extends LitElement {
|
|
|
9921
9933
|
draftData.forEach((entry, index) => {
|
|
9922
9934
|
console.log(` [${index}] conceptId: ${entry.conceptId}, columnId: ${entry.columnId}, value: ${entry.value}, unit: ${entry.unit || "none"}`);
|
|
9923
9935
|
});
|
|
9936
|
+
const roleCompletedStates = this._roleCompletedStates.size > 0 ? Object.fromEntries(this._roleCompletedStates) : void 0;
|
|
9924
9937
|
const metadata = this._draftStorageService.createMetadataSnapshot(
|
|
9925
9938
|
this.periodStartDate,
|
|
9926
9939
|
this.periodEndDate,
|
|
@@ -9934,7 +9947,8 @@ let JupiterDynamicForm = class extends LitElement {
|
|
|
9934
9947
|
this._unitData,
|
|
9935
9948
|
this.reportingLanguage,
|
|
9936
9949
|
this._repeatCounts,
|
|
9937
|
-
this._decimalsData
|
|
9950
|
+
this._decimalsData,
|
|
9951
|
+
roleCompletedStates
|
|
9938
9952
|
);
|
|
9939
9953
|
const draftPayloadSnapshot = JSON.stringify({
|
|
9940
9954
|
draftData,
|
|
@@ -10064,6 +10078,10 @@ let JupiterDynamicForm = class extends LitElement {
|
|
|
10064
10078
|
this._decimalsData = metadata.decimalsData;
|
|
10065
10079
|
console.log("đ Restored per-fact decimals data:", Object.keys(this._decimalsData).length, "concepts");
|
|
10066
10080
|
}
|
|
10081
|
+
if (metadata.roleCompletedStates) {
|
|
10082
|
+
this._roleCompletedStates = new Map(Object.entries(metadata.roleCompletedStates));
|
|
10083
|
+
console.log("đ Restored role completed states:", Object.keys(metadata.roleCompletedStates).length, "roles");
|
|
10084
|
+
}
|
|
10067
10085
|
if (metadata.periodPreferences) {
|
|
10068
10086
|
if (this._skipPeriodPreferencesRestore) {
|
|
10069
10087
|
console.log("âī¸ Skipping period preferences restoration - using new filter selections");
|
|
@@ -11065,6 +11083,15 @@ let JupiterDynamicForm = class extends LitElement {
|
|
|
11065
11083
|
console.log(`âšī¸ User can re-add this role using the Filter Roles dialog`);
|
|
11066
11084
|
this._closeRoleContextMenu();
|
|
11067
11085
|
}
|
|
11086
|
+
_handleRoleCompletedChange(roleId, checked) {
|
|
11087
|
+
if (checked) {
|
|
11088
|
+
this._roleCompletedStates.set(roleId, true);
|
|
11089
|
+
} else {
|
|
11090
|
+
this._roleCompletedStates.delete(roleId);
|
|
11091
|
+
}
|
|
11092
|
+
this._roleCompletedStates = new Map(this._roleCompletedStates);
|
|
11093
|
+
this._handleSaveDraft("auto");
|
|
11094
|
+
}
|
|
11068
11095
|
_handleSidePanelRoleClick(roleId) {
|
|
11069
11096
|
if (this._activeSidePanelRoleId && this._activeSidePanelRoleId !== roleId) {
|
|
11070
11097
|
this._analyzeAndLogRole(this._activeSidePanelRoleId);
|
|
@@ -11102,6 +11129,10 @@ let JupiterDynamicForm = class extends LitElement {
|
|
|
11102
11129
|
result = "INVALID";
|
|
11103
11130
|
console.warn(`
|
|
11104
11131
|
đ´ RESULT: INVALID (contains validation errors)`);
|
|
11132
|
+
} else if (filledCount === 0) {
|
|
11133
|
+
result = "UNTOUCHED";
|
|
11134
|
+
console.warn(`
|
|
11135
|
+
âŦ RESULT: UNTOUCHED (no data entered)`);
|
|
11105
11136
|
} else if (emptyCount > 0) {
|
|
11106
11137
|
result = "INCOMPLETE";
|
|
11107
11138
|
console.warn(`
|
|
@@ -11115,7 +11146,10 @@ let JupiterDynamicForm = class extends LitElement {
|
|
|
11115
11146
|
`);
|
|
11116
11147
|
if (result === "INVALID")
|
|
11117
11148
|
;
|
|
11118
|
-
else if (result === "
|
|
11149
|
+
else if (result === "UNTOUCHED") {
|
|
11150
|
+
this._roleBorderStatuses.set(roleId, "untouched");
|
|
11151
|
+
this._roleBorderStatuses = new Map(this._roleBorderStatuses);
|
|
11152
|
+
} else if (result === "INCOMPLETE") {
|
|
11119
11153
|
this._roleBorderStatuses.set(roleId, "incomplete");
|
|
11120
11154
|
this._roleBorderStatuses = new Map(this._roleBorderStatuses);
|
|
11121
11155
|
} else {
|
|
@@ -11777,7 +11811,8 @@ let JupiterDynamicForm = class extends LitElement {
|
|
|
11777
11811
|
${filteredSections.map((section2) => {
|
|
11778
11812
|
const hasErrors = this._roleHasErrors(section2.id);
|
|
11779
11813
|
const borderStatus = this._roleBorderStatuses.get(section2.id);
|
|
11780
|
-
const
|
|
11814
|
+
const isManuallyCompleted = this._roleCompletedStates.get(section2.id) === true;
|
|
11815
|
+
const statusClass = isManuallyCompleted ? "has-complete-data" : hasErrors ? "has-errors" : borderStatus === "untouched" ? "has-no-data" : borderStatus === "incomplete" ? "has-empty-fields" : borderStatus === "complete" ? "has-complete-data" : "";
|
|
11781
11816
|
return html`
|
|
11782
11817
|
<div
|
|
11783
11818
|
class="side-panel-role-item ${section2.id === this._activeSidePanelRoleId ? "active" : ""} ${statusClass}"
|
|
@@ -11847,6 +11882,15 @@ let JupiterDynamicForm = class extends LitElement {
|
|
|
11847
11882
|
@column-remove="${this._handleColumnRemove}"
|
|
11848
11883
|
@column-add-request="${this._handleColumnAddRequest}"
|
|
11849
11884
|
></jupiter-form-section>
|
|
11885
|
+
<div class="role-completion-row">
|
|
11886
|
+
<input
|
|
11887
|
+
type="checkbox"
|
|
11888
|
+
id="role-complete-${activeSection.id}"
|
|
11889
|
+
.checked="${this._roleCompletedStates.get(activeSection.id) === true}"
|
|
11890
|
+
@change="${(e2) => this._handleRoleCompletedChange(activeSection.id, e2.target.checked)}"
|
|
11891
|
+
>
|
|
11892
|
+
<label for="role-complete-${activeSection.id}">Mark as completed</label>
|
|
11893
|
+
</div>
|
|
11850
11894
|
` : html`
|
|
11851
11895
|
<div class="no-roles-message">
|
|
11852
11896
|
<h3>${I18n.t("form.noRoleSelected")}</h3>
|
|
@@ -12472,6 +12516,14 @@ JupiterDynamicForm.styles = css`
|
|
|
12472
12516
|
border-left: 2px solid var(--jupiter-error-color, #d32f2f);
|
|
12473
12517
|
}
|
|
12474
12518
|
|
|
12519
|
+
.side-panel-role-item.has-no-data {
|
|
12520
|
+
border-left: 2px solid var(--jupiter-untouched-color, #757575);
|
|
12521
|
+
}
|
|
12522
|
+
|
|
12523
|
+
.side-panel-role-item.has-no-data.active {
|
|
12524
|
+
border-left: 2px solid var(--jupiter-untouched-color, #757575);
|
|
12525
|
+
}
|
|
12526
|
+
|
|
12475
12527
|
.side-panel-role-item.has-empty-fields {
|
|
12476
12528
|
border-left: 2px solid var(--jupiter-warning-color, #ff9800);
|
|
12477
12529
|
}
|
|
@@ -12488,6 +12540,31 @@ JupiterDynamicForm.styles = css`
|
|
|
12488
12540
|
border-left: 2px solid var(--jupiter-success-color, #4caf50);
|
|
12489
12541
|
}
|
|
12490
12542
|
|
|
12543
|
+
.role-completion-row {
|
|
12544
|
+
display: flex;
|
|
12545
|
+
align-items: center;
|
|
12546
|
+
gap: 8px;
|
|
12547
|
+
padding: 12px 16px;
|
|
12548
|
+
border-top: 1px solid var(--jupiter-border-color, #e0e0e0);
|
|
12549
|
+
margin-top: 4px;
|
|
12550
|
+
background: var(--jupiter-background, #fff);
|
|
12551
|
+
}
|
|
12552
|
+
|
|
12553
|
+
.role-completion-row input[type="checkbox"] {
|
|
12554
|
+
width: 16px;
|
|
12555
|
+
height: 16px;
|
|
12556
|
+
cursor: pointer;
|
|
12557
|
+
accent-color: var(--jupiter-success-color, #4caf50);
|
|
12558
|
+
flex-shrink: 0;
|
|
12559
|
+
}
|
|
12560
|
+
|
|
12561
|
+
.role-completion-row label {
|
|
12562
|
+
font-size: 14px;
|
|
12563
|
+
color: var(--jupiter-text-secondary, #555);
|
|
12564
|
+
cursor: pointer;
|
|
12565
|
+
user-select: none;
|
|
12566
|
+
}
|
|
12567
|
+
|
|
12491
12568
|
.side-panel-content {
|
|
12492
12569
|
flex: 1;
|
|
12493
12570
|
overflow-y: auto;
|
|
@@ -12983,6 +13060,9 @@ __decorateClass([
|
|
|
12983
13060
|
__decorateClass([
|
|
12984
13061
|
r()
|
|
12985
13062
|
], JupiterDynamicForm.prototype, "_roleBorderStatuses", 2);
|
|
13063
|
+
__decorateClass([
|
|
13064
|
+
r()
|
|
13065
|
+
], JupiterDynamicForm.prototype, "_roleCompletedStates", 2);
|
|
12986
13066
|
__decorateClass([
|
|
12987
13067
|
r()
|
|
12988
13068
|
], JupiterDynamicForm.prototype, "_showRoleContextMenu", 2);
|