@oneblink/apps-react 13.0.0-beta.4 → 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.
Files changed (42) hide show
  1. package/dist/OneBlinkFormBase.js +133 -145
  2. package/dist/OneBlinkFormBase.js.map +1 -1
  3. package/dist/components/renderer/LookupNotification.js +7 -4
  4. package/dist/components/renderer/LookupNotification.js.map +1 -1
  5. package/dist/components/renderer/PageFormElements.js +8 -3
  6. package/dist/components/renderer/PageFormElements.js.map +1 -1
  7. package/dist/components/renderer/ReverseGeocode.js +2 -0
  8. package/dist/components/renderer/ReverseGeocode.js.map +1 -1
  9. package/dist/form-elements/FormElementCalculation.js +1 -0
  10. package/dist/form-elements/FormElementCalculation.js.map +1 -1
  11. package/dist/form-elements/FormElementForm.d.ts +2 -2
  12. package/dist/form-elements/FormElementForm.js +4 -3
  13. package/dist/form-elements/FormElementForm.js.map +1 -1
  14. package/dist/form-elements/FormElementLookupButton.js +3 -2
  15. package/dist/form-elements/FormElementLookupButton.js.map +1 -1
  16. package/dist/form-elements/FormElementRepeatableSet.js +6 -4
  17. package/dist/form-elements/FormElementRepeatableSet.js.map +1 -1
  18. package/dist/form-elements/FormElementSection.js +2 -2
  19. package/dist/form-elements/FormElementSection.js.map +1 -1
  20. package/dist/form-elements/FormElementSummary.js +2 -0
  21. package/dist/form-elements/FormElementSummary.js.map +1 -1
  22. package/dist/hooks/useFormElementOptions.js +2 -0
  23. package/dist/hooks/useFormElementOptions.js.map +1 -1
  24. package/dist/hooks/useFormIsDirty.d.ts +38 -0
  25. package/dist/hooks/useFormIsDirty.js +78 -0
  26. package/dist/hooks/useFormIsDirty.js.map +1 -0
  27. package/dist/hooks/useFormSubmissionAutoSaveState.d.ts +2 -9
  28. package/dist/hooks/useFormSubmissionAutoSaveState.js +4 -2
  29. package/dist/hooks/useFormSubmissionAutoSaveState.js.map +1 -1
  30. package/dist/hooks/useInjectPages.d.ts +2 -1
  31. package/dist/hooks/useInjectPages.js.map +1 -1
  32. package/dist/hooks/useLookupNotification.d.ts +1 -0
  33. package/dist/hooks/useLookupNotification.js.map +1 -1
  34. package/dist/hooks/useLookups.d.ts +3 -3
  35. package/dist/hooks/useLookups.js +7 -4
  36. package/dist/hooks/useLookups.js.map +1 -1
  37. package/dist/index.d.ts +1 -0
  38. package/dist/index.js +1 -0
  39. package/dist/index.js.map +1 -1
  40. package/dist/types/form.d.ts +17 -3
  41. package/dist/types/form.js.map +1 -1
  42. package/package.json +1 -1
@@ -47,6 +47,7 @@ import { ValidationIconConfigurationContext } from './hooks/useValidationIconCon
47
47
  import { Clickable } from './components/Clickable';
48
48
  import { EditableFormElementIdsContext } from './hooks/useEditableFormElementIds';
49
49
  import { useRegisterFormSubmissionAttempt } from './hooks/useFormSubmissionAttempt';
50
+ import { useRegisterFormIsDirty, FormMarkDirtyContextProvider, } from './hooks/useFormIsDirty';
50
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, }) {
51
52
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
52
53
  const isOffline = useIsOffline();
@@ -500,6 +501,7 @@ function OneBlinkFormBase({ googleMapsApiKey, abnLookupAuthenticationGuid, captc
500
501
  }
501
502
  }, [allowNavigationAfterHostAction, prepareSubmission]);
502
503
  useRegisterFormSubmissionAttempt(editableFormElementIds === undefined ? undefined : attemptFormSubmission);
504
+ useRegisterFormIsDirty(definition.id, isDirty);
503
505
  const handleSubmit = React.useCallback(async (event, continueWhilstAttachmentsAreUploading) => {
504
506
  event.preventDefault();
505
507
  // Approvers are not shown a submit button, so reaching here means the
@@ -616,109 +618,93 @@ function OneBlinkFormBase({ googleMapsApiKey, abnLookupAuthenticationGuid, captc
616
618
  //
617
619
  //
618
620
  //
619
- // #region Lookups
620
- const { handlePagesLookupResult } = useLookups(definition.id, setFormSubmission);
621
- // #endregion
621
+ // #region Submission/Definition Changes
622
+ const markFormDirty = React.useCallback(() => {
623
+ setUnsavedChangesState((current) => ({
624
+ ...current,
625
+ isDirty: true,
626
+ }));
627
+ }, []);
622
628
  //
623
629
  //
630
+ // #region Lookups
631
+ const { handlePagesLookupResult } = useLookups(definition.id, setFormSubmission, markFormDirty);
632
+ // #endregion
624
633
  //
625
634
  //
626
- // #region Submission/Definition Changes
627
- const handleChange = React.useCallback((element, { value, executedLookups, deleteSection, sectionState }) => {
635
+ const handleChange = React.useCallback((element, { value, executedLookups, deleteSection, sectionState, isDerivedChange }) => {
628
636
  if (
629
- //This will ensure on a read only form that the summary and calculation elements
630
- //can still be displayed as it needs handleChange so it can render
631
- //due to the dynamic nature of the summary element.
632
- (disabled &&
633
- element.type !== 'summary' &&
634
- 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) ||
635
640
  element.type === 'page') {
636
641
  return;
637
642
  }
638
- switch (element.type) {
639
- case 'section': {
640
- setFormSubmission((currentFormSubmission) => {
641
- const currentSectionState = currentFormSubmission.sectionState || [];
642
- const existingSectionIndex = currentSectionState.findIndex((section) => section.id === element.id);
643
- const sectionIsInState = existingSectionIndex >= 0;
644
- let newSectionState;
645
- if (sectionIsInState && deleteSection) {
646
- newSectionState = currentSectionState.filter((section) => section.id !== element.id);
647
- }
648
- else if (sectionIsInState) {
649
- // Update state of the section
650
- newSectionState = currentSectionState.map((section, index) => index === existingSectionIndex
651
- ? {
652
- ...section,
653
- state: section.state === 'COLLAPSED'
654
- ? 'EXPANDED'
655
- : 'COLLAPSED',
656
- }
657
- : section);
658
- }
659
- else {
660
- // Add the section to state
661
- newSectionState = [
662
- ...currentSectionState,
663
- {
664
- id: element.id,
665
- state: element.isCollapsed ? 'EXPANDED' : 'COLLAPSED',
666
- },
667
- ];
668
- }
669
- return {
670
- ...currentFormSubmission,
671
- sectionState: newSectionState,
672
- };
673
- });
674
- break;
675
- }
676
- // Don't update the last element updated for elements the user cannot set the value of
677
- case 'summary':
678
- case 'calculation': {
679
- setFormSubmission((currentFormSubmission) => ({
680
- ...currentFormSubmission,
681
- submission: {
682
- ...currentFormSubmission.submission,
683
- [element.name]: typeof value === 'function'
684
- ? value(currentFormSubmission.submission[element.name])
685
- : value,
686
- },
687
- }));
688
- break;
689
- }
690
- default: {
691
- setUnsavedChangesState((current) => ({
692
- ...current,
693
- isDirty: true,
694
- }));
695
- setFormSubmission((currentFormSubmission) => {
696
- var _a;
697
- return {
698
- ...currentFormSubmission,
699
- submission: {
700
- ...currentFormSubmission.submission,
701
- [element.name]: typeof value === 'function'
702
- ? value(currentFormSubmission.submission[element.name])
703
- : value,
704
- },
705
- lastElementUpdated: element,
706
- executedLookups: {
707
- ...currentFormSubmission.executedLookups,
708
- [element.name]: typeof executedLookups === 'function'
709
- ? executedLookups((_a = currentFormSubmission.executedLookups) === null || _a === void 0 ? void 0 : _a[element.name])
710
- : 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',
711
668
  },
712
- sectionState: sectionState
713
- ? typeof sectionState === 'function'
714
- ? sectionState(currentFormSubmission.sectionState)
715
- : sectionState
716
- : currentFormSubmission.sectionState,
717
- };
718
- });
719
- }
669
+ ];
670
+ }
671
+ return {
672
+ ...currentFormSubmission,
673
+ sectionState: newSectionState,
674
+ };
675
+ });
676
+ return;
720
677
  }
721
- }, [disabled, setFormSubmission]);
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]);
722
708
  // #endregion
723
709
  //
724
710
  //
@@ -768,58 +754,60 @@ function OneBlinkFormBase({ googleMapsApiKey, abnLookupAuthenticationGuid, captc
768
754
  if (conditionalLogicError) {
769
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()) })] }) }));
770
756
  }
771
- 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', {
772
- 'is-showing-pages': isShowingMultiplePages,
773
- }), 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', {
774
- 'is-active': isStepsHeaderActive,
775
- }), children: [_jsxs(Clickable, { className: clsx('ob-steps-navigation__header', {
776
- 'is-active': isStepsHeaderActive,
777
- }), 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', {
778
- 'is-active': isStepsHeaderActive,
779
- }), children: _jsx("div", { className: "steps is-small is-horizontal-tablet cypress-steps", children: visiblePages.map((page, index) => {
780
- const hasErrors = checkDisplayPageError(page);
781
- 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
782
- ? 'step'
783
- : undefined, className: clsx('step-item cypress-step-item', {
784
- 'is-active': currentPage.id === page.id,
785
- 'is-completed': currentPageIndex > index,
786
- 'is-error': hasErrors,
787
- }), onClick: (e) => {
788
- e.stopPropagation();
789
- if (page.id !== currentPage.id) {
790
- setPageId(page.id);
791
- }
792
- }, children: [_jsx("div", { className: "step-marker step-marker-error ob-step-marker cypress-step-marker",
793
- // @ts-expect-error ???
794
- 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));
795
- }) }) })] })), _jsx("div", { className: clsx('ob-steps-navigation__background', {
796
- 'is-active': isStepsHeaderActive,
797
- }), onClick: toggleStepsNavigation }), _jsxs("div", { className: "steps", children: [_jsx("div", { className: clsx('steps-content', {
798
- 'is-single-step': !isShowingMultiplePages,
799
- }), 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 ===
800
- currentPage.id, formId: definition.id, formElementsConditionallyShown: formElementsConditionallyShown, formElementsValidation: formElementsValidation, displayValidationMessages: hasAttemptedSubmit ||
801
- 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', {
802
- 'is-active': currentPage.id === page.id,
803
- 'is-completed': currentPageIndex > index,
804
- 'has-background-danger': currentPage.id !== page.id &&
805
- checkDisplayPageError(page),
806
- }) }, 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
807
- ? ''
808
- : '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 }, {
809
- 'ob-button-submit-is-disabled': submissionConditionallyEnabled,
810
- }), disabled: isPreview ||
811
- disabled ||
812
- isPreparingToSubmit ||
813
- !submissionConditionallyEnabled, children: _jsx(CustomisableButtonInner, { label: isInfoPage
814
- ? 'Done'
815
- : ((_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 &&
816
- (editableFormElementIds !== undefined || !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) ||
817
- '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) ||
818
- '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) || '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) => {
819
- setPromptOfflineSubmissionAttempt(false);
820
- handleSubmit(e, false);
821
- }, 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 &&
822
- 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 }))] }) }) }) }) }) }) }) }));
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 }))] }) }) }) }) }) }) }) }) }));
823
811
  }
824
812
  export default React.memo(OneBlinkFormBase);
825
813
  //# sourceMappingURL=OneBlinkFormBase.js.map