Skip to content

Commit c2b6fc5

Browse files
author
Revanth Banala
committed
Removed !initialRenderComplete.value from formviewer.vue
1 parent 98eb388 commit c2b6fc5

File tree

2 files changed

+30
-31
lines changed

2 files changed

+30
-31
lines changed

app/frontend/src/components/designer/FormViewer.vue

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -117,11 +117,10 @@ const authStore = useAuthStore();
117117
const formStore = useFormStore();
118118
const notificationStore = useNotificationStore();
119119
120-
// Local crash-recovery autosave
120+
// Local crash-recovery autosave (storage layer)
121121
const localAutosave = useLocalAutosave();
122122
const showLocalRecoveryDialog = ref(false);
123-
const autosaveReady = ref(false);
124-
const initialRenderComplete = ref(false); // Prevent autosave firing during Form.io internal events
123+
const autosaveReady = ref(false); // becomes true after first Form.io render
125124
126125
const { config } = storeToRefs(appStore);
127126
const { authenticated, keycloak, tokenParsed, user } = storeToRefs(authStore);
@@ -219,7 +218,7 @@ onBeforeUnmount(() => {
219218
window.removeEventListener('beforeunload', beforeWindowUnload);
220219
clearTimeout(downloadTimeout.value);
221220
222-
// Cleanup local autosave
221+
// Cleanup local autosave debounce
223222
localAutosave.cleanup();
224223
});
225224
@@ -233,6 +232,13 @@ function getCurrentAuthHeader() {
233232
return `Bearer ${keycloak.value.token}`;
234233
}
235234
235+
/**
236+
* Central autosave initialization:
237+
* - Only for authenticated, non-preview, non-readonly forms
238+
* - Only when form.enableAutoSave is true
239+
* - Builds a per-user, per-form(+submission) storage key
240+
* - Decides whether to show the recovery dialog
241+
*/
236242
function initializeLocalAutosave() {
237243
// Only enable for authenticated users on non-readonly, non-preview forms
238244
if (
@@ -256,7 +262,7 @@ function initializeLocalAutosave() {
256262
userId: authStore.currentUser.idpUserId,
257263
});
258264
259-
// Check if we should show recovery dialog
265+
// Decide if we should show the recovery dialog
260266
const shouldRecover = localAutosave.shouldShowRecoveryDialog(
261267
submissionRecord.value
262268
);
@@ -296,13 +302,6 @@ function handleLocalDiscard() {
296302
}
297303
298304
async function getFormData() {
299-
// We are loading an existing submission:
300-
// - stop autosave
301-
// - clear any stale local autosave data
302-
// - reset render flags so Form.io can re-init safely
303-
localAutosave.clear();
304-
autosaveReady.value = false;
305-
initialRenderComplete.value = false;
306305
function iterate(obj, stack, fields, propNeeded) {
307306
//Get property path from nested object
308307
for (let property in obj) {
@@ -514,6 +513,13 @@ function isProcessingMultiUpload(e) {
514513
block.value = e;
515514
}
516515
516+
/**
517+
* Form change handler:
518+
* - Validates drafts on change
519+
* - Ignores Form.io's internal "fromSubmission" changes
520+
* - Marks real user input
521+
* - Triggers autosave only when ready and allowed
522+
*/
517523
function formChange(e) {
518524
//If this is a draft, validate on change
519525
if (submissionRecord.value.draft) {
@@ -528,12 +534,11 @@ function formChange(e) {
528534
//user typing
529535
formDataEntered.value = true;
530536
531-
//AUTOSAVE – only when:
532-
//autosave is ready
533-
//form has enableAutoSave turned on
534-
//not read-only or preview
535-
//Form.io has valid _data
536-
537+
// AUTOSAVE – only when:
538+
// autosave flag ready (Form.io render happened)
539+
// form has enableAutoSave turned on
540+
// not read-only or preview
541+
// Form.io has valid _data
537542
if (
538543
autosaveReady.value &&
539544
form.value?.enableAutoSave &&
@@ -628,11 +633,8 @@ async function sendSubmission(isDraft, sub) {
628633
}
629634
630635
function onFormRender() {
631-
// Mark initial render complete + allow autosave AFTER Form.io finish render
632-
if (!initialRenderComplete.value) {
633-
initialRenderComplete.value = true;
634-
autosaveReady.value = true;
635-
}
636+
// Mark autosave as ready AFTER Form.io finishes first render
637+
autosaveReady.value = true;
636638
637639
if (isLoading.value) isLoading.value = false;
638640
}
@@ -653,7 +655,6 @@ function onSubmitButton(event) {
653655
}
654656
// this is our first event in the submission chain.
655657
// most important thing here is ensuring that the formio form does not have an action, or else it POSTs to that action.
656-
// console.info('onSubmitButton()') ; // eslint-disable-line no-console
657658
currentForm.value = event.instance.parent.root;
658659
currentForm.value.form.action = undefined;
659660
@@ -888,8 +889,8 @@ function beforeWindowUnload(e) {
888889
889890
// If autosave is enabled on this form, it can *reduce* warnings
890891
if (form.value?.enableAutoSave) {
891-
// If a debounced save is still pending, assume it will complete soon
892-
// Skip warning if save is pending OR data already exists in localStorage
892+
// If a debounced save is still pending, assume it will complete soon,
893+
// or if there is an autosave snapshot available, do not warn.
893894
if (
894895
(localAutosave._isPending && localAutosave._isPending()) ||
895896
localAutosave.exists()

app/frontend/src/composables/useLocalAutosave.js

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ const CLEANUP_META_KEY = `${STORAGE_PREFIX}__last_cleanup__`;
1717
// -----------------------------------------------------------------------------
1818
function handleStorageError(error) {
1919
// Intentionally no-op; ensures the parameter is "used" for linters/Sonar.
20-
// Converting to string avoids "unused" warnings without logging.
2120
String(error);
2221
}
2322

@@ -51,7 +50,7 @@ function safeParse(raw) {
5150
try {
5251
return JSON.parse(raw);
5352
} catch (error_) {
54-
// Only treat JSON parse failures as "handled"; everything else rethrows
53+
// Treat JSON parse failures as handled; we just ignore that entry
5554
handleStorageError(error_);
5655
return null;
5756
}
@@ -94,7 +93,7 @@ function cleanupKeyIfExpired(key, nowMs) {
9493

9594
const parsed = safeParse(raw);
9695
if (!parsed || typeof parsed !== 'object') {
97-
// Corrupt or unexpected payload → remove
96+
// Corrupt/unexpected payload → remove
9897
localStorage.removeItem(key);
9998
return;
10099
}
@@ -126,7 +125,7 @@ function setLastCleanupTime(nowMs) {
126125
try {
127126
localStorage.setItem(CLEANUP_META_KEY, String(nowMs));
128127
} catch (error_) {
129-
// Best-effort only, ignore failure
128+
// Best-effort only
130129
handleStorageError(error_);
131130
}
132131
}
@@ -173,7 +172,6 @@ function runGlobalCleanupIfDue() {
173172
try {
174173
const keys = collectAutosaveKeys();
175174

176-
// Sonar: prefer for..of over forEach
177175
for (const key of keys) {
178176
try {
179177
cleanupKeyIfExpired(key, now);

0 commit comments

Comments
 (0)