udp-stencil-component-library 25.18.2-beta.7 → 25.18.2-beta.8
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/cjs/loader.cjs.js +1 -1
- package/dist/cjs/stencil-library.cjs.js +1 -1
- package/dist/cjs/udp-forms-renderer.cjs.entry.js +591 -603
- package/dist/cjs/udp-forms-renderer.entry.cjs.js.map +1 -1
- package/dist/cjs/udp-forms-ui.cjs.entry.js +1 -4
- package/dist/cjs/udp-forms-ui.entry.cjs.js.map +1 -1
- package/dist/collection/components/forms/udp-forms/udp-forms-renderer/udp-forms-renderer-ui/udp-forms-ui.js +1 -4
- package/dist/collection/components/forms/udp-forms/udp-forms-renderer/udp-forms-renderer-ui/udp-forms-ui.js.map +1 -1
- package/dist/collection/components/forms/udp-forms/udp-forms-renderer/udp-forms-renderer-utils/comments-crud-utils.js +153 -0
- package/dist/collection/components/forms/udp-forms/udp-forms-renderer/udp-forms-renderer-utils/comments-crud-utils.js.map +1 -0
- package/dist/collection/components/forms/udp-forms/udp-forms-renderer/udp-forms-renderer-utils/repeated-section-utils.js +104 -0
- package/dist/collection/components/forms/udp-forms/udp-forms-renderer/udp-forms-renderer-utils/repeated-section-utils.js.map +1 -0
- package/dist/collection/components/forms/udp-forms/udp-forms-renderer/{udp-forms-renderer-utils.js → udp-forms-renderer-utils/utils.js} +48 -2
- package/dist/collection/components/forms/udp-forms/udp-forms-renderer/udp-forms-renderer-utils/utils.js.map +1 -0
- package/dist/collection/components/forms/udp-forms/udp-forms-renderer/udp-forms-renderer.js +187 -310
- package/dist/collection/components/forms/udp-forms/udp-forms-renderer/udp-forms-renderer.js.map +1 -1
- package/dist/collection/components/forms/udp-forms/udp-forms-utils/form-handler/UdpFormHandler.js +13 -13
- package/dist/collection/components/forms/udp-forms/udp-forms-utils/form-handler/UdpFormHandler.js.map +1 -1
- package/dist/collection/components/forms/udp-forms/udp-forms-utils/form-submission-handler/FormSubmissionHandler.js +142 -0
- package/dist/collection/components/forms/udp-forms/udp-forms-utils/form-submission-handler/FormSubmissionHandler.js.map +1 -0
- package/dist/collection/components/forms/udp-forms/udp-forms-utils/form-submission-handler/FormSubmissionHandlerFactory.js +3 -10
- package/dist/collection/components/forms/udp-forms/udp-forms-utils/form-submission-handler/FormSubmissionHandlerFactory.js.map +1 -1
- package/dist/collection/components/forms/udp-forms/udp-forms-utils/form-submission-handler/IFormSubmissionHandler.js.map +1 -1
- package/dist/collection/components/forms/udp-forms/udp-forms-utils/types.js.map +1 -1
- package/dist/components/udp-forms-renderer.js +593 -608
- package/dist/components/udp-forms-renderer.js.map +1 -1
- package/dist/components/udp-forms-ui2.js +1 -4
- package/dist/components/udp-forms-ui2.js.map +1 -1
- package/dist/docs.json +1 -1
- package/dist/esm/loader.js +1 -1
- package/dist/esm/stencil-library.js +1 -1
- package/dist/esm/udp-forms-renderer.entry.js +592 -604
- package/dist/esm/udp-forms-renderer.entry.js.map +1 -1
- package/dist/esm/udp-forms-ui.entry.js +1 -4
- package/dist/esm/udp-forms-ui.entry.js.map +1 -1
- package/dist/stencil-library/stencil-library.esm.js +1 -1
- package/dist/stencil-library/udp-forms-renderer.entry.esm.js.map +1 -1
- package/dist/stencil-library/udp-forms-renderer.entry.js +1 -1
- package/dist/stencil-library/udp-forms-renderer.entry.js.map +1 -1
- package/dist/stencil-library/udp-forms-ui.entry.esm.js.map +1 -1
- package/dist/stencil-library/udp-forms-ui.entry.js +1 -1
- package/dist/stencil-library/udp-forms-ui.entry.js.map +1 -1
- package/dist/types/components/forms/udp-forms/udp-forms-renderer/udp-forms-renderer-utils/comments-crud-utils.d.ts +31 -0
- package/dist/types/components/forms/udp-forms/udp-forms-renderer/udp-forms-renderer-utils/repeated-section-utils.d.ts +17 -0
- package/dist/types/components/forms/udp-forms/udp-forms-renderer/{udp-forms-renderer-utils.d.ts → udp-forms-renderer-utils/utils.d.ts} +4 -0
- package/dist/types/components/forms/udp-forms/udp-forms-renderer/udp-forms-renderer.d.ts +6 -10
- package/dist/types/components/forms/udp-forms/udp-forms-utils/form-handler/UdpFormHandler.d.ts +5 -6
- package/dist/types/components/forms/udp-forms/udp-forms-utils/form-submission-handler/FormSubmissionHandler.d.ts +42 -0
- package/dist/types/components/forms/udp-forms/udp-forms-utils/form-submission-handler/FormSubmissionHandlerFactory.d.ts +1 -1
- package/dist/types/components/forms/udp-forms/udp-forms-utils/form-submission-handler/IFormSubmissionHandler.d.ts +44 -5
- package/dist/types/components/forms/udp-forms/udp-forms-utils/types.d.ts +16 -0
- package/package.json +1 -1
- package/dist/collection/components/forms/udp-forms/udp-forms-renderer/udp-forms-renderer-utils.js.map +0 -1
- package/dist/collection/components/forms/udp-forms/udp-forms-utils/form-submission-handler/PrivateFormSubmissionHandler.js +0 -264
- package/dist/collection/components/forms/udp-forms/udp-forms-utils/form-submission-handler/PrivateFormSubmissionHandler.js.map +0 -1
- package/dist/collection/components/forms/udp-forms/udp-forms-utils/form-submission-handler/PublicFormSubmissionHandler.js +0 -63
- package/dist/collection/components/forms/udp-forms/udp-forms-utils/form-submission-handler/PublicFormSubmissionHandler.js.map +0 -1
- package/dist/types/components/forms/udp-forms/udp-forms-utils/form-submission-handler/PrivateFormSubmissionHandler.d.ts +0 -131
- package/dist/types/components/forms/udp-forms/udp-forms-utils/form-submission-handler/PublicFormSubmissionHandler.d.ts +0 -15
|
@@ -2,31 +2,29 @@ import { h } from "@stencil/core";
|
|
|
2
2
|
import { throttle } from "lodash";
|
|
3
3
|
import { getCurrentTenantId } from "../../../../udp-utilities/tenant/tenantUtils";
|
|
4
4
|
import { fetchLatestForms } from "../udp-forms-list/udp-form-api-utils";
|
|
5
|
-
import { UdpFormsTypeEnum, UdpFormsPageIdEnum, UdpFormsSubmissionStatusEnum
|
|
5
|
+
import { UdpFormsTypeEnum, UdpFormsPageIdEnum, UdpFormsSubmissionStatusEnum } from "../udp-forms-utils/enums";
|
|
6
6
|
import { buildEmptyCurrentValues } from "../udp-forms-utils/utils";
|
|
7
7
|
import { FormSubmissionHandlerFactory } from "../udp-forms-utils/form-submission-handler/FormSubmissionHandlerFactory";
|
|
8
8
|
import { UdpFormHandler } from "../udp-forms-utils/form-handler/UdpFormHandler";
|
|
9
9
|
import { UdpFormSubmission } from "../udp-forms-utils/classes/UdpFormSubmission";
|
|
10
10
|
import { UdpForm } from "../udp-forms-utils/classes/UdpForm";
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
11
|
+
import { applyUrlSeedValuesForAll, initializeDynamicSections, initializeDynamicSectionsWithUrlContext, replaceUrlWithSubmissionId, enqueueSnackbarSuccess, enqueueSnackbarError } from "./udp-forms-renderer-utils/utils";
|
|
12
|
+
import { computeDeleteRepeatableSection, computeDuplicateRepeatableSection } from "./udp-forms-renderer-utils/repeated-section-utils";
|
|
13
|
+
import { applyQuestionCommentCrud } from "./udp-forms-renderer-utils/comments-crud-utils";
|
|
13
14
|
export class UdpFormsRenderer {
|
|
14
15
|
constructor() {
|
|
15
16
|
this.isPublic = false;
|
|
16
17
|
this.autoSaveDelay = 2000; // Debounce delay for auto-save in milliseconds (currently disabled)
|
|
17
18
|
this.urlContext = {}; // additional context from URL if needed, eg. generic1, gernic2, generic3, or any initial prepopulated values for form inputs. eg section1.question1 = 'some value'
|
|
18
19
|
this.currentValues = {}; // values of the current form state
|
|
19
|
-
this.formInputSeedValues = {}; // support for a initial set of values to seed the form with
|
|
20
20
|
this.submitSuccessful = false;
|
|
21
21
|
this.isLoading = false;
|
|
22
22
|
this.isSaving = false;
|
|
23
23
|
this.isSubmitted = false;
|
|
24
|
-
this.saveErrorMessage = null;
|
|
25
24
|
this.dynamicSections = [];
|
|
26
25
|
this.isUpdatingSections = false;
|
|
27
26
|
this.reRenderKey = 0;
|
|
28
|
-
this.
|
|
29
|
-
this.isUserUpdatedSections = false;
|
|
27
|
+
this.hasUnsavedChanges = false;
|
|
30
28
|
this.sideSheetFollowUpFormsList = []; // used for follow up forms.
|
|
31
29
|
this.followUpSideSheetTotalItems = 0; // used for follow up forms.
|
|
32
30
|
this.isFollowUpFormsSideSheetOpen = false; // used for follow up forms.
|
|
@@ -46,9 +44,19 @@ export class UdpFormsRenderer {
|
|
|
46
44
|
};
|
|
47
45
|
this.followUpParentSectionKey = ''; // used for follow up forms.
|
|
48
46
|
this.followUpParentQuestionKey = ''; // used for follow up forms.
|
|
47
|
+
// Feature flags for public mode. Keep capabilities in the handlers,
|
|
48
|
+
// but disable UX / automatic flows for now.
|
|
49
|
+
this.publicFeatures = {
|
|
50
|
+
allowDraftSave: false, // public cannot save and return later
|
|
51
|
+
allowComments: true, // public can add comments locally; persistence handled by backend rules
|
|
52
|
+
allowFollowUpForms: false, // public does not support follow-up forms
|
|
53
|
+
};
|
|
49
54
|
this.handleLaunchFollowUpFormSideSheet = async (e) => {
|
|
50
55
|
try {
|
|
51
|
-
|
|
56
|
+
// Public forms do not support follow-up forms.
|
|
57
|
+
if (this.isPublic) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
52
60
|
this.followUpParentSectionKey = e.detail.sectionKey;
|
|
53
61
|
this.followUpParentQuestionKey = e.detail.questionKey;
|
|
54
62
|
await this.loadFollowUpForms(this.followUpParentSectionKey, this.followUpParentQuestionKey);
|
|
@@ -67,75 +75,20 @@ export class UdpFormsRenderer {
|
|
|
67
75
|
this.isUpdatingSections = true;
|
|
68
76
|
this.isLoading = true;
|
|
69
77
|
try {
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
// Find existing repeat group indices
|
|
75
|
-
const repeatKeys = findRepeatGroupKeys(cloningSectionName, this.currentValues);
|
|
76
|
-
const nextRepeatIndex = repeatKeys.length > 0 ? Math.max(...repeatKeys) + 1 : 2;
|
|
77
|
-
const clonedSection = Object.assign(Object.assign({}, structuredClone(sectionToClone)), { formQuestions: sectionToClone.formQuestions.map(q => {
|
|
78
|
-
const newQuestionObj = structuredClone(q);
|
|
79
|
-
newQuestionObj.questionIdentifierKey = `${cloningSectionName}_${nextRepeatIndex}.${q.name}`;
|
|
80
|
-
return newQuestionObj;
|
|
81
|
-
}), isOriginalSection: false, sectionPositionSuffix: nextRepeatIndex });
|
|
82
|
-
// Find the last index of this section group
|
|
83
|
-
let insertAtIndex = index;
|
|
84
|
-
for (let i = index + 1; i < this.dynamicSections.length; i++) {
|
|
85
|
-
const s = this.dynamicSections[i];
|
|
86
|
-
if (s.name === cloningSectionName) {
|
|
87
|
-
insertAtIndex = i;
|
|
88
|
-
}
|
|
89
|
-
else {
|
|
90
|
-
break;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
// Insert after the last repeat of the section group
|
|
94
|
-
this.dynamicSections = [
|
|
95
|
-
...this.dynamicSections.slice(0, insertAtIndex + 1),
|
|
96
|
-
clonedSection,
|
|
97
|
-
...this.dynamicSections.slice(insertAtIndex + 1),
|
|
98
|
-
];
|
|
99
|
-
// Create new initial values structure
|
|
100
|
-
const newCurrentValues = structuredClone(this.udpFormSubmission.data.submissionResponseData);
|
|
101
|
-
clonedSection.formQuestions.forEach(q => {
|
|
102
|
-
var _a, _b, _c, _d;
|
|
103
|
-
const newSectionNameWithSuffix = `${cloningSectionName}_${nextRepeatIndex}`;
|
|
104
|
-
const newQuestionName = q.name;
|
|
105
|
-
if (!newCurrentValues[newSectionNameWithSuffix]) {
|
|
106
|
-
newCurrentValues[newSectionNameWithSuffix] = {};
|
|
107
|
-
}
|
|
108
|
-
// Preserve only Paragraph values from the source section; clear others
|
|
109
|
-
let value = '';
|
|
110
|
-
if (q.fieldTypeId === UdpFormsFieldTypeEnum.Paragraph) {
|
|
111
|
-
// Determine source section key (the section being duplicated)
|
|
112
|
-
const sourceSectionKey = sectionToClone.isOriginalSection
|
|
113
|
-
? cloningSectionName
|
|
114
|
-
: `${cloningSectionName}_${sectionToClone.sectionPositionSuffix}`;
|
|
115
|
-
const sourceVal = (_c = (_b = (_a = this.udpFormSubmission.data.submissionResponseData) === null || _a === void 0 ? void 0 : _a[sourceSectionKey]) === null || _b === void 0 ? void 0 : _b[newQuestionName]) === null || _c === void 0 ? void 0 : _c.value;
|
|
116
|
-
let fieldProps = q === null || q === void 0 ? void 0 : q.fieldProperties;
|
|
117
|
-
if (typeof fieldProps === 'string') {
|
|
118
|
-
try {
|
|
119
|
-
fieldProps = JSON.parse(fieldProps || '{}');
|
|
120
|
-
}
|
|
121
|
-
catch (_e) {
|
|
122
|
-
fieldProps = {};
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
const paragraphDefault = (_d = fieldProps === null || fieldProps === void 0 ? void 0 : fieldProps.paragraphText) !== null && _d !== void 0 ? _d : '';
|
|
126
|
-
value = sourceVal !== null && sourceVal !== void 0 ? sourceVal : paragraphDefault;
|
|
127
|
-
}
|
|
128
|
-
newCurrentValues[newSectionNameWithSuffix][newQuestionName] = { value, comments: [], metadata: {} };
|
|
78
|
+
const { nextDynamicSections, nextValues } = computeDuplicateRepeatableSection({
|
|
79
|
+
dynamicSections: this.dynamicSections,
|
|
80
|
+
values: structuredClone(this.udpFormSubmission.data.submissionResponseData || {}),
|
|
81
|
+
index,
|
|
129
82
|
});
|
|
130
|
-
|
|
131
|
-
this.currentValues = Object.assign({},
|
|
132
|
-
this.udpFormSubmission.data.submissionResponseData = Object.assign({},
|
|
83
|
+
this.dynamicSections = nextDynamicSections;
|
|
84
|
+
this.currentValues = Object.assign({}, nextValues);
|
|
85
|
+
this.udpFormSubmission.data.submissionResponseData = Object.assign({}, nextValues);
|
|
133
86
|
this.triggerFormRerender();
|
|
134
87
|
}
|
|
135
88
|
finally {
|
|
136
89
|
this.isUpdatingSections = false;
|
|
137
90
|
this.isLoading = false;
|
|
138
|
-
this.
|
|
91
|
+
this.hasUnsavedChanges = true;
|
|
139
92
|
}
|
|
140
93
|
};
|
|
141
94
|
/**
|
|
@@ -150,137 +103,90 @@ export class UdpFormsRenderer {
|
|
|
150
103
|
this.isUpdatingSections = true;
|
|
151
104
|
this.isLoading = true;
|
|
152
105
|
try {
|
|
153
|
-
const
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
delete newCurrentValues[sectionKeyToDelete];
|
|
158
|
-
// Remove the section from dynamicSections
|
|
159
|
-
const updatedSections = structuredClone(this.dynamicSections);
|
|
160
|
-
updatedSections.splice(index, 1);
|
|
161
|
-
// Shift all later repeatable sections backward by 1
|
|
162
|
-
updatedSections.forEach(section => {
|
|
163
|
-
if (section.name !== deleteSectionName ||
|
|
164
|
-
section.isOriginalSection ||
|
|
165
|
-
section.sectionPositionSuffix <= deleteSuffix) {
|
|
166
|
-
return;
|
|
167
|
-
}
|
|
168
|
-
const oldSuffix = section.sectionPositionSuffix;
|
|
169
|
-
const oldSectionKey = `${deleteSectionName}_${oldSuffix}`;
|
|
170
|
-
const newSuffix = oldSuffix - 1;
|
|
171
|
-
const newSectionKey = `${deleteSectionName}_${newSuffix}`;
|
|
172
|
-
// Update suffix
|
|
173
|
-
section.sectionPositionSuffix = newSuffix;
|
|
174
|
-
// Update questionIdentifierKeys
|
|
175
|
-
section.formQuestions = section.formQuestions.map(q => {
|
|
176
|
-
const newSectionQuestion = structuredClone(q);
|
|
177
|
-
newSectionQuestion.questionIdentifierKey = `${newSectionKey}.${q.name}`;
|
|
178
|
-
return newSectionQuestion;
|
|
179
|
-
});
|
|
180
|
-
// Move data in initial values
|
|
181
|
-
if (newCurrentValues[oldSectionKey]) {
|
|
182
|
-
newCurrentValues[newSectionKey] = structuredClone(newCurrentValues[oldSectionKey]);
|
|
183
|
-
delete newCurrentValues[oldSectionKey];
|
|
184
|
-
}
|
|
106
|
+
const { nextDynamicSections, nextValues } = computeDeleteRepeatableSection({
|
|
107
|
+
dynamicSections: this.dynamicSections,
|
|
108
|
+
values: Object.assign({}, (this.udpFormSubmission.data.submissionResponseData || {})),
|
|
109
|
+
index,
|
|
185
110
|
});
|
|
186
|
-
this.dynamicSections =
|
|
187
|
-
this.currentValues = Object.assign({},
|
|
188
|
-
this.udpFormSubmission.data.submissionResponseData = Object.assign({},
|
|
111
|
+
this.dynamicSections = nextDynamicSections;
|
|
112
|
+
this.currentValues = Object.assign({}, nextValues);
|
|
113
|
+
this.udpFormSubmission.data.submissionResponseData = Object.assign({}, nextValues);
|
|
189
114
|
this.triggerFormRerender();
|
|
190
115
|
}
|
|
191
116
|
finally {
|
|
192
117
|
this.isUpdatingSections = false;
|
|
193
118
|
this.isLoading = false;
|
|
194
|
-
this.
|
|
119
|
+
this.hasUnsavedChanges = true;
|
|
195
120
|
}
|
|
196
121
|
};
|
|
197
122
|
/**
|
|
198
123
|
* Auto save (background save)
|
|
199
124
|
*/
|
|
200
125
|
this.performBackgroundSaveAndUpdateLocalSubmissionState = async (values) => {
|
|
201
|
-
|
|
202
|
-
|
|
126
|
+
return this.performBackgroundSaveAndUpdateLocalSubmissionStateInternal(values);
|
|
127
|
+
};
|
|
128
|
+
this.performBackgroundSaveAndUpdateLocalSubmissionStateInternal = async (values, opts) => {
|
|
129
|
+
var _a, _b;
|
|
130
|
+
const allowUrlReplace = (_a = opts === null || opts === void 0 ? void 0 : opts.allowUrlReplace) !== null && _a !== void 0 ? _a : !this.isPublic;
|
|
131
|
+
const forceCreateDraftIfMissingId = (_b = opts === null || opts === void 0 ? void 0 : opts.forceCreateDraftIfMissingId) !== null && _b !== void 0 ? _b : false;
|
|
132
|
+
// Public mode: disable draft save flows by default
|
|
133
|
+
if (this.isPublic && !this.publicFeatures.allowDraftSave && !forceCreateDraftIfMissingId) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
203
136
|
try {
|
|
204
|
-
|
|
205
|
-
this.
|
|
206
|
-
|
|
207
|
-
if (!new URLSearchParams(window.location.search).has('udpf_submissionId')) {
|
|
137
|
+
await this.formSubmissionHandler.saveCurrentFormSubmissionState(values, this.udpFormSubmission);
|
|
138
|
+
await this.refreshSubmissionAndSyncState();
|
|
139
|
+
if (allowUrlReplace && !new URLSearchParams(window.location.search).has('udpf_submissionId')) {
|
|
208
140
|
// replace the current entry's query string with udpf_submissionId without needing to know the path
|
|
209
|
-
|
|
141
|
+
replaceUrlWithSubmissionId(this.udpFormSubmission.id, this.history);
|
|
210
142
|
}
|
|
211
143
|
}
|
|
212
144
|
catch (error) {
|
|
213
|
-
this.saveErrorMessage = 'Failed to save form data';
|
|
214
145
|
}
|
|
215
146
|
finally {
|
|
216
147
|
this.isSaving = false;
|
|
217
|
-
this.
|
|
218
|
-
this.isFormDirty = false;
|
|
148
|
+
this.hasUnsavedChanges = false;
|
|
219
149
|
}
|
|
220
150
|
};
|
|
151
|
+
this.refreshSubmissionAndSyncState = async () => {
|
|
152
|
+
var _a, _b;
|
|
153
|
+
if (!((_a = this.udpFormSubmission) === null || _a === void 0 ? void 0 : _a.id))
|
|
154
|
+
return;
|
|
155
|
+
const updated = await this.formSubmissionHandler.fetchAndPopulateUdpFormSubmissionObj(this.udpFormSubmission);
|
|
156
|
+
this.udpFormSubmission = updated;
|
|
157
|
+
this.currentValues = Object.assign({}, (((_b = updated.data) === null || _b === void 0 ? void 0 : _b.submissionResponseData) || {}));
|
|
158
|
+
this.isSubmitted = updated.status === UdpFormsSubmissionStatusEnum.Submitted;
|
|
159
|
+
};
|
|
221
160
|
/**
|
|
222
|
-
* Handle the user saving or deleting a comment
|
|
161
|
+
* Handle the user saving or deleting a comment (pre-submit, private forms only)
|
|
223
162
|
*/
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
const updatedUdpFormSubmission = await this.formSubmissionHandler.saveFormSubmissionComments(values, this.udpFormSubmission);
|
|
230
|
-
this.udpFormSubmission = updatedUdpFormSubmission;
|
|
231
|
-
this.currentValues = Object.assign({}, (((_a = updatedUdpFormSubmission.data) === null || _a === void 0 ? void 0 : _a.submissionResponseData) || {}));
|
|
232
|
-
this.enqueueSnackbar('Saved sucessfully.', {
|
|
233
|
-
variant: 'success',
|
|
234
|
-
anchorOrigin: { vertical: 'top', horizontal: 'center' },
|
|
235
|
-
});
|
|
236
|
-
}
|
|
237
|
-
catch (error) {
|
|
238
|
-
this.enqueueSnackbar('There was an error saving.', {
|
|
239
|
-
variant: 'error',
|
|
240
|
-
anchorOrigin: { vertical: 'top', horizontal: 'center' },
|
|
241
|
-
});
|
|
242
|
-
}
|
|
243
|
-
finally {
|
|
244
|
-
this.isSaving = false;
|
|
245
|
-
this.isUserUpdatedSections = false;
|
|
246
|
-
this.isFormDirty = false;
|
|
247
|
-
}
|
|
248
|
-
};
|
|
163
|
+
// NOTE: comment saves for non-submitted owner flows are now handled by the standard
|
|
164
|
+
// draft save path (manual/background save). Dedicated comment endpoints are used
|
|
165
|
+
// only for:
|
|
166
|
+
// 1) submitted submissions, OR
|
|
167
|
+
// 2) non-owner viewers adding/updating/deleting comments.
|
|
249
168
|
/**
|
|
250
|
-
* Manual save function - debounced to 5 seconds
|
|
169
|
+
* Manual save function - debounced to 5 seconds (private forms only)
|
|
251
170
|
*/
|
|
252
171
|
this.handleManualSave = async (values) => {
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
// return;
|
|
256
|
-
// }
|
|
257
|
-
var _a;
|
|
172
|
+
if (this.isPublic && !this.publicFeatures.allowDraftSave)
|
|
173
|
+
return;
|
|
258
174
|
this.isSaving = true;
|
|
259
|
-
this.saveErrorMessage = null;
|
|
260
175
|
try {
|
|
261
|
-
|
|
262
|
-
this.
|
|
263
|
-
this.currentValues = Object.assign({}, (((_a = updatedUdpFormSubmission.data) === null || _a === void 0 ? void 0 : _a.submissionResponseData) || {}));
|
|
176
|
+
await this.formSubmissionHandler.saveCurrentFormSubmissionState(values, this.udpFormSubmission);
|
|
177
|
+
await this.refreshSubmissionAndSyncState();
|
|
264
178
|
if (!new URLSearchParams(window.location.search).has('udpf_submissionId')) {
|
|
265
179
|
// replace the current entry's query string with udpf_submissionId without needing to know the path
|
|
266
|
-
|
|
180
|
+
replaceUrlWithSubmissionId(this.udpFormSubmission.id, this.history);
|
|
267
181
|
}
|
|
268
|
-
|
|
269
|
-
variant: 'success',
|
|
270
|
-
anchorOrigin: { vertical: 'top', horizontal: 'center' },
|
|
271
|
-
});
|
|
182
|
+
enqueueSnackbarSuccess('Form saved successfully.', this.enqueueSnackbar);
|
|
272
183
|
}
|
|
273
184
|
catch (error) {
|
|
274
|
-
|
|
275
|
-
variant: 'error',
|
|
276
|
-
anchorOrigin: { vertical: 'top', horizontal: 'center' },
|
|
277
|
-
});
|
|
278
|
-
this.saveErrorMessage = 'Failed to save form data';
|
|
185
|
+
enqueueSnackbarError('There was an error saving this form', this.enqueueSnackbar);
|
|
279
186
|
}
|
|
280
187
|
finally {
|
|
281
188
|
this.isSaving = false;
|
|
282
|
-
this.
|
|
283
|
-
this.isFormDirty = false;
|
|
189
|
+
this.hasUnsavedChanges = false;
|
|
284
190
|
}
|
|
285
191
|
};
|
|
286
192
|
this.handleFormChange = (values) => {
|
|
@@ -347,7 +253,9 @@ export class UdpFormsRenderer {
|
|
|
347
253
|
// Listen for launchFollowUpFormSideSheet event from udp-question
|
|
348
254
|
this.el.addEventListener('launchFollowUpFormSideSheet', (e) => this.handleLaunchFollowUpFormSideSheet(e));
|
|
349
255
|
this.el.addEventListener('formDirtyChange', (e) => {
|
|
350
|
-
|
|
256
|
+
// Preserve any previously-detected unsaved changes (e.g. repeatable section add/delete)
|
|
257
|
+
// so a later false emission doesn't hide the save icon.
|
|
258
|
+
this.hasUnsavedChanges = this.hasUnsavedChanges || e.detail;
|
|
351
259
|
});
|
|
352
260
|
}
|
|
353
261
|
}
|
|
@@ -356,17 +264,24 @@ export class UdpFormsRenderer {
|
|
|
356
264
|
this.isLoading = true;
|
|
357
265
|
try {
|
|
358
266
|
// Get client user info if available
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
this.clientUserInfo.
|
|
362
|
-
|
|
363
|
-
|
|
267
|
+
if (this.isPublic) {
|
|
268
|
+
this.clientUserInfo.id = '00000000-0000-0000-0000-000000000001';
|
|
269
|
+
this.clientUserInfo.displayName = 'Anonymous';
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
const user = (_a = this.getUserCallback) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
273
|
+
if (user) {
|
|
274
|
+
this.clientUserInfo.id = user.id || null;
|
|
275
|
+
this.clientUserInfo.displayName = user.name || null;
|
|
276
|
+
this.clientUserInfo.email = user.email || null;
|
|
277
|
+
}
|
|
364
278
|
}
|
|
365
279
|
this.formSubmissionHandler = FormSubmissionHandlerFactory.create(this.isPublic, this.clientUserInfo.id);
|
|
366
280
|
this.udpFormSubmission = new UdpFormSubmission({ id: this.submissionId, formId: this.formId, formVersion: this.version, unityUserId: this.clientUserInfo.id, generic1: this.urlContext.generic1, generic2: this.urlContext.generic2, generic3: this.urlContext.generic3 });
|
|
367
281
|
// fetch existing submission from Udp.FormSubmission if submissionId is provided
|
|
368
282
|
// take exisitng object, and populate with db values, and return new obj with updated values
|
|
369
283
|
if (this.submissionId) {
|
|
284
|
+
// Public users should not open private forms; we rely on backend auth to block.
|
|
370
285
|
this.udpFormSubmission = await this.formSubmissionHandler.fetchAndPopulateUdpFormSubmissionObj(this.udpFormSubmission);
|
|
371
286
|
}
|
|
372
287
|
// get the master form from Udp.Form
|
|
@@ -425,157 +340,117 @@ export class UdpFormsRenderer {
|
|
|
425
340
|
async handleSubmit(values) {
|
|
426
341
|
this.isLoading = true;
|
|
427
342
|
try {
|
|
428
|
-
|
|
343
|
+
await this.formSubmissionHandler.finalizeFormSubmissionState(values, this.udpFormSubmission);
|
|
344
|
+
await this.refreshSubmissionAndSyncState();
|
|
429
345
|
this.submitSuccessful = true;
|
|
430
346
|
}
|
|
431
347
|
catch (error) {
|
|
432
|
-
|
|
433
|
-
variant: 'error',
|
|
434
|
-
anchorOrigin: { vertical: 'top', horizontal: 'center' },
|
|
435
|
-
});
|
|
348
|
+
enqueueSnackbarError('There was an error submitting this form', this.enqueueSnackbar);
|
|
436
349
|
throw error;
|
|
437
350
|
}
|
|
438
351
|
finally {
|
|
439
352
|
this.isLoading = false;
|
|
440
353
|
}
|
|
441
354
|
}
|
|
442
|
-
replaceUrlWithSubmissionId(submissionId) {
|
|
443
|
-
// build a URL that preserves the current pathname + hash but replaces the query string
|
|
444
|
-
const pathname = typeof window !== 'undefined' ? window.location.pathname : `/page/${UdpFormsPageIdEnum.FormRendererPageId}`;
|
|
445
|
-
const hash = typeof window !== 'undefined' ? window.location.hash : '';
|
|
446
|
-
const newUrl = `${pathname}?udpf_submissionId=${submissionId}${hash}`;
|
|
447
|
-
const h = this.history;
|
|
448
|
-
// Prefer history.replace when available, handle react-router v6 navigate function, fallback to push or native replaceState
|
|
449
|
-
if (h) {
|
|
450
|
-
if (typeof h.replace === 'function') {
|
|
451
|
-
h.replace(newUrl);
|
|
452
|
-
return;
|
|
453
|
-
}
|
|
454
|
-
if (typeof h.push === 'function') {
|
|
455
|
-
h.push(newUrl);
|
|
456
|
-
return;
|
|
457
|
-
}
|
|
458
|
-
// react-router v6 exposes a navigate function
|
|
459
|
-
if (typeof h === 'function') {
|
|
460
|
-
try {
|
|
461
|
-
h(newUrl, { replace: true });
|
|
462
|
-
}
|
|
463
|
-
catch (_a) {
|
|
464
|
-
h(newUrl);
|
|
465
|
-
}
|
|
466
|
-
return;
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
if (typeof window !== 'undefined' && window.history && typeof window.history.replaceState === 'function') {
|
|
470
|
-
window.history.replaceState({}, '', newUrl);
|
|
471
|
-
}
|
|
472
|
-
else if (typeof window !== 'undefined') {
|
|
473
|
-
window.location.href = newUrl;
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
355
|
async handleQuestionCommentLiveCRUD(e) {
|
|
477
|
-
var _a, _b, _c;
|
|
356
|
+
var _a, _b, _c, _d, _e, _f;
|
|
357
|
+
if (this.isPublic && !this.publicFeatures.allowComments)
|
|
358
|
+
return;
|
|
478
359
|
try {
|
|
479
360
|
const { type, questionIdentifierKey, commentId } = e.detail;
|
|
480
|
-
const
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
else {
|
|
495
|
-
// ensure arrays/objects exist so later code can safely push/filter
|
|
496
|
-
newCurrentValues[sectionName][questionName].comments = (_a = newCurrentValues[sectionName][questionName].comments) !== null && _a !== void 0 ? _a : [];
|
|
497
|
-
newCurrentValues[sectionName][questionName].draftComments = (_b = newCurrentValues[sectionName][questionName].draftComments) !== null && _b !== void 0 ? _b : [];
|
|
498
|
-
newCurrentValues[sectionName][questionName].metadata = (_c = newCurrentValues[sectionName][questionName].metadata) !== null && _c !== void 0 ? _c : {};
|
|
499
|
-
}
|
|
500
|
-
// normalize draftComments to array if needed (back-compat)
|
|
501
|
-
const maybeDraft = newCurrentValues[sectionName][questionName].draftComments;
|
|
502
|
-
if (maybeDraft && !Array.isArray(maybeDraft)) {
|
|
503
|
-
newCurrentValues[sectionName][questionName].draftComments = [maybeDraft];
|
|
504
|
-
}
|
|
505
|
-
else if (!maybeDraft) {
|
|
506
|
-
newCurrentValues[sectionName][questionName].draftComments = [];
|
|
361
|
+
const result = applyQuestionCommentCrud({
|
|
362
|
+
actionType: type,
|
|
363
|
+
questionIdentifierKey,
|
|
364
|
+
commentId,
|
|
365
|
+
currentSubmissionResponseData: this.udpFormSubmission.data.submissionResponseData || {},
|
|
366
|
+
clientUserInfo: this.clientUserInfo,
|
|
367
|
+
});
|
|
368
|
+
const newCurrentValues = result.nextSubmissionResponseData;
|
|
369
|
+
// keep submission state in sync
|
|
370
|
+
this.udpFormSubmission.data.submissionResponseData = Object.assign({}, newCurrentValues);
|
|
371
|
+
// Edit-ish actions are UI-only (open/close draft editor). They must update currentValues
|
|
372
|
+
// even though they don't persist.
|
|
373
|
+
if (type === 'edit' || type === 'editClose' || type === 'add') {
|
|
374
|
+
this.currentValues = Object.assign({}, newCurrentValues);
|
|
507
375
|
}
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
const draftIdx = draftsArr.findIndex(d => d.commentId === commentId);
|
|
525
|
-
if (draftIdx === -1)
|
|
526
|
-
return;
|
|
527
|
-
const draft = draftsArr[draftIdx];
|
|
528
|
-
const saveTimestamp = draft.timestamp || new Date().toISOString();
|
|
529
|
-
const savedComment = Object.assign(Object.assign({}, draft), { timestamp: saveTimestamp, editedTimestamp: new Date().toISOString(), userId: this.clientUserInfo.id, userDisplayName: this.clientUserInfo.displayName, isDraftComment: false });
|
|
530
|
-
// If a saved comment with same id exists, replace it. Otherwise append.
|
|
531
|
-
const existingIdx = commentsArr.findIndex(c => c.commentId === commentId);
|
|
532
|
-
if (existingIdx !== -1) {
|
|
533
|
-
const newComments = [...commentsArr];
|
|
534
|
-
newComments[existingIdx] = Object.assign({}, savedComment);
|
|
535
|
-
newCurrentValues[sectionName][questionName].comments = newComments;
|
|
376
|
+
// if it's a save or delete action, persist immediately
|
|
377
|
+
if (result.shouldPersist) {
|
|
378
|
+
const submissionIsSubmitted = ((_a = this.udpFormSubmission) === null || _a === void 0 ? void 0 : _a.status) === UdpFormsSubmissionStatusEnum.Submitted;
|
|
379
|
+
const submissionIsOwnedByCurrentUser = ((_b = this.udpFormSubmission) === null || _b === void 0 ? void 0 : _b.unityUserId) === this.clientUserInfo.id;
|
|
380
|
+
// Detect whether this save is updating an existing saved comment vs creating a new one.
|
|
381
|
+
// IMPORTANT: check against the *previous* persisted state (before applyQuestionCommentCrud),
|
|
382
|
+
// because once we apply 'save' locally the comment will exist locally even if it's new.
|
|
383
|
+
const existingSavedComment = (((_e = (_d = (_c = ((this.currentValues || {}))) === null || _c === void 0 ? void 0 : _c[result.sectionKey]) === null || _d === void 0 ? void 0 : _d[result.questionKey]) === null || _e === void 0 ? void 0 : _e.comments) || [])
|
|
384
|
+
.find((c) => (c === null || c === void 0 ? void 0 : c.commentId) === result.commentId && !(c === null || c === void 0 ? void 0 : c.isDeleted));
|
|
385
|
+
// Use dedicated comment APIs in 2 scenarios:
|
|
386
|
+
// 1) Once submitted (public+private) to avoid overwriting submission data.
|
|
387
|
+
// 2) When viewed by a non-owner (read-only mode), since they can't save the whole submission.
|
|
388
|
+
if (submissionIsSubmitted || !submissionIsOwnedByCurrentUser) {
|
|
389
|
+
if (!((_f = this.udpFormSubmission) === null || _f === void 0 ? void 0 : _f.id)) {
|
|
390
|
+
// can't persist without an ID; keep local only
|
|
391
|
+
this.currentValues = Object.assign({}, newCurrentValues);
|
|
536
392
|
}
|
|
537
|
-
else {
|
|
538
|
-
|
|
393
|
+
else if (type === 'save') {
|
|
394
|
+
const valueToPersist = result.valueToPersist;
|
|
395
|
+
if (valueToPersist) {
|
|
396
|
+
try {
|
|
397
|
+
// If this comment already exists, update it; otherwise add it.
|
|
398
|
+
if (existingSavedComment) {
|
|
399
|
+
await this.formSubmissionHandler.updateComment(this.udpFormSubmission, {
|
|
400
|
+
sectionKey: result.sectionKey,
|
|
401
|
+
questionKey: result.questionKey,
|
|
402
|
+
value: valueToPersist,
|
|
403
|
+
commentId: result.commentId,
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
else {
|
|
407
|
+
await this.formSubmissionHandler.addComment(this.udpFormSubmission, {
|
|
408
|
+
sectionKey: result.sectionKey,
|
|
409
|
+
questionKey: result.questionKey,
|
|
410
|
+
value: valueToPersist,
|
|
411
|
+
commentId: result.commentId,
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
await this.refreshSubmissionAndSyncState();
|
|
415
|
+
enqueueSnackbarSuccess(existingSavedComment ? 'Comment updated.' : 'Comment added.', this.enqueueSnackbar);
|
|
416
|
+
}
|
|
417
|
+
catch (error) {
|
|
418
|
+
enqueueSnackbarError(existingSavedComment ? 'Failed to update comment.' : 'Failed to add comment.', this.enqueueSnackbar);
|
|
419
|
+
throw error;
|
|
420
|
+
}
|
|
421
|
+
}
|
|
539
422
|
}
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
break;
|
|
554
|
-
}
|
|
555
|
-
case 'delete': {
|
|
556
|
-
// mark the comment as deleted and clear its value, then persist.
|
|
557
|
-
newCurrentValues[sectionName][questionName].comments = commentsArr.map(c => {
|
|
558
|
-
if (c.commentId === commentId) {
|
|
559
|
-
return Object.assign(Object.assign({}, c), { isDeleted: true, value: '', editedTimestamp: new Date().toISOString() });
|
|
423
|
+
else if (type === 'delete') {
|
|
424
|
+
try {
|
|
425
|
+
await this.formSubmissionHandler.deleteComment(this.udpFormSubmission, {
|
|
426
|
+
sectionKey: result.sectionKey,
|
|
427
|
+
questionKey: result.questionKey,
|
|
428
|
+
commentId: result.commentId,
|
|
429
|
+
});
|
|
430
|
+
await this.refreshSubmissionAndSyncState();
|
|
431
|
+
enqueueSnackbarSuccess('Comment deleted.', this.enqueueSnackbar);
|
|
432
|
+
}
|
|
433
|
+
catch (error) {
|
|
434
|
+
enqueueSnackbarError('Failed to delete comment.', this.enqueueSnackbar);
|
|
435
|
+
throw error;
|
|
560
436
|
}
|
|
561
|
-
|
|
562
|
-
});
|
|
563
|
-
break;
|
|
437
|
+
}
|
|
564
438
|
}
|
|
565
|
-
|
|
566
|
-
//
|
|
567
|
-
|
|
568
|
-
|
|
439
|
+
else {
|
|
440
|
+
// Not submitted yet:
|
|
441
|
+
// - public: persist nothing beyond local state (submission is created on submit)
|
|
442
|
+
// - private + owner: comment edits are persisted via standard submission save
|
|
443
|
+
if (this.isPublic) {
|
|
444
|
+
this.currentValues = Object.assign({}, newCurrentValues);
|
|
445
|
+
}
|
|
446
|
+
else {
|
|
447
|
+
await this.handleManualSave(newCurrentValues);
|
|
448
|
+
}
|
|
569
449
|
}
|
|
570
450
|
}
|
|
571
|
-
// if it's a save or delete action, persist immediately
|
|
572
|
-
if (type === 'save' || type === 'delete') {
|
|
573
|
-
this.udpFormSubmission.data.submissionResponseData = Object.assign({}, newCurrentValues);
|
|
574
|
-
await this.handleCommmentUpdate(newCurrentValues);
|
|
575
|
-
}
|
|
576
451
|
else {
|
|
452
|
+
// Non-persisting actions update UI state only
|
|
577
453
|
this.currentValues = Object.assign({}, newCurrentValues);
|
|
578
|
-
this.udpFormSubmission.data.submissionResponseData = Object.assign({}, newCurrentValues);
|
|
579
454
|
}
|
|
580
455
|
}
|
|
581
456
|
catch (error) {
|
|
@@ -588,7 +463,6 @@ export class UdpFormsRenderer {
|
|
|
588
463
|
async loadFollowUpForms(sectionKey, questionKey) {
|
|
589
464
|
var _a;
|
|
590
465
|
this.isLoading = true;
|
|
591
|
-
this.saveErrorMessage = '';
|
|
592
466
|
try {
|
|
593
467
|
const response = await fetchLatestForms(this.followUpSideSheetListPageNumber, this.FOLLOW_UP_SIDE_SHEET_PAGE_SIZE, [{ searchField: 'type', searchOperator: '=', searchValue: UdpFormsTypeEnum.FollowUp }], { sortDirection: 'DESC', sortColumn: 'lastModifiedOn' });
|
|
594
468
|
const data = response.data;
|
|
@@ -600,7 +474,6 @@ export class UdpFormsRenderer {
|
|
|
600
474
|
}
|
|
601
475
|
catch (err) {
|
|
602
476
|
console.error('Failed to follow up form.', err);
|
|
603
|
-
this.saveErrorMessage = 'Failed to follow up forms.';
|
|
604
477
|
}
|
|
605
478
|
finally {
|
|
606
479
|
this.isLoading = false;
|
|
@@ -618,11 +491,17 @@ export class UdpFormsRenderer {
|
|
|
618
491
|
await this.loadFollowUpForms(this.followUpParentSectionKey, this.followUpParentQuestionKey);
|
|
619
492
|
}
|
|
620
493
|
renderFollowUpSideSheet() {
|
|
494
|
+
if (this.isPublic)
|
|
495
|
+
return null;
|
|
621
496
|
return (h("udp-side-sheet", { title: "Link a Follow Up Form", open: this.isFollowUpFormsSideSheetOpen, onUdpSideSheetClose: () => this.handleSideSheetClose(), position: "right", width: "md" }, this.isLoading && this.isFollowUpFormsSideSheetOpen && h("udp-linear-loader", null), h("udp-list-renderer", { itemComponent: "udp-forms-follow-up-list-card", data: this.sideSheetFollowUpFormsList, pagination: true, isServerSide: true, isLoading: this.isLoading, itemsPerPage: this.FOLLOW_UP_SIDE_SHEET_PAGE_SIZE, currentPage: this.followUpSideSheetListPageNumber, totalItems: this.followUpSideSheetTotalItems, onPageChange: e => this.handleSideSheetPageChange(e.detail), componentDataMap: this.componentMap, spacing: 'md' })));
|
|
622
497
|
}
|
|
623
498
|
isShowManualSaveIcon() {
|
|
624
|
-
|
|
625
|
-
|
|
499
|
+
if (this.isPublic)
|
|
500
|
+
return false; // cannot save a form in public mode. can only submit.
|
|
501
|
+
// NOTE: repeatable section add/delete sets hasUnsavedChanges=true, but udp-forms-ui likely
|
|
502
|
+
// also emits a formDirtyChange event that can override the value back to false.
|
|
503
|
+
// Keep the save icon sticky once we've detected any unsaved change.
|
|
504
|
+
const showSaveIcon = !!this.clientUserInfo.id && (this.hasUnsavedChanges);
|
|
626
505
|
return showSaveIcon;
|
|
627
506
|
}
|
|
628
507
|
;
|
|
@@ -630,7 +509,8 @@ export class UdpFormsRenderer {
|
|
|
630
509
|
return this.isSubmitted || this.udpFormSubmission.unityUserId !== this.clientUserInfo.id;
|
|
631
510
|
}
|
|
632
511
|
render() {
|
|
633
|
-
return (h("div", { key: '
|
|
512
|
+
return (h("div", { key: '37ec47fc7f3ecec70ba7ca3e12717789285be5d8', class: "forms-renderer-container", style: this.isLoading ? { minHeight: '100vh' } : {} }, this.renderFollowUpSideSheet(), h("udp-forms-ui", { udpForm: this.udpForm, currentValues: this.currentValues, udpFormSubmission: this.udpFormSubmission, submitSuccessful: this.submitSuccessful, isSaving: this.isSaving,
|
|
513
|
+
// saveErrorMessage={this.saveErrorMessage}
|
|
634
514
|
// showAutoSaveStatus={this.formSubmissionHandler.supportsAutoSave() && !!this.userId}
|
|
635
515
|
readonly: this.isReadOnlyMode, handleSubmit: this.handleSubmit.bind(this), handleSave: values => Promise.resolve(this.debouncedManualSave(values)), handleChange: this.handleFormChange, handleAction: this.triggerAction, handleFinish: this.handleFinish, clientUserInfo: this.clientUserInfo, isSubmitted: this.isSubmitted, dynamicSections: this.dynamicSections, duplicateRepeatableSection: this.duplicateRepeatableSection, deleteRepeatableSection: this.deleteRepeatableSection, key: `form-rerender-key-${this.reRenderKey}`, isShowManualSaveIcon: this.isShowManualSaveIcon(), isLoading: this.isLoading, performBackgroundSaveAndUpdateLocalSubmissionState: this.performBackgroundSaveAndUpdateLocalSubmissionState })));
|
|
636
516
|
}
|
|
@@ -906,17 +786,14 @@ export class UdpFormsRenderer {
|
|
|
906
786
|
static get states() {
|
|
907
787
|
return {
|
|
908
788
|
"currentValues": {},
|
|
909
|
-
"formInputSeedValues": {},
|
|
910
789
|
"submitSuccessful": {},
|
|
911
790
|
"isLoading": {},
|
|
912
791
|
"isSaving": {},
|
|
913
792
|
"isSubmitted": {},
|
|
914
|
-
"saveErrorMessage": {},
|
|
915
793
|
"dynamicSections": {},
|
|
916
794
|
"isUpdatingSections": {},
|
|
917
795
|
"reRenderKey": {},
|
|
918
|
-
"
|
|
919
|
-
"isUserUpdatedSections": {},
|
|
796
|
+
"hasUnsavedChanges": {},
|
|
920
797
|
"sideSheetFollowUpFormsList": {},
|
|
921
798
|
"followUpSideSheetTotalItems": {},
|
|
922
799
|
"isFollowUpFormsSideSheetOpen": {},
|