@oneblink/apps-react 13.0.0-beta.1 → 13.0.0-beta.10
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/OneBlinkFormBase.d.ts +23 -3
- package/dist/OneBlinkFormBase.js +350 -193
- package/dist/OneBlinkFormBase.js.map +1 -1
- package/dist/OneBlinkReadOnlyForm.d.ts +17 -7
- package/dist/OneBlinkReadOnlyForm.js +24 -8
- package/dist/OneBlinkReadOnlyForm.js.map +1 -1
- package/dist/apps/approvals-service.d.ts +1 -0
- package/dist/apps/approvals-service.js.map +1 -1
- package/dist/apps/services/api/submissions.d.ts +3 -2
- package/dist/apps/services/api/submissions.js +3 -6
- package/dist/apps/services/api/submissions.js.map +1 -1
- package/dist/apps/submission-service.d.ts +11 -5
- package/dist/apps/submission-service.js +9 -4
- package/dist/apps/submission-service.js.map +1 -1
- package/dist/components/renderer/LookupButton.d.ts +1 -2
- package/dist/components/renderer/LookupButton.js +7 -6
- package/dist/components/renderer/LookupButton.js.map +1 -1
- package/dist/components/renderer/LookupNotification.js +31 -24
- package/dist/components/renderer/LookupNotification.js.map +1 -1
- package/dist/components/renderer/OneBlinkFormElements.d.ts +5 -7
- package/dist/components/renderer/OneBlinkFormElements.js +10 -35
- package/dist/components/renderer/OneBlinkFormElements.js.map +1 -1
- package/dist/components/renderer/PageFormElements.js +8 -3
- package/dist/components/renderer/PageFormElements.js.map +1 -1
- package/dist/components/renderer/ReverseGeocode.js +6 -11
- package/dist/components/renderer/ReverseGeocode.js.map +1 -1
- package/dist/form-elements/FormElementABN.js +1 -1
- package/dist/form-elements/FormElementABN.js.map +1 -1
- package/dist/form-elements/FormElementBSB.js +1 -1
- package/dist/form-elements/FormElementBSB.js.map +1 -1
- package/dist/form-elements/FormElementBarcodeScanner.js +1 -1
- package/dist/form-elements/FormElementBarcodeScanner.js.map +1 -1
- package/dist/form-elements/FormElementCalculation.js +1 -0
- package/dist/form-elements/FormElementCalculation.js.map +1 -1
- package/dist/form-elements/FormElementCheckBoxes.js +1 -1
- package/dist/form-elements/FormElementCheckBoxes.js.map +1 -1
- package/dist/form-elements/FormElementDate.js +1 -1
- package/dist/form-elements/FormElementDate.js.map +1 -1
- package/dist/form-elements/FormElementDateTime.js +1 -1
- package/dist/form-elements/FormElementDateTime.js.map +1 -1
- package/dist/form-elements/FormElementEmail.js +1 -1
- package/dist/form-elements/FormElementEmail.js.map +1 -1
- package/dist/form-elements/FormElementForm.d.ts +8 -9
- package/dist/form-elements/FormElementForm.js +4 -3
- package/dist/form-elements/FormElementForm.js.map +1 -1
- package/dist/form-elements/FormElementLookupButton.js +4 -3
- package/dist/form-elements/FormElementLookupButton.js.map +1 -1
- package/dist/form-elements/FormElementNumber.js +1 -1
- package/dist/form-elements/FormElementNumber.js.map +1 -1
- package/dist/form-elements/FormElementRepeatableSet.d.ts +4 -4
- package/dist/form-elements/FormElementRepeatableSet.js +6 -4
- package/dist/form-elements/FormElementRepeatableSet.js.map +1 -1
- package/dist/form-elements/FormElementSection.d.ts +3 -3
- package/dist/form-elements/FormElementSection.js +2 -2
- package/dist/form-elements/FormElementSection.js.map +1 -1
- package/dist/form-elements/FormElementSelect.js +1 -1
- package/dist/form-elements/FormElementSelect.js.map +1 -1
- package/dist/form-elements/FormElementSummary.js +2 -0
- package/dist/form-elements/FormElementSummary.js.map +1 -1
- package/dist/form-elements/FormElementTelephone.js +1 -1
- package/dist/form-elements/FormElementTelephone.js.map +1 -1
- package/dist/form-elements/FormElementText.js +1 -1
- package/dist/form-elements/FormElementText.js.map +1 -1
- package/dist/form-elements/FormElementTextarea.js +1 -1
- package/dist/form-elements/FormElementTextarea.js.map +1 -1
- package/dist/form-elements/FormElementTime.js +1 -1
- package/dist/form-elements/FormElementTime.js.map +1 -1
- package/dist/hooks/useAreLookupsDisallowed.d.ts +2 -0
- package/dist/hooks/useAreLookupsDisallowed.js +12 -0
- package/dist/hooks/useAreLookupsDisallowed.js.map +1 -0
- package/dist/hooks/useEditableFormElementIds.d.ts +3 -0
- package/dist/hooks/useEditableFormElementIds.js +6 -0
- package/dist/hooks/useEditableFormElementIds.js.map +1 -0
- package/dist/hooks/useFormElementOptions.js +2 -0
- package/dist/hooks/useFormElementOptions.js.map +1 -1
- package/dist/hooks/useFormIsDirty.d.ts +38 -0
- package/dist/hooks/useFormIsDirty.js +78 -0
- package/dist/hooks/useFormIsDirty.js.map +1 -0
- package/dist/hooks/useFormSubmissionAttempt.d.ts +88 -0
- package/dist/hooks/useFormSubmissionAttempt.js +103 -0
- package/dist/hooks/useFormSubmissionAttempt.js.map +1 -0
- package/dist/hooks/useFormSubmissionAutoSaveState.d.ts +2 -9
- package/dist/hooks/useFormSubmissionAutoSaveState.js +4 -2
- package/dist/hooks/useFormSubmissionAutoSaveState.js.map +1 -1
- package/dist/hooks/useFormValidation.d.ts +1 -1
- package/dist/hooks/useFormValidation.js +2 -1
- package/dist/hooks/useFormValidation.js.map +1 -1
- package/dist/hooks/useInjectPages.d.ts +2 -1
- package/dist/hooks/useInjectPages.js.map +1 -1
- package/dist/hooks/useIsFormElementReadOnly.d.ts +2 -0
- package/dist/hooks/useIsFormElementReadOnly.js +13 -0
- package/dist/hooks/useIsFormElementReadOnly.js.map +1 -0
- package/dist/hooks/useLookupNotification.d.ts +23 -2
- package/dist/hooks/useLookupNotification.js +2 -1
- package/dist/hooks/useLookupNotification.js.map +1 -1
- package/dist/hooks/useLookups.d.ts +3 -3
- package/dist/hooks/useLookups.js +7 -4
- package/dist/hooks/useLookups.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/services/form-validation/extensions.d.ts +2 -1
- package/dist/services/form-validation/extensions.js +2 -1
- package/dist/services/form-validation/extensions.js.map +1 -1
- package/dist/services/form-validation/validateSubmission.d.ts +2 -1
- package/dist/services/form-validation/validateSubmission.js +14 -9
- package/dist/services/form-validation/validateSubmission.js.map +1 -1
- package/dist/types/form.d.ts +17 -3
- package/dist/types/form.js.map +1 -1
- package/dist/utils/read-only-form-elements.d.ts +37 -0
- package/dist/utils/read-only-form-elements.js +63 -0
- package/dist/utils/read-only-form-elements.js.map +1 -0
- package/package.json +4 -3
- package/dist/services/isElementReadOnlyForAudience.d.ts +0 -20
- package/dist/services/isElementReadOnlyForAudience.js +0 -46
- package/dist/services/isElementReadOnlyForAudience.js.map +0 -1
- package/dist/services/resolveFormElementReadOnly.d.ts +0 -10
- package/dist/services/resolveFormElementReadOnly.js +0 -17
- package/dist/services/resolveFormElementReadOnly.js.map +0 -1
package/dist/OneBlinkFormBase.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import * as React from 'react';
|
|
3
|
+
import { flushSync } from 'react-dom';
|
|
3
4
|
import { createTheme as createMuiTheme, ThemeProvider } from '@mui/material';
|
|
4
5
|
import Tooltip from './components/renderer/Tooltip';
|
|
5
6
|
import { Prompt, useHistory } from 'react-router-dom';
|
|
@@ -44,7 +45,40 @@ import { getElementDisplayNameForAnalyticsEvent, sendGoogleAnalyticsEvent, } fro
|
|
|
44
45
|
import { useUserProfileForInjectablesOutsideContext } from './hooks/useUserProfileForInjectables';
|
|
45
46
|
import { ValidationIconConfigurationContext } from './hooks/useValidationIconConfiguration';
|
|
46
47
|
import { Clickable } from './components/Clickable';
|
|
47
|
-
|
|
48
|
+
import { EditableFormElementIdsContext } from './hooks/useEditableFormElementIds';
|
|
49
|
+
import { useRegisterFormSubmissionAttempt } from './hooks/useFormSubmissionAttempt';
|
|
50
|
+
import { useRegisterFormIsDirty, FormMarkDirtyContextProvider, } from './hooks/useFormIsDirty';
|
|
51
|
+
var AttachmentUploadStatus;
|
|
52
|
+
(function (AttachmentUploadStatus) {
|
|
53
|
+
AttachmentUploadStatus["ATTACHMENTS_UPLOADED"] = "ATTACHMENTS_UPLOADED";
|
|
54
|
+
AttachmentUploadStatus["ATTACHMENTS_UPLOAD_BLOCKING"] = "ATTACHMENTS_UPLOAD_BLOCKING";
|
|
55
|
+
AttachmentUploadStatus["ATTACHMENTS_UPLOAD_NON_BLOCKING"] = "ATTACHMENTS_UPLOAD_NON_BLOCKING";
|
|
56
|
+
})(AttachmentUploadStatus || (AttachmentUploadStatus = {}));
|
|
57
|
+
var SubmissionPreparationStatus;
|
|
58
|
+
(function (SubmissionPreparationStatus) {
|
|
59
|
+
SubmissionPreparationStatus["OFFLINE_SUBMISSION"] = "OFFLINE_SUBMISSION";
|
|
60
|
+
SubmissionPreparationStatus["SUBMISSION_READY"] = "SUBMISSION_READY";
|
|
61
|
+
})(SubmissionPreparationStatus || (SubmissionPreparationStatus = {}));
|
|
62
|
+
const idlePhase = { status: 'idle' };
|
|
63
|
+
function HostPreparationEffect({ continueWithAttachments, prepareSubmission, onResult, }) {
|
|
64
|
+
// prepareSubmission is in the dep array so that an environment change
|
|
65
|
+
// (e.g. going offline) that recreates prepareSubmission will re-trigger
|
|
66
|
+
// preparation with the updated closure. The cleanup function cancels
|
|
67
|
+
// the prior in-flight call before the new one starts.
|
|
68
|
+
React.useEffect(() => {
|
|
69
|
+
let cancelled = false;
|
|
70
|
+
prepareSubmission(continueWithAttachments).then((result) => {
|
|
71
|
+
if (!cancelled) {
|
|
72
|
+
onResult(result);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
return () => {
|
|
76
|
+
cancelled = true;
|
|
77
|
+
};
|
|
78
|
+
}, [continueWithAttachments, onResult, prepareSubmission]);
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
function OneBlinkFormBase({ googleMapsApiKey, abnLookupAuthenticationGuid, captchaSiteKey, definition, disabled, isPreview, submission, isReadOnly, onCancel, onSubmit, onSaveDraft, setFormSubmission, buttons, validationIcon, primaryColour, attachmentRetentionInDays, isPendingQueueEnabled, handleNavigateAway, isInfoPage: isInfoPageProp, lastElementUpdated, executedLookups, task, taskGroup, taskGroupInstance, onUploadAttachment, captchaType, shouldUseNavigableValidationErrorsNotification = true, navigableValidationErrorsNotificationSettings, replaceInjectablesOverrides, sectionState, scrollToTopOfPage, getCurrentSubmissionDuration, onBeforeUnload, audience, editableFormElementIds, }) {
|
|
48
82
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
|
|
49
83
|
const isOffline = useIsOffline();
|
|
50
84
|
const { isUsingFormsKey } = useAuth();
|
|
@@ -142,6 +176,8 @@ function OneBlinkFormBase({ googleMapsApiKey, abnLookupAuthenticationGuid, captc
|
|
|
142
176
|
});
|
|
143
177
|
const [promptOfflineSubmissionAttempt, setPromptOfflineSubmissionAttempt] = React.useState(false);
|
|
144
178
|
const [promptUploadingAttachments, setPromptUploadingAttachments] = React.useState(false);
|
|
179
|
+
const [hostAttemptPhase, setHostAttemptPhase] = React.useState(idlePhase);
|
|
180
|
+
const [hostAttemptResolver, setHostAttemptResolver] = React.useState(null);
|
|
145
181
|
const handleBlockedNavigation = React.useCallback((location) => {
|
|
146
182
|
setUnsavedChangesState((current) => ({
|
|
147
183
|
...current,
|
|
@@ -225,6 +261,13 @@ function OneBlinkFormBase({ googleMapsApiKey, abnLookupAuthenticationGuid, captc
|
|
|
225
261
|
isNavigationAllowed: true,
|
|
226
262
|
}));
|
|
227
263
|
}, []);
|
|
264
|
+
const allowNavigationAfterHostAction = React.useCallback(() => {
|
|
265
|
+
// React Router DOM v5's <Prompt> has no imperative "proceed" API, so the
|
|
266
|
+
// guard must rerender as disabled before the host navigates in the same
|
|
267
|
+
// tick. Migrating to the React Router DOM v6 blocker APIs would allow the
|
|
268
|
+
// blocked transition to proceed directly without flushSync().
|
|
269
|
+
flushSync(allowNavigation);
|
|
270
|
+
}, [allowNavigation]);
|
|
228
271
|
// #endregion Unsaved Changed
|
|
229
272
|
//
|
|
230
273
|
//
|
|
@@ -246,8 +289,8 @@ function OneBlinkFormBase({ googleMapsApiKey, abnLookupAuthenticationGuid, captc
|
|
|
246
289
|
const [isShowingValidationErrorsCard, setIsShowingValidationErrorsCard] = React.useState(false);
|
|
247
290
|
const { validate } = useFormValidation(pages);
|
|
248
291
|
const recaptchaType = React.useMemo(() => captchaType !== null && captchaType !== void 0 ? captchaType : 'CHECKBOX', [captchaType]);
|
|
249
|
-
const formElementsValidation = React.useMemo(() => !isReadOnly
|
|
250
|
-
? validate(submission, formElementsConditionallyShown, executedLookups !== null && executedLookups !== void 0 ? executedLookups : {}, recaptchaType, isOffline, audience)
|
|
292
|
+
const formElementsValidation = React.useMemo(() => !isReadOnly || editableFormElementIds !== undefined
|
|
293
|
+
? validate(submission, formElementsConditionallyShown, executedLookups !== null && executedLookups !== void 0 ? executedLookups : {}, recaptchaType, isOffline, audience, editableFormElementIds)
|
|
251
294
|
: undefined, [
|
|
252
295
|
isReadOnly,
|
|
253
296
|
validate,
|
|
@@ -257,6 +300,7 @@ function OneBlinkFormBase({ googleMapsApiKey, abnLookupAuthenticationGuid, captc
|
|
|
257
300
|
recaptchaType,
|
|
258
301
|
isOffline,
|
|
259
302
|
audience,
|
|
303
|
+
editableFormElementIds,
|
|
260
304
|
]);
|
|
261
305
|
React.useEffect(() => {
|
|
262
306
|
if (!formElementsValidation) {
|
|
@@ -312,7 +356,7 @@ function OneBlinkFormBase({ googleMapsApiKey, abnLookupAuthenticationGuid, captc
|
|
|
312
356
|
// be taken care of by a pending queue if enabled, otherwise
|
|
313
357
|
// the user will be prompted to try again or save a draft.
|
|
314
358
|
if (isOffline) {
|
|
315
|
-
return
|
|
359
|
+
return AttachmentUploadStatus.ATTACHMENTS_UPLOADED;
|
|
316
360
|
}
|
|
317
361
|
const attachmentsAreUploading = attachmentsService.checkIfAttachmentsAreUploading(definition, submission);
|
|
318
362
|
if (attachmentsAreUploading) {
|
|
@@ -325,14 +369,13 @@ function OneBlinkFormBase({ googleMapsApiKey, abnLookupAuthenticationGuid, captc
|
|
|
325
369
|
pauseOnHover: true,
|
|
326
370
|
closeOnClick: true,
|
|
327
371
|
});
|
|
328
|
-
return
|
|
372
|
+
return AttachmentUploadStatus.ATTACHMENTS_UPLOAD_BLOCKING;
|
|
329
373
|
}
|
|
330
374
|
else {
|
|
331
|
-
|
|
332
|
-
return false;
|
|
375
|
+
return AttachmentUploadStatus.ATTACHMENTS_UPLOAD_NON_BLOCKING;
|
|
333
376
|
}
|
|
334
377
|
}
|
|
335
|
-
return
|
|
378
|
+
return AttachmentUploadStatus.ATTACHMENTS_UPLOADED;
|
|
336
379
|
}, [definition, isOffline, isPendingQueueEnabled, isUsingFormsKey]);
|
|
337
380
|
const checkBsbsCanBeSubmitted = React.useCallback((submission) => {
|
|
338
381
|
return !checkBsbsAreInvalid(definition, submission);
|
|
@@ -405,15 +448,29 @@ function OneBlinkFormBase({ googleMapsApiKey, abnLookupAuthenticationGuid, captc
|
|
|
405
448
|
if (!checkBsbsCanBeSubmitted(submissionData.submission)) {
|
|
406
449
|
return;
|
|
407
450
|
}
|
|
408
|
-
if (!continueWhilstAttachmentsAreUploading
|
|
409
|
-
|
|
410
|
-
|
|
451
|
+
if (!continueWhilstAttachmentsAreUploading) {
|
|
452
|
+
const attachmentStatus = checkAttachmentsCanBeSubmitted(submissionData.submission);
|
|
453
|
+
switch (attachmentStatus) {
|
|
454
|
+
case AttachmentUploadStatus.ATTACHMENTS_UPLOAD_BLOCKING:
|
|
455
|
+
// The submitter cannot upload attachments in the background and must wait for them to upload before submitting
|
|
456
|
+
return;
|
|
457
|
+
case AttachmentUploadStatus.ATTACHMENTS_UPLOAD_NON_BLOCKING:
|
|
458
|
+
// We can display a prompt allowing the submitter to upload attachments in the background
|
|
459
|
+
return {
|
|
460
|
+
status: attachmentStatus,
|
|
461
|
+
};
|
|
462
|
+
case AttachmentUploadStatus.ATTACHMENTS_UPLOADED:
|
|
463
|
+
break;
|
|
464
|
+
default:
|
|
465
|
+
return;
|
|
466
|
+
}
|
|
411
467
|
}
|
|
412
468
|
if (captchaType === 'INVISIBLE') {
|
|
413
469
|
if (captchasRef.current.length) {
|
|
414
470
|
if (isOffline) {
|
|
415
|
-
|
|
416
|
-
|
|
471
|
+
return {
|
|
472
|
+
status: SubmissionPreparationStatus.OFFLINE_SUBMISSION,
|
|
473
|
+
};
|
|
417
474
|
}
|
|
418
475
|
const tokenResults = await Promise.allSettled(captchasRef.current.map((captcha) => captcha.executeAsync()));
|
|
419
476
|
const captchaTokens = [];
|
|
@@ -454,10 +511,14 @@ function OneBlinkFormBase({ googleMapsApiKey, abnLookupAuthenticationGuid, captc
|
|
|
454
511
|
}
|
|
455
512
|
if (isOffline && !isPendingQueueEnabled) {
|
|
456
513
|
console.log('User is offline and form does not support a pending queue');
|
|
457
|
-
|
|
458
|
-
|
|
514
|
+
return {
|
|
515
|
+
status: SubmissionPreparationStatus.OFFLINE_SUBMISSION,
|
|
516
|
+
};
|
|
459
517
|
}
|
|
460
|
-
return
|
|
518
|
+
return {
|
|
519
|
+
status: SubmissionPreparationStatus.SUBMISSION_READY,
|
|
520
|
+
submissionData: submissionData,
|
|
521
|
+
};
|
|
461
522
|
}, [
|
|
462
523
|
attachmentRetentionInDays,
|
|
463
524
|
captchaType,
|
|
@@ -472,6 +533,54 @@ function OneBlinkFormBase({ googleMapsApiKey, abnLookupAuthenticationGuid, captc
|
|
|
472
533
|
setFormSubmission,
|
|
473
534
|
shouldUseNavigableValidationErrorsNotification,
|
|
474
535
|
]);
|
|
536
|
+
const handleHostPreparationResult = React.useCallback((result) => {
|
|
537
|
+
if (!result) {
|
|
538
|
+
setHostAttemptPhase({ status: 'resolved', result: false });
|
|
539
|
+
return;
|
|
540
|
+
}
|
|
541
|
+
switch (result.status) {
|
|
542
|
+
case AttachmentUploadStatus.ATTACHMENTS_UPLOAD_NON_BLOCKING: {
|
|
543
|
+
setPromptUploadingAttachments(true);
|
|
544
|
+
setHostAttemptPhase({ status: 'prompt-attachments' });
|
|
545
|
+
break;
|
|
546
|
+
}
|
|
547
|
+
case SubmissionPreparationStatus.OFFLINE_SUBMISSION: {
|
|
548
|
+
setPromptOfflineSubmissionAttempt(true);
|
|
549
|
+
setHostAttemptPhase((current) => ({
|
|
550
|
+
status: 'prompt-offline',
|
|
551
|
+
continueWithAttachments: current.status === 'preparing'
|
|
552
|
+
? current.continueWithAttachments
|
|
553
|
+
: false,
|
|
554
|
+
}));
|
|
555
|
+
break;
|
|
556
|
+
}
|
|
557
|
+
case SubmissionPreparationStatus.SUBMISSION_READY: {
|
|
558
|
+
setHostAttemptPhase({
|
|
559
|
+
status: 'resolved',
|
|
560
|
+
result: allowNavigationAfterHostAction,
|
|
561
|
+
});
|
|
562
|
+
break;
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
}, [allowNavigationAfterHostAction]);
|
|
566
|
+
const attemptFormSubmission = React.useCallback(() => {
|
|
567
|
+
setHasAttemptedSubmit(true);
|
|
568
|
+
setIsPreparingToSubmit(true);
|
|
569
|
+
setHostAttemptPhase({ status: 'preparing', continueWithAttachments: false });
|
|
570
|
+
return new Promise((resolve) => {
|
|
571
|
+
setHostAttemptResolver({ resolve });
|
|
572
|
+
});
|
|
573
|
+
}, []);
|
|
574
|
+
React.useEffect(() => {
|
|
575
|
+
if (hostAttemptPhase.status === 'resolved') {
|
|
576
|
+
setIsPreparingToSubmit(false);
|
|
577
|
+
hostAttemptResolver === null || hostAttemptResolver === void 0 ? void 0 : hostAttemptResolver.resolve(hostAttemptPhase.result);
|
|
578
|
+
setHostAttemptResolver(null);
|
|
579
|
+
setHostAttemptPhase(idlePhase);
|
|
580
|
+
}
|
|
581
|
+
}, [hostAttemptPhase, hostAttemptResolver]);
|
|
582
|
+
useRegisterFormSubmissionAttempt(editableFormElementIds === undefined ? undefined : attemptFormSubmission);
|
|
583
|
+
useRegisterFormIsDirty(definition.id, isDirty);
|
|
475
584
|
const handleSubmit = React.useCallback(async (event, continueWhilstAttachmentsAreUploading) => {
|
|
476
585
|
event.preventDefault();
|
|
477
586
|
// Approvers are not shown a submit button, so reaching here means the
|
|
@@ -482,39 +591,60 @@ function OneBlinkFormBase({ googleMapsApiKey, abnLookupAuthenticationGuid, captc
|
|
|
482
591
|
return;
|
|
483
592
|
setHasAttemptedSubmit(true);
|
|
484
593
|
setIsPreparingToSubmit(true);
|
|
485
|
-
const
|
|
486
|
-
if (!
|
|
594
|
+
const submissionResult = await prepareSubmission(continueWhilstAttachmentsAreUploading);
|
|
595
|
+
if (!submissionResult) {
|
|
487
596
|
setIsPreparingToSubmit(false);
|
|
488
597
|
return;
|
|
489
598
|
}
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
599
|
+
switch (submissionResult.status) {
|
|
600
|
+
case AttachmentUploadStatus.ATTACHMENTS_UPLOAD_NON_BLOCKING: {
|
|
601
|
+
setPromptUploadingAttachments(true);
|
|
602
|
+
setIsPreparingToSubmit(false);
|
|
603
|
+
return;
|
|
604
|
+
}
|
|
605
|
+
case SubmissionPreparationStatus.OFFLINE_SUBMISSION: {
|
|
606
|
+
setPromptOfflineSubmissionAttempt(true);
|
|
607
|
+
setIsPreparingToSubmit(false);
|
|
608
|
+
return;
|
|
609
|
+
}
|
|
610
|
+
case SubmissionPreparationStatus.SUBMISSION_READY: {
|
|
611
|
+
allowNavigation();
|
|
612
|
+
const submissionData = submissionResult.submissionData;
|
|
613
|
+
// transplant injected options on the definition
|
|
614
|
+
const elementsWithInjectedOptions = injectOptionsAcrossAllElements({
|
|
615
|
+
contextElements: definition.elements,
|
|
616
|
+
elements: definition.elements,
|
|
617
|
+
submission: submissionData.submission,
|
|
618
|
+
taskContext: taskContextValue,
|
|
619
|
+
userProfile: userProfileForInjectables,
|
|
620
|
+
});
|
|
621
|
+
setIsPreparingToSubmit(false);
|
|
622
|
+
resetRecaptchas();
|
|
623
|
+
onSubmit({
|
|
624
|
+
definition: {
|
|
625
|
+
...definition,
|
|
626
|
+
elements: elementsWithInjectedOptions,
|
|
627
|
+
},
|
|
628
|
+
submission: submissionData.submission,
|
|
629
|
+
recaptchas: submissionData.captchaTokens.map((token) => ({
|
|
630
|
+
token,
|
|
631
|
+
siteKey: captchaSiteKey,
|
|
632
|
+
})),
|
|
633
|
+
});
|
|
634
|
+
sendGoogleAnalyticsEvent('oneblink_form_submit', {
|
|
635
|
+
formId: definition.id,
|
|
636
|
+
formName: definition.name,
|
|
637
|
+
lastElementUpdated: getElementDisplayNameForAnalyticsEvent(lastElementUpdated),
|
|
638
|
+
durationUntilSubmission: getCurrentSubmissionDuration === null || getCurrentSubmissionDuration === void 0 ? void 0 : getCurrentSubmissionDuration(),
|
|
639
|
+
});
|
|
640
|
+
return;
|
|
641
|
+
}
|
|
642
|
+
default: {
|
|
643
|
+
const never = submissionResult;
|
|
644
|
+
setIsPreparingToSubmit(false);
|
|
645
|
+
return never;
|
|
646
|
+
}
|
|
647
|
+
}
|
|
518
648
|
}, [
|
|
519
649
|
disabled,
|
|
520
650
|
isReadOnly,
|
|
@@ -541,9 +671,18 @@ function OneBlinkFormBase({ googleMapsApiKey, abnLookupAuthenticationGuid, captc
|
|
|
541
671
|
if (!checkBsbAreValidating(submission)) {
|
|
542
672
|
return;
|
|
543
673
|
}
|
|
544
|
-
if (!continueWhilstAttachmentsAreUploading
|
|
545
|
-
|
|
546
|
-
|
|
674
|
+
if (!continueWhilstAttachmentsAreUploading) {
|
|
675
|
+
const attachmentCheckResult = checkAttachmentsCanBeSubmitted(submission);
|
|
676
|
+
if (attachmentCheckResult ===
|
|
677
|
+
AttachmentUploadStatus.ATTACHMENTS_UPLOAD_NON_BLOCKING) {
|
|
678
|
+
setPromptUploadingAttachments(true);
|
|
679
|
+
return;
|
|
680
|
+
}
|
|
681
|
+
if (attachmentCheckResult ===
|
|
682
|
+
AttachmentUploadStatus.ATTACHMENTS_UPLOAD_BLOCKING) {
|
|
683
|
+
// The submitter cannot upload attachments in the background and must wait for them to upload before saving draft
|
|
684
|
+
return;
|
|
685
|
+
}
|
|
547
686
|
}
|
|
548
687
|
onSaveDraft({
|
|
549
688
|
definition,
|
|
@@ -568,6 +707,13 @@ function OneBlinkFormBase({ googleMapsApiKey, abnLookupAuthenticationGuid, captc
|
|
|
568
707
|
]);
|
|
569
708
|
const handleContinueWithAttachments = React.useCallback((e) => {
|
|
570
709
|
setPromptUploadingAttachments(false);
|
|
710
|
+
if (hostAttemptPhase.status === 'prompt-attachments') {
|
|
711
|
+
setHostAttemptPhase({
|
|
712
|
+
status: 'preparing',
|
|
713
|
+
continueWithAttachments: true,
|
|
714
|
+
});
|
|
715
|
+
return;
|
|
716
|
+
}
|
|
571
717
|
if (hasAttemptedSubmit) {
|
|
572
718
|
handleSubmit(e, true);
|
|
573
719
|
}
|
|
@@ -576,121 +722,129 @@ function OneBlinkFormBase({ googleMapsApiKey, abnLookupAuthenticationGuid, captc
|
|
|
576
722
|
}
|
|
577
723
|
}, [
|
|
578
724
|
handleSubmit,
|
|
579
|
-
|
|
725
|
+
hostAttemptPhase.status,
|
|
580
726
|
hasAttemptedSubmit,
|
|
581
727
|
handleSaveDraft,
|
|
582
728
|
]);
|
|
583
729
|
const handleWaitForAttachments = React.useCallback(() => {
|
|
584
730
|
setPromptUploadingAttachments(false);
|
|
585
|
-
|
|
731
|
+
if (hostAttemptPhase.status === 'prompt-attachments') {
|
|
732
|
+
setHostAttemptPhase({ status: 'resolved', result: false });
|
|
733
|
+
}
|
|
734
|
+
}, [hostAttemptPhase.status]);
|
|
735
|
+
const handleCancelOfflineSubmission = React.useCallback(() => {
|
|
736
|
+
setPromptOfflineSubmissionAttempt(false);
|
|
737
|
+
if (hostAttemptPhase.status === 'prompt-offline') {
|
|
738
|
+
setHostAttemptPhase({ status: 'resolved', result: false });
|
|
739
|
+
}
|
|
740
|
+
}, [hostAttemptPhase.status]);
|
|
741
|
+
const handleRetryOfflineSubmission = React.useCallback((e) => {
|
|
742
|
+
setPromptOfflineSubmissionAttempt(false);
|
|
743
|
+
if (hostAttemptPhase.status === 'prompt-offline') {
|
|
744
|
+
setHostAttemptPhase({
|
|
745
|
+
status: 'preparing',
|
|
746
|
+
continueWithAttachments: hostAttemptPhase.continueWithAttachments,
|
|
747
|
+
});
|
|
748
|
+
}
|
|
749
|
+
else {
|
|
750
|
+
handleSubmit(e, false);
|
|
751
|
+
}
|
|
752
|
+
}, [
|
|
753
|
+
handleSubmit,
|
|
754
|
+
hostAttemptPhase,
|
|
755
|
+
]);
|
|
586
756
|
// #endregion
|
|
587
757
|
//
|
|
588
758
|
//
|
|
589
759
|
//
|
|
590
760
|
//
|
|
591
|
-
// #region
|
|
592
|
-
const
|
|
593
|
-
|
|
761
|
+
// #region Submission/Definition Changes
|
|
762
|
+
const markFormDirty = React.useCallback(() => {
|
|
763
|
+
setUnsavedChangesState((current) => ({
|
|
764
|
+
...current,
|
|
765
|
+
isDirty: true,
|
|
766
|
+
}));
|
|
767
|
+
}, []);
|
|
594
768
|
//
|
|
595
769
|
//
|
|
770
|
+
// #region Lookups
|
|
771
|
+
const { handlePagesLookupResult } = useLookups(definition.id, setFormSubmission, markFormDirty);
|
|
772
|
+
// #endregion
|
|
596
773
|
//
|
|
597
774
|
//
|
|
598
|
-
|
|
599
|
-
const handleChange = React.useCallback((element, { value, executedLookups, deleteSection, sectionState }) => {
|
|
775
|
+
const handleChange = React.useCallback((element, { value, executedLookups, deleteSection, sectionState, isDerivedChange }) => {
|
|
600
776
|
if (
|
|
601
|
-
//
|
|
602
|
-
//
|
|
603
|
-
|
|
604
|
-
(disabled &&
|
|
605
|
-
element.type !== 'summary' &&
|
|
606
|
-
element.type !== 'calculation') ||
|
|
777
|
+
// Disabled forms still need derived writers (calculation, summary, …)
|
|
778
|
+
// so those elements can recompute and display from the current model.
|
|
779
|
+
(disabled && !isDerivedChange) ||
|
|
607
780
|
element.type === 'page') {
|
|
608
781
|
return;
|
|
609
782
|
}
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
{
|
|
636
|
-
id: element.id,
|
|
637
|
-
state: element.isCollapsed ? 'EXPANDED' : 'COLLAPSED',
|
|
638
|
-
},
|
|
639
|
-
];
|
|
640
|
-
}
|
|
641
|
-
return {
|
|
642
|
-
...currentFormSubmission,
|
|
643
|
-
sectionState: newSectionState,
|
|
644
|
-
};
|
|
645
|
-
});
|
|
646
|
-
break;
|
|
647
|
-
}
|
|
648
|
-
// Don't update the last element updated for elements the user cannot set the value of
|
|
649
|
-
case 'summary':
|
|
650
|
-
case 'calculation': {
|
|
651
|
-
setFormSubmission((currentFormSubmission) => ({
|
|
652
|
-
...currentFormSubmission,
|
|
653
|
-
submission: {
|
|
654
|
-
...currentFormSubmission.submission,
|
|
655
|
-
[element.name]: typeof value === 'function'
|
|
656
|
-
? value(currentFormSubmission.submission[element.name])
|
|
657
|
-
: value,
|
|
658
|
-
},
|
|
659
|
-
}));
|
|
660
|
-
break;
|
|
661
|
-
}
|
|
662
|
-
default: {
|
|
663
|
-
setUnsavedChangesState((current) => ({
|
|
664
|
-
...current,
|
|
665
|
-
isDirty: true,
|
|
666
|
-
}));
|
|
667
|
-
setFormSubmission((currentFormSubmission) => {
|
|
668
|
-
var _a;
|
|
669
|
-
return {
|
|
670
|
-
...currentFormSubmission,
|
|
671
|
-
submission: {
|
|
672
|
-
...currentFormSubmission.submission,
|
|
673
|
-
[element.name]: typeof value === 'function'
|
|
674
|
-
? value(currentFormSubmission.submission[element.name])
|
|
675
|
-
: value,
|
|
676
|
-
},
|
|
677
|
-
lastElementUpdated: element,
|
|
678
|
-
executedLookups: {
|
|
679
|
-
...currentFormSubmission.executedLookups,
|
|
680
|
-
[element.name]: typeof executedLookups === 'function'
|
|
681
|
-
? executedLookups((_a = currentFormSubmission.executedLookups) === null || _a === void 0 ? void 0 : _a[element.name])
|
|
682
|
-
: executedLookups,
|
|
783
|
+
if (element.type === 'section') {
|
|
784
|
+
setFormSubmission((currentFormSubmission) => {
|
|
785
|
+
const currentSectionState = currentFormSubmission.sectionState || [];
|
|
786
|
+
const existingSectionIndex = currentSectionState.findIndex((section) => section.id === element.id);
|
|
787
|
+
const sectionIsInState = existingSectionIndex >= 0;
|
|
788
|
+
let newSectionState;
|
|
789
|
+
if (sectionIsInState && deleteSection) {
|
|
790
|
+
newSectionState = currentSectionState.filter((section) => section.id !== element.id);
|
|
791
|
+
}
|
|
792
|
+
else if (sectionIsInState) {
|
|
793
|
+
// Update state of the section
|
|
794
|
+
newSectionState = currentSectionState.map((section, index) => index === existingSectionIndex
|
|
795
|
+
? {
|
|
796
|
+
...section,
|
|
797
|
+
state: section.state === 'COLLAPSED' ? 'EXPANDED' : 'COLLAPSED',
|
|
798
|
+
}
|
|
799
|
+
: section);
|
|
800
|
+
}
|
|
801
|
+
else {
|
|
802
|
+
// Add the section to state
|
|
803
|
+
newSectionState = [
|
|
804
|
+
...currentSectionState,
|
|
805
|
+
{
|
|
806
|
+
id: element.id,
|
|
807
|
+
state: element.isCollapsed ? 'EXPANDED' : 'COLLAPSED',
|
|
683
808
|
},
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
809
|
+
];
|
|
810
|
+
}
|
|
811
|
+
return {
|
|
812
|
+
...currentFormSubmission,
|
|
813
|
+
sectionState: newSectionState,
|
|
814
|
+
};
|
|
815
|
+
});
|
|
816
|
+
return;
|
|
817
|
+
}
|
|
818
|
+
if (!isDerivedChange) {
|
|
819
|
+
markFormDirty();
|
|
692
820
|
}
|
|
693
|
-
|
|
821
|
+
setFormSubmission((currentFormSubmission) => {
|
|
822
|
+
var _a;
|
|
823
|
+
return {
|
|
824
|
+
...currentFormSubmission,
|
|
825
|
+
submission: {
|
|
826
|
+
...currentFormSubmission.submission,
|
|
827
|
+
[element.name]: typeof value === 'function'
|
|
828
|
+
? value(currentFormSubmission.submission[element.name])
|
|
829
|
+
: value,
|
|
830
|
+
},
|
|
831
|
+
lastElementUpdated: isDerivedChange
|
|
832
|
+
? currentFormSubmission.lastElementUpdated
|
|
833
|
+
: element,
|
|
834
|
+
executedLookups: {
|
|
835
|
+
...currentFormSubmission.executedLookups,
|
|
836
|
+
[element.name]: typeof executedLookups === 'function'
|
|
837
|
+
? executedLookups((_a = currentFormSubmission.executedLookups) === null || _a === void 0 ? void 0 : _a[element.name])
|
|
838
|
+
: executedLookups,
|
|
839
|
+
},
|
|
840
|
+
sectionState: sectionState
|
|
841
|
+
? typeof sectionState === 'function'
|
|
842
|
+
? sectionState(currentFormSubmission.sectionState)
|
|
843
|
+
: sectionState
|
|
844
|
+
: currentFormSubmission.sectionState,
|
|
845
|
+
};
|
|
846
|
+
}, { isDerivedChange });
|
|
847
|
+
}, [disabled, markFormDirty, setFormSubmission]);
|
|
694
848
|
// #endregion
|
|
695
849
|
//
|
|
696
850
|
//
|
|
@@ -740,55 +894,58 @@ function OneBlinkFormBase({ googleMapsApiKey, abnLookupAuthenticationGuid, captc
|
|
|
740
894
|
if (conditionalLogicError) {
|
|
741
895
|
return (_jsx(_Fragment, { children: _jsxs("div", { className: "has-text-centered", children: [_jsx(MaterialIcon, { className: "has-text-warning icon-x-large", children: "error" }), _jsx("h3", { className: "title is-3", children: "Bad Form Configuration" }), _jsx("p", { className: "cypress-conditional-logic-error-message", children: conditionalLogicError.message }), _jsx("p", { className: "has-text-grey", children: localisationService.formatDatetimeLong(new Date()) })] }) }));
|
|
742
896
|
}
|
|
743
|
-
return (_jsx(ThemeProvider, { theme: theme, children: _jsx(LocalizationProvider, { dateAdapter: AdapterDateFns, children: _jsx(ReplaceInjectablesOverridesContext.Provider, { value: replaceInjectablesOverrides, children: _jsx(FormDefinitionContext.Provider, { value: definition, children: _jsx(FormElementOptionsContextProvider, { formIsReadOnly: isReadOnly, children: _jsx(FormElementLookupsContextProvider, { children: _jsx(OneBlinkFormContainerContext.Provider, { value: obFormContainerHTMLElementRef, children: _jsxs("div", { className: clsx('ob-form-container', {
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
897
|
+
return (_jsx(FormMarkDirtyContextProvider, { markDirty: markFormDirty, children: _jsx(ThemeProvider, { theme: theme, children: _jsx(LocalizationProvider, { dateAdapter: AdapterDateFns, children: _jsx(ReplaceInjectablesOverridesContext.Provider, { value: replaceInjectablesOverrides, children: _jsx(FormDefinitionContext.Provider, { value: definition, children: _jsx(FormElementOptionsContextProvider, { formIsReadOnly: isReadOnly, children: _jsx(FormElementLookupsContextProvider, { children: _jsx(OneBlinkFormContainerContext.Provider, { value: obFormContainerHTMLElementRef, children: _jsxs("div", { className: clsx('ob-form-container', {
|
|
898
|
+
'is-showing-pages': isShowingMultiplePages,
|
|
899
|
+
}), ref: obFormContainerHTMLElementRef, children: [_jsx("form", { name: "obForm", className: `ob-form cypress-ob-form ob-form__page-${currentPageIndex + 1}`, noValidate: true, onSubmit: (e) => handleSubmit(e, false), children: _jsxs("div", { children: [_jsx("div", { ref: scrollToTopOfPageHTMLElementRef }), isShowingMultiplePages && (_jsxs("div", { className: clsx('ob-steps-navigation', {
|
|
900
|
+
'is-active': isStepsHeaderActive,
|
|
901
|
+
}), children: [_jsxs(Clickable, { className: clsx('ob-steps-navigation__header', {
|
|
902
|
+
'is-active': isStepsHeaderActive,
|
|
903
|
+
}), onClick: toggleStepsNavigation, children: [_jsx("span", { className: "icon is-invisible", children: _jsx(MaterialIcon, { children: "keyboard_arrow_down" }) }), _jsxs("div", { className: "steps-header-active-page", children: [isDisplayingCurrentPageError ? (_jsx("span", { className: "icon", children: _jsx(MaterialIcon, { className: "has-text-danger is-size-4", children: "warning" }) })) : (_jsx("span", { className: "steps-header-active-page-icon", children: currentPageNumber })), _jsx("span", { className: "steps-header-active-page-label cypress-tablet-step-title", children: currentPage ? currentPage.label : '' })] }), _jsx("span", { className: "dropdown icon", children: _jsx(MaterialIcon, { children: "keyboard_arrow_down" }) })] }), _jsx("div", { role: "navigation", className: clsx('ob-steps-navigation__steps', {
|
|
904
|
+
'is-active': isStepsHeaderActive,
|
|
905
|
+
}), children: _jsx("div", { className: "steps is-small is-horizontal-tablet cypress-steps", children: visiblePages.map((page, index) => {
|
|
906
|
+
const hasErrors = checkDisplayPageError(page);
|
|
907
|
+
return (_jsxs(Clickable, { id: `steps-navigation-step-${page.id}`, "aria-label": `${page.label}, page ${index + 1} of ${visiblePages.length}`, "aria-current": currentPage.id === page.id
|
|
908
|
+
? 'step'
|
|
909
|
+
: undefined, className: clsx('step-item cypress-step-item', {
|
|
910
|
+
'is-active': currentPage.id === page.id,
|
|
911
|
+
'is-completed': currentPageIndex > index,
|
|
912
|
+
'is-error': hasErrors,
|
|
913
|
+
}), onClick: (e) => {
|
|
914
|
+
e.stopPropagation();
|
|
915
|
+
if (page.id !== currentPage.id) {
|
|
916
|
+
setPageId(page.id);
|
|
917
|
+
}
|
|
918
|
+
}, children: [_jsx("div", { className: "step-marker step-marker-error ob-step-marker cypress-step-marker",
|
|
919
|
+
// @ts-expect-error ???
|
|
920
|
+
name: `cypress-page-stepper-${index + 1}`, value: index + 1, children: hasErrors ? (_jsx(Tooltip, { title: "Page has errors", children: _jsx("span", { className: "icon tooltip has-tooltip-top cypress-page-error", children: _jsx(MaterialIcon, { className: "has-text-danger is-size-3", children: "warning" }) }) })) : (_jsx("span", { children: index + 1 })) }), _jsx("div", { className: "step-details ob-step-details", children: _jsx("p", { className: "step-title ob-step-title cypress-desktop-step-title", id: `steps-navigation-step-label-${page.id}`, children: page.label }) })] }, page.id));
|
|
921
|
+
}) }) })] })), _jsx("div", { className: clsx('ob-steps-navigation__background', {
|
|
922
|
+
'is-active': isStepsHeaderActive,
|
|
923
|
+
}), onClick: toggleStepsNavigation }), _jsxs("div", { className: "steps", children: [_jsx("div", { className: clsx('steps-content', {
|
|
924
|
+
'is-single-step': !isShowingMultiplePages,
|
|
925
|
+
}), children: _jsx(InjectPagesContext.Provider, { value: handlePagesLookupResult, children: _jsx(GoogleMapsApiKeyContext.Provider, { value: googleMapsApiKey, children: _jsx(AbnLookupAuthenticationGuidContext.Provider, { value: abnLookupAuthenticationGuid, children: _jsx(ValidationIconConfigurationContext.Provider, { value: validationIcon, children: _jsx(CaptchaContext.Provider, { value: captchaContextValue, children: _jsx(AttachmentBlobsProvider, { children: _jsx(FormIsReadOnlyContext.Provider, { value: isReadOnly, children: _jsx(EditableFormElementIdsContext.Provider, { value: editableFormElementIds, children: _jsx(FormAudienceContext.Provider, { value: audience, children: _jsx(TaskContext.Provider, { value: taskContextValue, children: _jsx(OnUploadAttachmentContext.Provider, { value: onUploadAttachment, children: visiblePages.map((pageElement) => (_jsx(PageFormElements, { isActive: pageElement.id ===
|
|
926
|
+
currentPage.id, formId: definition.id, formElementsConditionallyShown: formElementsConditionallyShown, formElementsValidation: formElementsValidation, displayValidationMessages: hasAttemptedSubmit ||
|
|
927
|
+
isDisplayingCurrentPageError, pageElement: pageElement, onChange: handleChange, model: submission, setFormSubmission: setFormSubmission, sectionState: sectionState }, pageElement.id))) }) }) }) }) }) }) }) }) }) }) }) }), isShowingMultiplePages && (_jsxs("div", { className: "steps-actions", children: [_jsx("div", { className: "steps-action", children: _jsxs("button", { type: "button", onClick: goToPreviousPage, disabled: isFirstVisiblePage, className: "button is-light cypress-pages-previous", children: [_jsx("span", { className: "icon", children: _jsx(MaterialIcon, { children: "keyboard_arrow_left" }) }), _jsx("span", { children: "Back" })] }) }), _jsx("div", { className: "step-progress-mobile cypress-steps-mobile", children: visiblePages.map((page, index) => (_jsx("div", { className: clsx('step-progress-mobile-dot', {
|
|
928
|
+
'is-active': currentPage.id === page.id,
|
|
929
|
+
'is-completed': currentPageIndex > index,
|
|
930
|
+
'has-background-danger': currentPage.id !== page.id &&
|
|
931
|
+
checkDisplayPageError(page),
|
|
932
|
+
}) }, page.id))) }), _jsx("div", { className: "steps-action", children: _jsxs("button", { type: "button", onClick: goToNextPage, disabled: isLastVisiblePage, className: "button is-light cypress-pages-next", children: [_jsx("span", { children: "Next" }), _jsx("span", { className: "icon", children: _jsx(MaterialIcon, { children: "keyboard_arrow_right" }) })] }) })] }))] }), !isReadOnly && audience !== 'APPROVER' && (_jsxs("div", { className: "buttons ob-buttons ob-buttons-submit", children: [onSaveDraft && !isInfoPage && (_jsx("button", { type: "button", className: "button ob-button is-primary ob-button-save-draft cypress-save-draft-form", onClick: () => handleSaveDraft(false), disabled: isPreview || disabled, children: _jsx(CustomisableButtonInner, { label: ((_a = buttons === null || buttons === void 0 ? void 0 : buttons.saveDraft) === null || _a === void 0 ? void 0 : _a.label) || 'Save Draft', icon: (_b = buttons === null || buttons === void 0 ? void 0 : buttons.saveDraft) === null || _b === void 0 ? void 0 : _b.icon }) })), _jsx("span", { className: "ob-buttons-submit__spacer" }), !isInfoPage && (_jsx("button", { type: "button", className: "button ob-button is-light ob-button-submit-cancel cypress-cancel-form", onClick: handleCancel, disabled: isPreview || disabled, children: _jsx(CustomisableButtonInner, { label: ((_c = buttons === null || buttons === void 0 ? void 0 : buttons.cancel) === null || _c === void 0 ? void 0 : _c.label) || 'Cancel', icon: (_d = buttons === null || buttons === void 0 ? void 0 : buttons.cancel) === null || _d === void 0 ? void 0 : _d.icon }) })), isLastVisiblePage && (_jsx(Tooltip, { title: submissionConditionallyEnabled
|
|
933
|
+
? ''
|
|
934
|
+
: 'Submission disabled: Your inputs have not met the criteria for submission', children: _jsx("span", { children: _jsx("button", { type: "submit", className: clsx('button ob-button is-success ob-button-submit cypress-submit-form-button cypress-submit-form', { 'is-loading': isPreparingToSubmit }, {
|
|
935
|
+
'ob-button-submit-is-disabled': submissionConditionallyEnabled,
|
|
936
|
+
}), disabled: isPreview ||
|
|
937
|
+
disabled ||
|
|
938
|
+
isPreparingToSubmit ||
|
|
939
|
+
!submissionConditionallyEnabled, children: _jsx(CustomisableButtonInner, { label: isInfoPage
|
|
940
|
+
? 'Done'
|
|
941
|
+
: ((_e = buttons === null || buttons === void 0 ? void 0 : buttons.submit) === null || _e === void 0 ? void 0 : _e.label) || 'Submit', icon: (_f = buttons === null || buttons === void 0 ? void 0 : buttons.submit) === null || _f === void 0 ? void 0 : _f.icon }) }) }) }))] }))] }) }), !isPreview &&
|
|
942
|
+
(editableFormElementIds !== undefined ||
|
|
943
|
+
!isReadOnly) && (_jsxs(React.Fragment, { children: [_jsx(Prompt, { when: isDirty && !isNavigationAllowed, message: handleBlockedNavigation }), _jsx(Modal, { isOpen: hasConfirmedNavigation === false, title: "Unsaved Changes", cardClassName: "cypress-cancel-confirm", titleClassName: "cypress-cancel-confirm-title", bodyClassName: "cypress-cancel-confirm-body", actions: _jsxs(_Fragment, { children: [onSaveDraft && (_jsx("button", { type: "button", className: "button ob-button is-success cypress-cancel-confirm-save-draft", onClick: () => handleSaveDraft(false), children: _jsx(CustomisableButtonInner, { label: ((_g = buttons === null || buttons === void 0 ? void 0 : buttons.saveDraft) === null || _g === void 0 ? void 0 : _g.label) ||
|
|
944
|
+
'Save Draft', icon: (_h = buttons === null || buttons === void 0 ? void 0 : buttons.saveDraft) === null || _h === void 0 ? void 0 : _h.icon }) })), _jsx("span", { style: { flex: 1 } }), _jsx("button", { type: "button", className: "button ob-button is-light cypress-cancel-confirm-back", onClick: handleKeepGoing, children: _jsx(CustomisableButtonInner, { label: ((_j = buttons === null || buttons === void 0 ? void 0 : buttons.cancelPromptNo) === null || _j === void 0 ? void 0 : _j.label) || 'Back', icon: (_k = buttons === null || buttons === void 0 ? void 0 : buttons.cancelPromptNo) === null || _k === void 0 ? void 0 : _k.icon }) }), _jsx("button", { type: "button", className: "button ob-button is-primary cypress-cancel-confirm-discard", onClick: handleDiscardUnsavedChanges, autoFocus: true, children: _jsx(CustomisableButtonInner, { label: ((_l = buttons === null || buttons === void 0 ? void 0 : buttons.cancelPromptYes) === null || _l === void 0 ? void 0 : _l.label) ||
|
|
945
|
+
'Discard', icon: (_m = buttons === null || buttons === void 0 ? void 0 : buttons.cancelPromptYes) === null || _m === void 0 ? void 0 : _m.icon }) })] }), children: _jsx("p", { children: "You have unsaved changes, are you sure you want discard them?" }) }), hostAttemptPhase.status === 'preparing' && (_jsx(HostPreparationEffect, { continueWithAttachments: hostAttemptPhase.continueWithAttachments, prepareSubmission: prepareSubmission, onResult: handleHostPreparationResult })), _jsx(Modal, { isOpen: promptUploadingAttachments === true, title: "Attachment upload in progress", cardClassName: "cypress-attachments-wait-continue", titleClassName: "cypress-attachments-confirm-wait-title", bodyClassName: "cypress-attachments-confirm-wait-body", actions: _jsxs(_Fragment, { children: [_jsx("span", { style: { flex: 1 } }), _jsx("button", { type: "button", className: "button ob-button is-light cypress-attachments-confirm-wait", onClick: handleWaitForAttachments, children: "Wait" }), _jsx("button", { type: "button", className: "button ob-button is-primary cypress-attachments-confirm-continue", onClick: handleContinueWithAttachments, autoFocus: true, children: "Continue" })] }), children: _jsx("p", { children: "Your attachments are still uploading, do you want to wait for the uploads to complete or continue using the app? If you click continue the attachments will upload in the background. Do not close the app until the upload has been completed." }) }), _jsxs(Modal, { isOpen: promptOfflineSubmissionAttempt, title: "It looks like you're Offline", className: "ob-modal__offline-submission-attempt", cardClassName: "cypress-submission-offline has-text-centered", titleClassName: "cypress-offline-title", bodyClassName: "cypress-offline-body", actions: _jsxs(_Fragment, { children: [onSaveDraft && (_jsx("button", { type: "button", className: "button ob-button ob-button__offline-submission-attempt-save-draft is-success", onClick: () => handleSaveDraft(false), children: _jsx(CustomisableButtonInner, { label: ((_o = buttons === null || buttons === void 0 ? void 0 : buttons.saveDraft) === null || _o === void 0 ? void 0 : _o.label) ||
|
|
946
|
+
'Save Draft', icon: (_p = buttons === null || buttons === void 0 ? void 0 : buttons.saveDraft) === null || _p === void 0 ? void 0 : _p.icon }) })), _jsx("span", { style: { flex: 1 } }), _jsx("button", { className: "button ob-button ob-button__offline-submission-attempt-cancel is-light cypress-offline-submission-cancel", onClick: handleCancelOfflineSubmission, children: "Cancel" }), _jsx("button", { className: "button ob-button ob-button__offline-submission-attempt-try-again is-primary cypress-offline-submission-try-again", onClick: handleRetryOfflineSubmission, autoFocus: true, children: "Try Again" })] }), children: [_jsxs("p", { className: "ob-modal__offline-submission-attempt-message", children: ["You cannot submit this form while offline, please try again when connectivity is restored.", onSaveDraft && (_jsxs("span", { className: "ob-modal__offline-submission-attempt-save-draft-message", children: [' ', "Alternatively, click the", ' ', _jsx("b", { children: ((_q = buttons === null || buttons === void 0 ? void 0 : buttons.saveDraft) === null || _q === void 0 ? void 0 : _q.label) ||
|
|
947
|
+
'Save Draft' }), ' ', "button below to come back to this later."] }))] }), _jsx(MaterialIcon, { className: "has-text-warning icon-x-large ob-modal__offline-submission-attempt-icon", children: "wifi_off" })] })] })), shouldUseNavigableValidationErrorsNotification &&
|
|
948
|
+
isShowingValidationErrorsCard && (_jsx(ValidationErrorsCard, { visiblePages: visiblePages, formElementsValidation: formElementsValidation, setPageId: setPageId, currentPage: currentPage, navigationTopOffset: (_r = navigableValidationErrorsNotificationSettings === null || navigableValidationErrorsNotificationSettings === void 0 ? void 0 : navigableValidationErrorsNotificationSettings.navigationTopOffset) !== null && _r !== void 0 ? _r : 'CALCULATE', scrollableContainerId: navigableValidationErrorsNotificationSettings === null || navigableValidationErrorsNotificationSettings === void 0 ? void 0 : navigableValidationErrorsNotificationSettings.scrollableContainerId, validationErrorToastFocusElementRef: validationErrorToastFocusElementRef }))] }) }) }) }) }) }) }) }) }));
|
|
792
949
|
}
|
|
793
950
|
export default React.memo(OneBlinkFormBase);
|
|
794
951
|
//# sourceMappingURL=OneBlinkFormBase.js.map
|