@oneblink/apps-react 13.0.0-beta.3 → 13.0.0-beta.5
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 +164 -145
- 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/components/renderer/LookupNotification.js +15 -16
- 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/FormElementCalculation.js +1 -0
- package/dist/form-elements/FormElementCalculation.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 +3 -2
- package/dist/form-elements/FormElementLookupButton.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/FormElementSummary.js +2 -0
- package/dist/form-elements/FormElementSummary.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 +1 -0
- 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 +2 -1
- 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
|
@@ -3,7 +3,7 @@ import { submissionService, attachmentsService } from './apps';
|
|
|
3
3
|
import { EnvironmentTypes, FormTypes, FormsAppsTypes, ScheduledTasksTypes, SubmissionTypes } from '@oneblink/types';
|
|
4
4
|
import { ReplaceInjectablesOverrides } from './hooks/useReplaceInjectablesOverrides';
|
|
5
5
|
import { CaptchaType, ExecutedLookups, SetFormSubmission, SectionState } from './types/form';
|
|
6
|
-
|
|
6
|
+
type OneBlinkFormDisplayProps = {
|
|
7
7
|
/**
|
|
8
8
|
* A [Google Maps API
|
|
9
9
|
* Key](https://developers.google.com/maps/documentation/javascript/get-api-key).
|
|
@@ -40,7 +40,27 @@ export type OneBlinkReadOnlyFormProps = {
|
|
|
40
40
|
*/
|
|
41
41
|
audience: FormTypes.FormElementHiddenFromAudience;
|
|
42
42
|
};
|
|
43
|
-
export type
|
|
43
|
+
export type OneBlinkReadOnlyFormProps = OneBlinkFormDisplayProps & ((OneBlinkFormControlledProps & {
|
|
44
|
+
/**
|
|
45
|
+
* Element ids that remain editable. All other elements are read-only.
|
|
46
|
+
* Requires the same controlled submission props as
|
|
47
|
+
* `OneBlinkFormControlled`.
|
|
48
|
+
*/
|
|
49
|
+
editableFormElementIds: string[];
|
|
50
|
+
form?: never;
|
|
51
|
+
initialSubmission?: never;
|
|
52
|
+
}) | (OneBlinkFormUncontrolledProps & {
|
|
53
|
+
/** Omit to render every form element as read-only. */
|
|
54
|
+
editableFormElementIds?: never;
|
|
55
|
+
definition?: never;
|
|
56
|
+
submission?: never;
|
|
57
|
+
setFormSubmission?: never;
|
|
58
|
+
lastElementUpdated?: never;
|
|
59
|
+
executedLookups?: never;
|
|
60
|
+
sectionState?: never;
|
|
61
|
+
}));
|
|
62
|
+
export type OneBlinkFormBaseProps = OneBlinkFormDisplayProps & {
|
|
63
|
+
editableFormElementIds?: string[];
|
|
44
64
|
/** The function to call when the user cancels the form */
|
|
45
65
|
onCancel: () => unknown;
|
|
46
66
|
/**
|
|
@@ -162,6 +182,6 @@ export type OneBlinkFormControlledProps = {
|
|
|
162
182
|
type Props = OneBlinkFormBaseProps & OneBlinkFormControlledProps & {
|
|
163
183
|
isReadOnly: boolean;
|
|
164
184
|
};
|
|
165
|
-
declare 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, navigableValidationErrorsNotificationSettings, replaceInjectablesOverrides, sectionState, scrollToTopOfPage, getCurrentSubmissionDuration, onBeforeUnload, audience, }: Props): import("react/jsx-runtime").JSX.Element;
|
|
185
|
+
declare 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, navigableValidationErrorsNotificationSettings, replaceInjectablesOverrides, sectionState, scrollToTopOfPage, getCurrentSubmissionDuration, onBeforeUnload, audience, editableFormElementIds, }: Props): import("react/jsx-runtime").JSX.Element;
|
|
166
186
|
declare const _default: React.MemoExoticComponent<typeof OneBlinkFormBase>;
|
|
167
187
|
export default _default;
|
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,10 @@ 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
|
+
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
52
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
|
|
49
53
|
const isOffline = useIsOffline();
|
|
50
54
|
const { isUsingFormsKey } = useAuth();
|
|
@@ -225,6 +229,13 @@ function OneBlinkFormBase({ googleMapsApiKey, abnLookupAuthenticationGuid, captc
|
|
|
225
229
|
isNavigationAllowed: true,
|
|
226
230
|
}));
|
|
227
231
|
}, []);
|
|
232
|
+
const allowNavigationAfterHostAction = React.useCallback(() => {
|
|
233
|
+
// React Router DOM v5's <Prompt> has no imperative "proceed" API, so the
|
|
234
|
+
// guard must rerender as disabled before the host navigates in the same
|
|
235
|
+
// tick. Migrating to the React Router DOM v6 blocker APIs would allow the
|
|
236
|
+
// blocked transition to proceed directly without flushSync().
|
|
237
|
+
flushSync(allowNavigation);
|
|
238
|
+
}, [allowNavigation]);
|
|
228
239
|
// #endregion Unsaved Changed
|
|
229
240
|
//
|
|
230
241
|
//
|
|
@@ -246,8 +257,8 @@ function OneBlinkFormBase({ googleMapsApiKey, abnLookupAuthenticationGuid, captc
|
|
|
246
257
|
const [isShowingValidationErrorsCard, setIsShowingValidationErrorsCard] = React.useState(false);
|
|
247
258
|
const { validate } = useFormValidation(pages);
|
|
248
259
|
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)
|
|
260
|
+
const formElementsValidation = React.useMemo(() => !isReadOnly || editableFormElementIds !== undefined
|
|
261
|
+
? validate(submission, formElementsConditionallyShown, executedLookups !== null && executedLookups !== void 0 ? executedLookups : {}, recaptchaType, isOffline, audience, editableFormElementIds)
|
|
251
262
|
: undefined, [
|
|
252
263
|
isReadOnly,
|
|
253
264
|
validate,
|
|
@@ -257,6 +268,7 @@ function OneBlinkFormBase({ googleMapsApiKey, abnLookupAuthenticationGuid, captc
|
|
|
257
268
|
recaptchaType,
|
|
258
269
|
isOffline,
|
|
259
270
|
audience,
|
|
271
|
+
editableFormElementIds,
|
|
260
272
|
]);
|
|
261
273
|
React.useEffect(() => {
|
|
262
274
|
if (!formElementsValidation) {
|
|
@@ -472,6 +484,24 @@ function OneBlinkFormBase({ googleMapsApiKey, abnLookupAuthenticationGuid, captc
|
|
|
472
484
|
setFormSubmission,
|
|
473
485
|
shouldUseNavigableValidationErrorsNotification,
|
|
474
486
|
]);
|
|
487
|
+
const attemptFormSubmission = React.useCallback(async () => {
|
|
488
|
+
setHasAttemptedSubmit(true);
|
|
489
|
+
setIsPreparingToSubmit(true);
|
|
490
|
+
try {
|
|
491
|
+
if (!(await prepareSubmission(false))) {
|
|
492
|
+
return false;
|
|
493
|
+
}
|
|
494
|
+
// The host must call this after it has persisted the edits. Calling it
|
|
495
|
+
// here would let the user cancel a later confirmation dialog and leave
|
|
496
|
+
// without being prompted.
|
|
497
|
+
return allowNavigationAfterHostAction;
|
|
498
|
+
}
|
|
499
|
+
finally {
|
|
500
|
+
setIsPreparingToSubmit(false);
|
|
501
|
+
}
|
|
502
|
+
}, [allowNavigationAfterHostAction, prepareSubmission]);
|
|
503
|
+
useRegisterFormSubmissionAttempt(editableFormElementIds === undefined ? undefined : attemptFormSubmission);
|
|
504
|
+
useRegisterFormIsDirty(definition.id, isDirty);
|
|
475
505
|
const handleSubmit = React.useCallback(async (event, continueWhilstAttachmentsAreUploading) => {
|
|
476
506
|
event.preventDefault();
|
|
477
507
|
// Approvers are not shown a submit button, so reaching here means the
|
|
@@ -588,109 +618,93 @@ function OneBlinkFormBase({ googleMapsApiKey, abnLookupAuthenticationGuid, captc
|
|
|
588
618
|
//
|
|
589
619
|
//
|
|
590
620
|
//
|
|
591
|
-
// #region
|
|
592
|
-
const
|
|
593
|
-
|
|
621
|
+
// #region Submission/Definition Changes
|
|
622
|
+
const markFormDirty = React.useCallback(() => {
|
|
623
|
+
setUnsavedChangesState((current) => ({
|
|
624
|
+
...current,
|
|
625
|
+
isDirty: true,
|
|
626
|
+
}));
|
|
627
|
+
}, []);
|
|
594
628
|
//
|
|
595
629
|
//
|
|
630
|
+
// #region Lookups
|
|
631
|
+
const { handlePagesLookupResult } = useLookups(definition.id, setFormSubmission, markFormDirty);
|
|
632
|
+
// #endregion
|
|
596
633
|
//
|
|
597
634
|
//
|
|
598
|
-
|
|
599
|
-
const handleChange = React.useCallback((element, { value, executedLookups, deleteSection, sectionState }) => {
|
|
635
|
+
const handleChange = React.useCallback((element, { value, executedLookups, deleteSection, sectionState, isDerivedChange }) => {
|
|
600
636
|
if (
|
|
601
|
-
//
|
|
602
|
-
//
|
|
603
|
-
|
|
604
|
-
(disabled &&
|
|
605
|
-
element.type !== 'summary' &&
|
|
606
|
-
element.type !== 'calculation') ||
|
|
637
|
+
// Disabled forms still need derived writers (calculation, summary, …)
|
|
638
|
+
// so those elements can recompute and display from the current model.
|
|
639
|
+
(disabled && !isDerivedChange) ||
|
|
607
640
|
element.type === 'page') {
|
|
608
641
|
return;
|
|
609
642
|
}
|
|
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,
|
|
643
|
+
if (element.type === 'section') {
|
|
644
|
+
setFormSubmission((currentFormSubmission) => {
|
|
645
|
+
const currentSectionState = currentFormSubmission.sectionState || [];
|
|
646
|
+
const existingSectionIndex = currentSectionState.findIndex((section) => section.id === element.id);
|
|
647
|
+
const sectionIsInState = existingSectionIndex >= 0;
|
|
648
|
+
let newSectionState;
|
|
649
|
+
if (sectionIsInState && deleteSection) {
|
|
650
|
+
newSectionState = currentSectionState.filter((section) => section.id !== element.id);
|
|
651
|
+
}
|
|
652
|
+
else if (sectionIsInState) {
|
|
653
|
+
// Update state of the section
|
|
654
|
+
newSectionState = currentSectionState.map((section, index) => index === existingSectionIndex
|
|
655
|
+
? {
|
|
656
|
+
...section,
|
|
657
|
+
state: section.state === 'COLLAPSED' ? 'EXPANDED' : 'COLLAPSED',
|
|
658
|
+
}
|
|
659
|
+
: section);
|
|
660
|
+
}
|
|
661
|
+
else {
|
|
662
|
+
// Add the section to state
|
|
663
|
+
newSectionState = [
|
|
664
|
+
...currentSectionState,
|
|
665
|
+
{
|
|
666
|
+
id: element.id,
|
|
667
|
+
state: element.isCollapsed ? 'EXPANDED' : 'COLLAPSED',
|
|
683
668
|
},
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
669
|
+
];
|
|
670
|
+
}
|
|
671
|
+
return {
|
|
672
|
+
...currentFormSubmission,
|
|
673
|
+
sectionState: newSectionState,
|
|
674
|
+
};
|
|
675
|
+
});
|
|
676
|
+
return;
|
|
692
677
|
}
|
|
693
|
-
|
|
678
|
+
if (!isDerivedChange) {
|
|
679
|
+
markFormDirty();
|
|
680
|
+
}
|
|
681
|
+
setFormSubmission((currentFormSubmission) => {
|
|
682
|
+
var _a;
|
|
683
|
+
return {
|
|
684
|
+
...currentFormSubmission,
|
|
685
|
+
submission: {
|
|
686
|
+
...currentFormSubmission.submission,
|
|
687
|
+
[element.name]: typeof value === 'function'
|
|
688
|
+
? value(currentFormSubmission.submission[element.name])
|
|
689
|
+
: value,
|
|
690
|
+
},
|
|
691
|
+
lastElementUpdated: isDerivedChange
|
|
692
|
+
? currentFormSubmission.lastElementUpdated
|
|
693
|
+
: element,
|
|
694
|
+
executedLookups: {
|
|
695
|
+
...currentFormSubmission.executedLookups,
|
|
696
|
+
[element.name]: typeof executedLookups === 'function'
|
|
697
|
+
? executedLookups((_a = currentFormSubmission.executedLookups) === null || _a === void 0 ? void 0 : _a[element.name])
|
|
698
|
+
: executedLookups,
|
|
699
|
+
},
|
|
700
|
+
sectionState: sectionState
|
|
701
|
+
? typeof sectionState === 'function'
|
|
702
|
+
? sectionState(currentFormSubmission.sectionState)
|
|
703
|
+
: sectionState
|
|
704
|
+
: currentFormSubmission.sectionState,
|
|
705
|
+
};
|
|
706
|
+
}, { isDerivedChange });
|
|
707
|
+
}, [disabled, markFormDirty, setFormSubmission]);
|
|
694
708
|
// #endregion
|
|
695
709
|
//
|
|
696
710
|
//
|
|
@@ -740,55 +754,60 @@ function OneBlinkFormBase({ googleMapsApiKey, abnLookupAuthenticationGuid, captc
|
|
|
740
754
|
if (conditionalLogicError) {
|
|
741
755
|
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
756
|
}
|
|
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
|
-
|
|
757
|
+
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', {
|
|
758
|
+
'is-showing-pages': isShowingMultiplePages,
|
|
759
|
+
}), 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', {
|
|
760
|
+
'is-active': isStepsHeaderActive,
|
|
761
|
+
}), children: [_jsxs(Clickable, { className: clsx('ob-steps-navigation__header', {
|
|
762
|
+
'is-active': isStepsHeaderActive,
|
|
763
|
+
}), 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', {
|
|
764
|
+
'is-active': isStepsHeaderActive,
|
|
765
|
+
}), children: _jsx("div", { className: "steps is-small is-horizontal-tablet cypress-steps", children: visiblePages.map((page, index) => {
|
|
766
|
+
const hasErrors = checkDisplayPageError(page);
|
|
767
|
+
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
|
|
768
|
+
? 'step'
|
|
769
|
+
: undefined, className: clsx('step-item cypress-step-item', {
|
|
770
|
+
'is-active': currentPage.id === page.id,
|
|
771
|
+
'is-completed': currentPageIndex > index,
|
|
772
|
+
'is-error': hasErrors,
|
|
773
|
+
}), onClick: (e) => {
|
|
774
|
+
e.stopPropagation();
|
|
775
|
+
if (page.id !== currentPage.id) {
|
|
776
|
+
setPageId(page.id);
|
|
777
|
+
}
|
|
778
|
+
}, children: [_jsx("div", { className: "step-marker step-marker-error ob-step-marker cypress-step-marker",
|
|
779
|
+
// @ts-expect-error ???
|
|
780
|
+
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));
|
|
781
|
+
}) }) })] })), _jsx("div", { className: clsx('ob-steps-navigation__background', {
|
|
782
|
+
'is-active': isStepsHeaderActive,
|
|
783
|
+
}), onClick: toggleStepsNavigation }), _jsxs("div", { className: "steps", children: [_jsx("div", { className: clsx('steps-content', {
|
|
784
|
+
'is-single-step': !isShowingMultiplePages,
|
|
785
|
+
}), 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 ===
|
|
786
|
+
currentPage.id, formId: definition.id, formElementsConditionallyShown: formElementsConditionallyShown, formElementsValidation: formElementsValidation, displayValidationMessages: hasAttemptedSubmit ||
|
|
787
|
+
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', {
|
|
788
|
+
'is-active': currentPage.id === page.id,
|
|
789
|
+
'is-completed': currentPageIndex > index,
|
|
790
|
+
'has-background-danger': currentPage.id !== page.id &&
|
|
791
|
+
checkDisplayPageError(page),
|
|
792
|
+
}) }, 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
|
|
793
|
+
? ''
|
|
794
|
+
: '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 }, {
|
|
795
|
+
'ob-button-submit-is-disabled': submissionConditionallyEnabled,
|
|
796
|
+
}), disabled: isPreview ||
|
|
797
|
+
disabled ||
|
|
798
|
+
isPreparingToSubmit ||
|
|
799
|
+
!submissionConditionallyEnabled, children: _jsx(CustomisableButtonInner, { label: isInfoPage
|
|
800
|
+
? 'Done'
|
|
801
|
+
: ((_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 &&
|
|
802
|
+
(editableFormElementIds !== undefined ||
|
|
803
|
+
!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) ||
|
|
804
|
+
'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) ||
|
|
805
|
+
'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?" }) })] })), !isReadOnly && !isPreview && audience !== 'APPROVER' && (_jsxs(React.Fragment, { children: [_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) ||
|
|
806
|
+
'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", onClick: () => setPromptOfflineSubmissionAttempt(false), children: "Cancel" }), _jsx("button", { className: "button ob-button ob-button__offline-submission-attempt-try-again is-primary", onClick: (e) => {
|
|
807
|
+
setPromptOfflineSubmissionAttempt(false);
|
|
808
|
+
handleSubmit(e, false);
|
|
809
|
+
}, 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) || '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 &&
|
|
810
|
+
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
811
|
}
|
|
793
812
|
export default React.memo(OneBlinkFormBase);
|
|
794
813
|
//# sourceMappingURL=OneBlinkFormBase.js.map
|