@oneblink/apps-react 13.0.0-beta.1 → 13.0.0-beta.11
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 +351 -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 +2 -60
- package/dist/apps/approvals-service.js +1 -181
- 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 +56 -0
- package/dist/hooks/useFormIsDirty.js +121 -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/services/getFlowInstanceNodesWithMeta.d.ts +70 -0
- package/dist/services/getFlowInstanceNodesWithMeta.js +247 -0
- package/dist/services/getFlowInstanceNodesWithMeta.js.map +1 -0
- 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, useRegisterAllowFormNavigation, 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,55 @@ 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);
|
|
584
|
+
useRegisterAllowFormNavigation(definition.id, allowNavigationAfterHostAction);
|
|
475
585
|
const handleSubmit = React.useCallback(async (event, continueWhilstAttachmentsAreUploading) => {
|
|
476
586
|
event.preventDefault();
|
|
477
587
|
// Approvers are not shown a submit button, so reaching here means the
|
|
@@ -482,39 +592,60 @@ function OneBlinkFormBase({ googleMapsApiKey, abnLookupAuthenticationGuid, captc
|
|
|
482
592
|
return;
|
|
483
593
|
setHasAttemptedSubmit(true);
|
|
484
594
|
setIsPreparingToSubmit(true);
|
|
485
|
-
const
|
|
486
|
-
if (!
|
|
595
|
+
const submissionResult = await prepareSubmission(continueWhilstAttachmentsAreUploading);
|
|
596
|
+
if (!submissionResult) {
|
|
487
597
|
setIsPreparingToSubmit(false);
|
|
488
598
|
return;
|
|
489
599
|
}
|
|
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
|
-
|
|
600
|
+
switch (submissionResult.status) {
|
|
601
|
+
case AttachmentUploadStatus.ATTACHMENTS_UPLOAD_NON_BLOCKING: {
|
|
602
|
+
setPromptUploadingAttachments(true);
|
|
603
|
+
setIsPreparingToSubmit(false);
|
|
604
|
+
return;
|
|
605
|
+
}
|
|
606
|
+
case SubmissionPreparationStatus.OFFLINE_SUBMISSION: {
|
|
607
|
+
setPromptOfflineSubmissionAttempt(true);
|
|
608
|
+
setIsPreparingToSubmit(false);
|
|
609
|
+
return;
|
|
610
|
+
}
|
|
611
|
+
case SubmissionPreparationStatus.SUBMISSION_READY: {
|
|
612
|
+
allowNavigation();
|
|
613
|
+
const submissionData = submissionResult.submissionData;
|
|
614
|
+
// transplant injected options on the definition
|
|
615
|
+
const elementsWithInjectedOptions = injectOptionsAcrossAllElements({
|
|
616
|
+
contextElements: definition.elements,
|
|
617
|
+
elements: definition.elements,
|
|
618
|
+
submission: submissionData.submission,
|
|
619
|
+
taskContext: taskContextValue,
|
|
620
|
+
userProfile: userProfileForInjectables,
|
|
621
|
+
});
|
|
622
|
+
setIsPreparingToSubmit(false);
|
|
623
|
+
resetRecaptchas();
|
|
624
|
+
onSubmit({
|
|
625
|
+
definition: {
|
|
626
|
+
...definition,
|
|
627
|
+
elements: elementsWithInjectedOptions,
|
|
628
|
+
},
|
|
629
|
+
submission: submissionData.submission,
|
|
630
|
+
recaptchas: submissionData.captchaTokens.map((token) => ({
|
|
631
|
+
token,
|
|
632
|
+
siteKey: captchaSiteKey,
|
|
633
|
+
})),
|
|
634
|
+
});
|
|
635
|
+
sendGoogleAnalyticsEvent('oneblink_form_submit', {
|
|
636
|
+
formId: definition.id,
|
|
637
|
+
formName: definition.name,
|
|
638
|
+
lastElementUpdated: getElementDisplayNameForAnalyticsEvent(lastElementUpdated),
|
|
639
|
+
durationUntilSubmission: getCurrentSubmissionDuration === null || getCurrentSubmissionDuration === void 0 ? void 0 : getCurrentSubmissionDuration(),
|
|
640
|
+
});
|
|
641
|
+
return;
|
|
642
|
+
}
|
|
643
|
+
default: {
|
|
644
|
+
const never = submissionResult;
|
|
645
|
+
setIsPreparingToSubmit(false);
|
|
646
|
+
return never;
|
|
647
|
+
}
|
|
648
|
+
}
|
|
518
649
|
}, [
|
|
519
650
|
disabled,
|
|
520
651
|
isReadOnly,
|
|
@@ -541,9 +672,18 @@ function OneBlinkFormBase({ googleMapsApiKey, abnLookupAuthenticationGuid, captc
|
|
|
541
672
|
if (!checkBsbAreValidating(submission)) {
|
|
542
673
|
return;
|
|
543
674
|
}
|
|
544
|
-
if (!continueWhilstAttachmentsAreUploading
|
|
545
|
-
|
|
546
|
-
|
|
675
|
+
if (!continueWhilstAttachmentsAreUploading) {
|
|
676
|
+
const attachmentCheckResult = checkAttachmentsCanBeSubmitted(submission);
|
|
677
|
+
if (attachmentCheckResult ===
|
|
678
|
+
AttachmentUploadStatus.ATTACHMENTS_UPLOAD_NON_BLOCKING) {
|
|
679
|
+
setPromptUploadingAttachments(true);
|
|
680
|
+
return;
|
|
681
|
+
}
|
|
682
|
+
if (attachmentCheckResult ===
|
|
683
|
+
AttachmentUploadStatus.ATTACHMENTS_UPLOAD_BLOCKING) {
|
|
684
|
+
// The submitter cannot upload attachments in the background and must wait for them to upload before saving draft
|
|
685
|
+
return;
|
|
686
|
+
}
|
|
547
687
|
}
|
|
548
688
|
onSaveDraft({
|
|
549
689
|
definition,
|
|
@@ -568,6 +708,13 @@ function OneBlinkFormBase({ googleMapsApiKey, abnLookupAuthenticationGuid, captc
|
|
|
568
708
|
]);
|
|
569
709
|
const handleContinueWithAttachments = React.useCallback((e) => {
|
|
570
710
|
setPromptUploadingAttachments(false);
|
|
711
|
+
if (hostAttemptPhase.status === 'prompt-attachments') {
|
|
712
|
+
setHostAttemptPhase({
|
|
713
|
+
status: 'preparing',
|
|
714
|
+
continueWithAttachments: true,
|
|
715
|
+
});
|
|
716
|
+
return;
|
|
717
|
+
}
|
|
571
718
|
if (hasAttemptedSubmit) {
|
|
572
719
|
handleSubmit(e, true);
|
|
573
720
|
}
|
|
@@ -576,121 +723,129 @@ function OneBlinkFormBase({ googleMapsApiKey, abnLookupAuthenticationGuid, captc
|
|
|
576
723
|
}
|
|
577
724
|
}, [
|
|
578
725
|
handleSubmit,
|
|
579
|
-
|
|
726
|
+
hostAttemptPhase.status,
|
|
580
727
|
hasAttemptedSubmit,
|
|
581
728
|
handleSaveDraft,
|
|
582
729
|
]);
|
|
583
730
|
const handleWaitForAttachments = React.useCallback(() => {
|
|
584
731
|
setPromptUploadingAttachments(false);
|
|
585
|
-
|
|
732
|
+
if (hostAttemptPhase.status === 'prompt-attachments') {
|
|
733
|
+
setHostAttemptPhase({ status: 'resolved', result: false });
|
|
734
|
+
}
|
|
735
|
+
}, [hostAttemptPhase.status]);
|
|
736
|
+
const handleCancelOfflineSubmission = React.useCallback(() => {
|
|
737
|
+
setPromptOfflineSubmissionAttempt(false);
|
|
738
|
+
if (hostAttemptPhase.status === 'prompt-offline') {
|
|
739
|
+
setHostAttemptPhase({ status: 'resolved', result: false });
|
|
740
|
+
}
|
|
741
|
+
}, [hostAttemptPhase.status]);
|
|
742
|
+
const handleRetryOfflineSubmission = React.useCallback((e) => {
|
|
743
|
+
setPromptOfflineSubmissionAttempt(false);
|
|
744
|
+
if (hostAttemptPhase.status === 'prompt-offline') {
|
|
745
|
+
setHostAttemptPhase({
|
|
746
|
+
status: 'preparing',
|
|
747
|
+
continueWithAttachments: hostAttemptPhase.continueWithAttachments,
|
|
748
|
+
});
|
|
749
|
+
}
|
|
750
|
+
else {
|
|
751
|
+
handleSubmit(e, false);
|
|
752
|
+
}
|
|
753
|
+
}, [
|
|
754
|
+
handleSubmit,
|
|
755
|
+
hostAttemptPhase,
|
|
756
|
+
]);
|
|
586
757
|
// #endregion
|
|
587
758
|
//
|
|
588
759
|
//
|
|
589
760
|
//
|
|
590
761
|
//
|
|
591
|
-
// #region
|
|
592
|
-
const
|
|
593
|
-
|
|
762
|
+
// #region Submission/Definition Changes
|
|
763
|
+
const markFormDirty = React.useCallback(() => {
|
|
764
|
+
setUnsavedChangesState((current) => ({
|
|
765
|
+
...current,
|
|
766
|
+
isDirty: true,
|
|
767
|
+
}));
|
|
768
|
+
}, []);
|
|
594
769
|
//
|
|
595
770
|
//
|
|
771
|
+
// #region Lookups
|
|
772
|
+
const { handlePagesLookupResult } = useLookups(definition.id, setFormSubmission, markFormDirty);
|
|
773
|
+
// #endregion
|
|
596
774
|
//
|
|
597
775
|
//
|
|
598
|
-
|
|
599
|
-
const handleChange = React.useCallback((element, { value, executedLookups, deleteSection, sectionState }) => {
|
|
776
|
+
const handleChange = React.useCallback((element, { value, executedLookups, deleteSection, sectionState, isDerivedChange }) => {
|
|
600
777
|
if (
|
|
601
|
-
//
|
|
602
|
-
//
|
|
603
|
-
|
|
604
|
-
(disabled &&
|
|
605
|
-
element.type !== 'summary' &&
|
|
606
|
-
element.type !== 'calculation') ||
|
|
778
|
+
// Disabled forms still need derived writers (calculation, summary, …)
|
|
779
|
+
// so those elements can recompute and display from the current model.
|
|
780
|
+
(disabled && !isDerivedChange) ||
|
|
607
781
|
element.type === 'page') {
|
|
608
782
|
return;
|
|
609
783
|
}
|
|
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,
|
|
784
|
+
if (element.type === 'section') {
|
|
785
|
+
setFormSubmission((currentFormSubmission) => {
|
|
786
|
+
const currentSectionState = currentFormSubmission.sectionState || [];
|
|
787
|
+
const existingSectionIndex = currentSectionState.findIndex((section) => section.id === element.id);
|
|
788
|
+
const sectionIsInState = existingSectionIndex >= 0;
|
|
789
|
+
let newSectionState;
|
|
790
|
+
if (sectionIsInState && deleteSection) {
|
|
791
|
+
newSectionState = currentSectionState.filter((section) => section.id !== element.id);
|
|
792
|
+
}
|
|
793
|
+
else if (sectionIsInState) {
|
|
794
|
+
// Update state of the section
|
|
795
|
+
newSectionState = currentSectionState.map((section, index) => index === existingSectionIndex
|
|
796
|
+
? {
|
|
797
|
+
...section,
|
|
798
|
+
state: section.state === 'COLLAPSED' ? 'EXPANDED' : 'COLLAPSED',
|
|
799
|
+
}
|
|
800
|
+
: section);
|
|
801
|
+
}
|
|
802
|
+
else {
|
|
803
|
+
// Add the section to state
|
|
804
|
+
newSectionState = [
|
|
805
|
+
...currentSectionState,
|
|
806
|
+
{
|
|
807
|
+
id: element.id,
|
|
808
|
+
state: element.isCollapsed ? 'EXPANDED' : 'COLLAPSED',
|
|
683
809
|
},
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
810
|
+
];
|
|
811
|
+
}
|
|
812
|
+
return {
|
|
813
|
+
...currentFormSubmission,
|
|
814
|
+
sectionState: newSectionState,
|
|
815
|
+
};
|
|
816
|
+
});
|
|
817
|
+
return;
|
|
818
|
+
}
|
|
819
|
+
if (!isDerivedChange) {
|
|
820
|
+
markFormDirty();
|
|
692
821
|
}
|
|
693
|
-
|
|
822
|
+
setFormSubmission((currentFormSubmission) => {
|
|
823
|
+
var _a;
|
|
824
|
+
return {
|
|
825
|
+
...currentFormSubmission,
|
|
826
|
+
submission: {
|
|
827
|
+
...currentFormSubmission.submission,
|
|
828
|
+
[element.name]: typeof value === 'function'
|
|
829
|
+
? value(currentFormSubmission.submission[element.name])
|
|
830
|
+
: value,
|
|
831
|
+
},
|
|
832
|
+
lastElementUpdated: isDerivedChange
|
|
833
|
+
? currentFormSubmission.lastElementUpdated
|
|
834
|
+
: element,
|
|
835
|
+
executedLookups: {
|
|
836
|
+
...currentFormSubmission.executedLookups,
|
|
837
|
+
[element.name]: typeof executedLookups === 'function'
|
|
838
|
+
? executedLookups((_a = currentFormSubmission.executedLookups) === null || _a === void 0 ? void 0 : _a[element.name])
|
|
839
|
+
: executedLookups,
|
|
840
|
+
},
|
|
841
|
+
sectionState: sectionState
|
|
842
|
+
? typeof sectionState === 'function'
|
|
843
|
+
? sectionState(currentFormSubmission.sectionState)
|
|
844
|
+
: sectionState
|
|
845
|
+
: currentFormSubmission.sectionState,
|
|
846
|
+
};
|
|
847
|
+
}, { isDerivedChange });
|
|
848
|
+
}, [disabled, markFormDirty, setFormSubmission]);
|
|
694
849
|
// #endregion
|
|
695
850
|
//
|
|
696
851
|
//
|
|
@@ -740,55 +895,58 @@ function OneBlinkFormBase({ googleMapsApiKey, abnLookupAuthenticationGuid, captc
|
|
|
740
895
|
if (conditionalLogicError) {
|
|
741
896
|
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
897
|
}
|
|
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
|
-
|
|
898
|
+
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', {
|
|
899
|
+
'is-showing-pages': isShowingMultiplePages,
|
|
900
|
+
}), 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', {
|
|
901
|
+
'is-active': isStepsHeaderActive,
|
|
902
|
+
}), children: [_jsxs(Clickable, { className: clsx('ob-steps-navigation__header', {
|
|
903
|
+
'is-active': isStepsHeaderActive,
|
|
904
|
+
}), 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', {
|
|
905
|
+
'is-active': isStepsHeaderActive,
|
|
906
|
+
}), children: _jsx("div", { className: "steps is-small is-horizontal-tablet cypress-steps", children: visiblePages.map((page, index) => {
|
|
907
|
+
const hasErrors = checkDisplayPageError(page);
|
|
908
|
+
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
|
|
909
|
+
? 'step'
|
|
910
|
+
: undefined, className: clsx('step-item cypress-step-item', {
|
|
911
|
+
'is-active': currentPage.id === page.id,
|
|
912
|
+
'is-completed': currentPageIndex > index,
|
|
913
|
+
'is-error': hasErrors,
|
|
914
|
+
}), onClick: (e) => {
|
|
915
|
+
e.stopPropagation();
|
|
916
|
+
if (page.id !== currentPage.id) {
|
|
917
|
+
setPageId(page.id);
|
|
918
|
+
}
|
|
919
|
+
}, children: [_jsx("div", { className: "step-marker step-marker-error ob-step-marker cypress-step-marker",
|
|
920
|
+
// @ts-expect-error ???
|
|
921
|
+
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));
|
|
922
|
+
}) }) })] })), _jsx("div", { className: clsx('ob-steps-navigation__background', {
|
|
923
|
+
'is-active': isStepsHeaderActive,
|
|
924
|
+
}), onClick: toggleStepsNavigation }), _jsxs("div", { className: "steps", children: [_jsx("div", { className: clsx('steps-content', {
|
|
925
|
+
'is-single-step': !isShowingMultiplePages,
|
|
926
|
+
}), 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 ===
|
|
927
|
+
currentPage.id, formId: definition.id, formElementsConditionallyShown: formElementsConditionallyShown, formElementsValidation: formElementsValidation, displayValidationMessages: hasAttemptedSubmit ||
|
|
928
|
+
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', {
|
|
929
|
+
'is-active': currentPage.id === page.id,
|
|
930
|
+
'is-completed': currentPageIndex > index,
|
|
931
|
+
'has-background-danger': currentPage.id !== page.id &&
|
|
932
|
+
checkDisplayPageError(page),
|
|
933
|
+
}) }, 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
|
|
934
|
+
? ''
|
|
935
|
+
: '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 }, {
|
|
936
|
+
'ob-button-submit-is-disabled': submissionConditionallyEnabled,
|
|
937
|
+
}), disabled: isPreview ||
|
|
938
|
+
disabled ||
|
|
939
|
+
isPreparingToSubmit ||
|
|
940
|
+
!submissionConditionallyEnabled, children: _jsx(CustomisableButtonInner, { label: isInfoPage
|
|
941
|
+
? 'Done'
|
|
942
|
+
: ((_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 &&
|
|
943
|
+
(editableFormElementIds !== undefined ||
|
|
944
|
+
!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) ||
|
|
945
|
+
'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) ||
|
|
946
|
+
'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) ||
|
|
947
|
+
'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) ||
|
|
948
|
+
'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 &&
|
|
949
|
+
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
950
|
}
|
|
793
951
|
export default React.memo(OneBlinkFormBase);
|
|
794
952
|
//# sourceMappingURL=OneBlinkFormBase.js.map
|