@oneblink/apps-react 2.3.0-beta.2 → 2.3.0-beta.4
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/OneBlinkAutoSaveForm.d.ts +10 -10
- package/dist/OneBlinkAutoSaveForm.js +28 -28
- package/dist/OneBlinkForm.d.ts +11 -11
- package/dist/OneBlinkForm.js +11 -11
- package/dist/OneBlinkFormBase.d.ts +29 -28
- package/dist/OneBlinkFormBase.js +479 -472
- package/dist/OneBlinkFormBase.js.map +1 -1
- package/dist/OneBlinkReadOnlyForm.d.ts +11 -11
- package/dist/OneBlinkReadOnlyForm.js +48 -48
- package/dist/components/CopyToClipboardIconButton.d.ts +10 -10
- package/dist/components/CopyToClipboardIconButton.js +32 -32
- package/dist/components/CustomAccordion.d.ts +27 -27
- package/dist/components/CustomAccordion.js +37 -37
- package/dist/components/ErrorSnackbar.d.ts +8 -8
- package/dist/components/ErrorSnackbar.js +25 -25
- package/dist/components/Lists.d.ts +25 -25
- package/dist/components/Lists.js +44 -44
- package/dist/components/LoadingWithMessage.d.ts +6 -6
- package/dist/components/LoadingWithMessage.js +11 -11
- package/dist/components/formStore/FormStoreTableProvider.d.ts +6 -6
- package/dist/components/formStore/FormStoreTableProvider.js +90 -90
- package/dist/components/formStore/OneBlinkFormStoreClearFiltersButton.d.ts +5 -5
- package/dist/components/formStore/OneBlinkFormStoreClearFiltersButton.js +19 -19
- package/dist/components/formStore/OneBlinkFormStoreColumnsButton.d.ts +5 -5
- package/dist/components/formStore/OneBlinkFormStoreColumnsButton.js +66 -66
- package/dist/components/formStore/OneBlinkFormStoreDownloadButton.d.ts +5 -5
- package/dist/components/formStore/OneBlinkFormStoreDownloadButton.js +86 -86
- package/dist/components/formStore/OneBlinkFormStoreProvider.d.ts +8 -8
- package/dist/components/formStore/OneBlinkFormStoreProvider.js +24 -24
- package/dist/components/formStore/OneBlinkFormStoreRefreshButton.d.ts +5 -5
- package/dist/components/formStore/OneBlinkFormStoreRefreshButton.js +11 -11
- package/dist/components/formStore/OneBlinkFormStoreTable.d.ts +4 -4
- package/dist/components/formStore/OneBlinkFormStoreTable.js +194 -194
- package/dist/components/formStore/display/ElementDisplay.d.ts +23 -23
- package/dist/components/formStore/display/ElementDisplay.js +77 -77
- package/dist/components/formStore/display/FormStoreIcon.d.ts +2 -2
- package/dist/components/formStore/display/FormStoreIcon.js +2 -2
- package/dist/components/formStore/table/ActionedByTableCell.d.ts +11 -11
- package/dist/components/formStore/table/ActionedByTableCell.js +43 -43
- package/dist/components/formStore/table/ColumnFilters.d.ts +9 -9
- package/dist/components/formStore/table/ColumnFilters.js +179 -179
- package/dist/components/formStore/table/FormElementTableCell.d.ts +10 -10
- package/dist/components/formStore/table/FormElementTableCell.js +228 -228
- package/dist/components/formStore/table/HeaderCellMoreButton.d.ts +9 -9
- package/dist/components/formStore/table/HeaderCellMoreButton.js +48 -48
- package/dist/components/formStore/table/RepeatableSetCell.d.ts +8 -8
- package/dist/components/formStore/table/RepeatableSetCell.js +62 -62
- package/dist/components/formStore/table/RepeatableSetCellAccordion.d.ts +9 -9
- package/dist/components/formStore/table/RepeatableSetCellAccordion.js +11 -11
- package/dist/components/formStore/table/TableCellCopyButton.d.ts +7 -7
- package/dist/components/formStore/table/TableCellCopyButton.js +27 -27
- package/dist/components/formStore/table/generateColumns.d.ts +24 -24
- package/dist/components/formStore/table/generateColumns.js +290 -290
- package/dist/components/formStore/table/useFormStoreTable.d.ts +52 -52
- package/dist/components/formStore/table/useFormStoreTable.js +157 -157
- package/dist/components/formStore/useFormStoreTableContext.d.ts +44 -44
- package/dist/components/formStore/useFormStoreTableContext.js +9 -9
- package/dist/components/messages/ErrorMessage.d.ts +12 -12
- package/dist/components/messages/ErrorMessage.js +12 -12
- package/dist/components/messages/LargeIconMessage.d.ts +18 -18
- package/dist/components/messages/LargeIconMessage.js +33 -33
- package/dist/components/messages/NoResourcesYet.d.ts +11 -11
- package/dist/components/messages/NoResourcesYet.js +6 -6
- package/dist/components/pickers/V4CompatibleDatePicker.d.ts +32 -32
- package/dist/components/pickers/V4CompatibleDatePicker.js +70 -70
- package/dist/components/pickers/V4CompatibleDateTimePicker.d.ts +32 -32
- package/dist/components/pickers/V4CompatibleDateTimePicker.js +70 -70
- package/dist/components/pickers/V4CompatibleTimePicker.d.ts +28 -28
- package/dist/components/pickers/V4CompatibleTimePicker.js +53 -53
- package/dist/components/renderer/AnnotationModal.d.ts +8 -8
- package/dist/components/renderer/AnnotationModal.js +101 -101
- package/dist/components/renderer/AutocompleteDropdown.d.ts +26 -26
- package/dist/components/renderer/AutocompleteDropdown.js +175 -175
- package/dist/components/renderer/CopyToClipboardButton.d.ts +8 -8
- package/dist/components/renderer/CopyToClipboardButton.js +13 -13
- package/dist/components/renderer/CustomisableButtonInner.d.ts +7 -7
- package/dist/components/renderer/CustomisableButtonInner.js +8 -8
- package/dist/components/renderer/FormElementLabelContainer.d.ts +12 -12
- package/dist/components/renderer/FormElementLabelContainer.js +15 -15
- package/dist/components/renderer/FormElementOptions.d.ts +9 -9
- package/dist/components/renderer/FormElementOptions.js +14 -14
- package/dist/components/renderer/LookupButton.d.ts +10 -10
- package/dist/components/renderer/LookupButton.js +29 -29
- package/dist/components/renderer/LookupNotification.d.ts +12 -12
- package/dist/components/renderer/LookupNotification.js +230 -230
- package/dist/components/renderer/Modal.d.ts +14 -14
- package/dist/components/renderer/Modal.js +14 -14
- package/dist/components/renderer/OnLoading.d.ts +10 -10
- package/dist/components/renderer/OnLoading.js +11 -11
- package/dist/components/renderer/OneBlinkAppsErrorOriginalMessage.d.ts +7 -7
- package/dist/components/renderer/OneBlinkAppsErrorOriginalMessage.js +12 -12
- package/dist/components/renderer/OneBlinkFormElements.d.ts +19 -19
- package/dist/components/renderer/OneBlinkFormElements.js +202 -202
- package/dist/components/renderer/PageFormElements.d.ts +17 -17
- package/dist/components/renderer/PageFormElements.js +48 -48
- package/dist/components/renderer/ProgressBar.d.ts +7 -7
- package/dist/components/renderer/ProgressBar.js +6 -6
- package/dist/components/renderer/ProgressBar.js.map +1 -1
- package/dist/components/renderer/ToggleAllCheckbox.d.ts +13 -13
- package/dist/components/renderer/ToggleAllCheckbox.js +26 -26
- package/dist/components/renderer/attachments/AttachmentStatus.d.ts +10 -10
- package/dist/components/renderer/attachments/AttachmentStatus.js +36 -36
- package/dist/components/renderer/attachments/FileCard.d.ts +19 -19
- package/dist/components/renderer/attachments/FileCard.js +60 -60
- package/dist/components/renderer/attachments/FileCardContent.d.ts +5 -5
- package/dist/components/renderer/attachments/FileCardContent.js +10 -10
- package/dist/components/renderer/attachments/ImagePreviewUnavailable.d.ts +4 -4
- package/dist/components/renderer/attachments/ImagePreviewUnavailable.js +11 -11
- package/dist/components/renderer/attachments/ProgressBar.d.ts +8 -8
- package/dist/components/renderer/attachments/ProgressBar.js +33 -33
- package/dist/form-elements/ComplianceButton.d.ts +10 -10
- package/dist/form-elements/ComplianceButton.js +11 -11
- package/dist/form-elements/FormElementABN.d.ts +14 -14
- package/dist/form-elements/FormElementABN.js +155 -155
- package/dist/form-elements/FormElementAutocomplete.d.ts +19 -19
- package/dist/form-elements/FormElementAutocomplete.js +81 -81
- package/dist/form-elements/FormElementBSB.d.ts +18 -18
- package/dist/form-elements/FormElementBSB.js +100 -100
- package/dist/form-elements/FormElementBarcodeScanner.d.ts +14 -14
- package/dist/form-elements/FormElementBarcodeScanner.js +306 -306
- package/dist/form-elements/FormElementBoolean.d.ts +14 -14
- package/dist/form-elements/FormElementBoolean.js +16 -16
- package/dist/form-elements/FormElementCalculation.d.ts +11 -11
- package/dist/form-elements/FormElementCalculation.js +179 -179
- package/dist/form-elements/FormElementCamera.d.ts +15 -15
- package/dist/form-elements/FormElementCamera.js +227 -227
- package/dist/form-elements/FormElementCaptcha.d.ts +12 -12
- package/dist/form-elements/FormElementCaptcha.js +14 -14
- package/dist/form-elements/FormElementCheckBoxes.d.ts +15 -15
- package/dist/form-elements/FormElementCheckBoxes.js +64 -64
- package/dist/form-elements/FormElementCivicaNameRecord.d.ts +8 -8
- package/dist/form-elements/FormElementCivicaNameRecord.js +51 -51
- package/dist/form-elements/FormElementCivicaStreetName.d.ts +15 -15
- package/dist/form-elements/FormElementCivicaStreetName.js +38 -38
- package/dist/form-elements/FormElementCompliance.d.ts +22 -22
- package/dist/form-elements/FormElementCompliance.js +129 -129
- package/dist/form-elements/FormElementDate.d.ts +14 -14
- package/dist/form-elements/FormElementDate.js +74 -74
- package/dist/form-elements/FormElementDateTime.d.ts +14 -14
- package/dist/form-elements/FormElementDateTime.js +67 -67
- package/dist/form-elements/FormElementEmail.d.ts +14 -14
- package/dist/form-elements/FormElementEmail.js +22 -22
- package/dist/form-elements/FormElementFile.d.ts +13 -13
- package/dist/form-elements/FormElementFile.js +31 -31
- package/dist/form-elements/FormElementFiles.d.ts +15 -15
- package/dist/form-elements/FormElementFiles.js +42 -42
- package/dist/form-elements/FormElementForm.d.ts +17 -17
- package/dist/form-elements/FormElementForm.js +63 -63
- package/dist/form-elements/FormElementFreshdeskDependentField.d.ts +8 -8
- package/dist/form-elements/FormElementFreshdeskDependentField.js +15 -15
- package/dist/form-elements/FormElementGeoscapeAddress.d.ts +15 -15
- package/dist/form-elements/FormElementGeoscapeAddress.js +62 -62
- package/dist/form-elements/FormElementHTML.d.ts +8 -8
- package/dist/form-elements/FormElementHTML.js +15 -15
- package/dist/form-elements/FormElementHeading.d.ts +8 -8
- package/dist/form-elements/FormElementHeading.js +23 -23
- package/dist/form-elements/FormElementImage.d.ts +8 -8
- package/dist/form-elements/FormElementImage.js +6 -6
- package/dist/form-elements/FormElementLocation.d.ts +20 -20
- package/dist/form-elements/FormElementLocation.js +204 -204
- package/dist/form-elements/FormElementNumber.d.ts +14 -14
- package/dist/form-elements/FormElementNumber.js +72 -72
- package/dist/form-elements/FormElementPointAddress.d.ts +15 -15
- package/dist/form-elements/FormElementPointAddress.js +69 -69
- package/dist/form-elements/FormElementRadio.d.ts +15 -15
- package/dist/form-elements/FormElementRadio.js +41 -41
- package/dist/form-elements/FormElementRepeatableSet.d.ts +19 -19
- package/dist/form-elements/FormElementRepeatableSet.js +126 -126
- package/dist/form-elements/FormElementSection.d.ts +8 -8
- package/dist/form-elements/FormElementSection.js +69 -69
- package/dist/form-elements/FormElementSelect.d.ts +15 -15
- package/dist/form-elements/FormElementSelect.js +44 -44
- package/dist/form-elements/FormElementSignature.d.ts +15 -15
- package/dist/form-elements/FormElementSignature.js +138 -138
- package/dist/form-elements/FormElementSummary.d.ts +11 -11
- package/dist/form-elements/FormElementSummary.js +159 -159
- package/dist/form-elements/FormElementTelephone.d.ts +14 -14
- package/dist/form-elements/FormElementTelephone.js +22 -22
- package/dist/form-elements/FormElementText.d.ts +14 -14
- package/dist/form-elements/FormElementText.js +29 -29
- package/dist/form-elements/FormElementTextarea.d.ts +14 -14
- package/dist/form-elements/FormElementTextarea.js +30 -30
- package/dist/form-elements/FormElementTime.d.ts +14 -14
- package/dist/form-elements/FormElementTime.js +53 -53
- package/dist/form-elements/OptionButton.d.ts +11 -11
- package/dist/form-elements/OptionButton.js +9 -9
- package/dist/hooks/attachments/useAttachment.d.ts +12 -12
- package/dist/hooks/attachments/useAttachment.js +242 -242
- package/dist/hooks/attachments/useAttachmentBlobs.d.ts +19 -19
- package/dist/hooks/attachments/useAttachmentBlobs.js +23 -23
- package/dist/hooks/attachments/useAttachments.d.ts +10 -10
- package/dist/hooks/attachments/useAttachments.js +69 -69
- package/dist/hooks/useAbnLookupAuthenticationGuid.d.ts +3 -3
- package/dist/hooks/useAbnLookupAuthenticationGuid.js +5 -5
- package/dist/hooks/useAuth.d.ts +15 -15
- package/dist/hooks/useAuth.js +42 -42
- package/dist/hooks/useBooleanState.d.ts +5 -5
- package/dist/hooks/useBooleanState.js +8 -8
- package/dist/hooks/useCaptchaSiteKey.d.ts +3 -3
- package/dist/hooks/useCaptchaSiteKey.js +5 -5
- package/dist/hooks/useClickOutsideElement.d.ts +3 -3
- package/dist/hooks/useClickOutsideElement.js +14 -14
- package/dist/hooks/useConditionalLogic.d.ts +6 -6
- package/dist/hooks/useConditionalLogic.js +22 -22
- package/dist/hooks/useContrastColor.d.ts +2 -2
- package/dist/hooks/useContrastColor.js +12 -12
- package/dist/hooks/useDynamicOptionsLoaderState.d.ts +7 -7
- package/dist/hooks/useDynamicOptionsLoaderState.js +44 -44
- package/dist/hooks/useExecutedLookupCallback.d.ts +12 -12
- package/dist/hooks/useExecutedLookupCallback.js +15 -15
- package/dist/hooks/useFlatpickr.d.ts +10 -10
- package/dist/hooks/useFlatpickr.js +73 -73
- package/dist/hooks/useFlatpickrGuid.d.ts +7 -7
- package/dist/hooks/useFlatpickrGuid.js +11 -11
- package/dist/hooks/useFlattenElementsContext.d.ts +2 -2
- package/dist/hooks/useFlattenElementsContext.js +7 -7
- package/dist/hooks/useFormDefinition.d.ts +4 -4
- package/dist/hooks/useFormDefinition.js +9 -9
- package/dist/hooks/useFormElementOptions.d.ts +9 -9
- package/dist/hooks/useFormElementOptions.js +35 -35
- package/dist/hooks/useFormIsReadOnly.d.ts +3 -3
- package/dist/hooks/useFormIsReadOnly.js +5 -5
- package/dist/hooks/useFormSubmissionAutoSaveState.d.ts +24 -24
- package/dist/hooks/useFormSubmissionAutoSaveState.js +145 -145
- package/dist/hooks/useFormSubmissionModelContext.d.ts +15 -15
- package/dist/hooks/useFormSubmissionModelContext.js +32 -32
- package/dist/hooks/useFormSubmissionState.d.ts +10 -10
- package/dist/hooks/useFormSubmissionState.js +13 -13
- package/dist/hooks/useFormValidation.d.ts +7 -7
- package/dist/hooks/useFormValidation.js +29 -29
- package/dist/hooks/useGoogleMapsApiKey.d.ts +3 -3
- package/dist/hooks/useGoogleMapsApiKey.js +5 -5
- package/dist/hooks/useInfiniteScrollDataLoad.d.ts +30 -30
- package/dist/hooks/useInfiniteScrollDataLoad.js +124 -124
- package/dist/hooks/useInjectPages.d.ts +7 -7
- package/dist/hooks/useInjectPages.js +5 -5
- package/dist/hooks/useIsHovering.d.ts +5 -5
- package/dist/hooks/useIsHovering.js +12 -12
- package/dist/hooks/useIsMounted.d.ts +3 -3
- package/dist/hooks/useIsMounted.js +11 -11
- package/dist/hooks/useIsOffline.d.ts +6 -6
- package/dist/hooks/useIsOffline.js +26 -26
- package/dist/hooks/useIsPageVisible.d.ts +9 -9
- package/dist/hooks/useIsPageVisible.js +8 -8
- package/dist/hooks/useLoadDataState.d.ts +15 -15
- package/dist/hooks/useLoadDataState.js +54 -54
- package/dist/hooks/useLogin.d.ts +46 -46
- package/dist/hooks/useLogin.js +295 -295
- package/dist/hooks/useLookupNotification.d.ts +9 -9
- package/dist/hooks/useLookupNotification.js +10 -10
- package/dist/hooks/useLookups.d.ts +5 -5
- package/dist/hooks/useLookups.js +62 -62
- package/dist/hooks/useNullableState.d.ts +2 -2
- package/dist/hooks/useNullableState.js +6 -6
- package/dist/hooks/usePages.d.ts +24 -24
- package/dist/hooks/usePages.js +141 -141
- package/dist/hooks/useQuery.d.ts +2 -2
- package/dist/hooks/useQuery.js +7 -7
- package/dist/hooks/useSubmissionIdIsValid.d.ts +3 -3
- package/dist/hooks/useSubmissionIdIsValid.js +19 -19
- package/dist/hooks/useToggleComplianceChildren.d.ts +3 -3
- package/dist/hooks/useToggleComplianceChildren.js +13 -13
- package/dist/index.d.ts +23 -23
- package/dist/index.js +23 -23
- package/dist/services/attachments.d.ts +10 -10
- package/dist/services/attachments.js +72 -72
- package/dist/services/barcode-readers/quagger.d.ts +1 -1
- package/dist/services/barcode-readers/quagger.js +34 -34
- package/dist/services/blob-utils.d.ts +5 -5
- package/dist/services/blob-utils.js +73 -73
- package/dist/services/checkBsbsAreInvalid.d.ts +3 -3
- package/dist/services/checkBsbsAreInvalid.js +40 -40
- package/dist/services/checkIfAttachmentsExist.d.ts +5 -5
- package/dist/services/checkIfAttachmentsExist.js +144 -144
- package/dist/services/checkIfBsbsAreValidating.d.ts +3 -3
- package/dist/services/checkIfBsbsAreValidating.js +40 -40
- package/dist/services/cleanFormSubmissionModel.d.ts +6 -6
- package/dist/services/cleanFormSubmissionModel.js +203 -203
- package/dist/services/defaultCoordinates.d.ts +5 -5
- package/dist/services/defaultCoordinates.js +8 -8
- package/dist/services/download-file.d.ts +3 -3
- package/dist/services/download-file.js +90 -90
- package/dist/services/drawTimestampOnCanvas.d.ts +1 -1
- package/dist/services/drawTimestampOnCanvas.js +22 -22
- package/dist/services/form-validation.d.ts +10 -10
- package/dist/services/form-validation.js +561 -561
- package/dist/services/generate-default-data.d.ts +13 -13
- package/dist/services/generate-default-data.js +494 -494
- package/dist/services/generateCivicaNameRecordElements.d.ts +2 -2
- package/dist/services/generateCivicaNameRecordElements.js +140 -140
- package/dist/services/generateFreshdeskDependentFieldElements.d.ts +2 -2
- package/dist/services/generateFreshdeskDependentFieldElements.js +69 -69
- package/dist/services/sanitize-html.d.ts +2 -2
- package/dist/services/sanitize-html.js +20 -20
- package/dist/services/scrolling-service.d.ts +7 -7
- package/dist/services/scrolling-service.js +38 -38
- package/dist/services/utils-service.d.ts +5 -5
- package/dist/services/utils-service.js +16 -16
- package/dist/types/attachments.d.ts +19 -19
- package/dist/types/attachments.js +1 -1
- package/dist/types/form.d.ts +40 -40
- package/dist/types/form.js +2 -2
- package/package.json +2 -2
- package/dist/OneBlinkFormStoreView.d.ts +0 -8
- package/dist/OneBlinkFormStoreView.js +0 -55
- package/dist/OneBlinkFormStoreView.js.map +0 -1
- package/dist/components/AnnotationModal.d.ts +0 -8
- package/dist/components/AnnotationModal.js +0 -104
- package/dist/components/AnnotationModal.js.map +0 -1
- package/dist/components/AutocompleteDropdown.d.ts +0 -26
- package/dist/components/AutocompleteDropdown.js +0 -174
- package/dist/components/AutocompleteDropdown.js.map +0 -1
- package/dist/components/CopyToClipboardButton.d.ts +0 -9
- package/dist/components/CopyToClipboardButton.js +0 -14
- package/dist/components/CopyToClipboardButton.js.map +0 -1
- package/dist/components/CustomisableButtonInner.d.ts +0 -7
- package/dist/components/CustomisableButtonInner.js +0 -9
- package/dist/components/CustomisableButtonInner.js.map +0 -1
- package/dist/components/ErrorMessage.d.ts +0 -13
- package/dist/components/ErrorMessage.js +0 -13
- package/dist/components/ErrorMessage.js.map +0 -1
- package/dist/components/FormElementLabelContainer.d.ts +0 -12
- package/dist/components/FormElementLabelContainer.js +0 -16
- package/dist/components/FormElementLabelContainer.js.map +0 -1
- package/dist/components/FormElementOptions.d.ts +0 -9
- package/dist/components/FormElementOptions.js +0 -15
- package/dist/components/FormElementOptions.js.map +0 -1
- package/dist/components/LookupButton.d.ts +0 -10
- package/dist/components/LookupButton.js +0 -30
- package/dist/components/LookupButton.js.map +0 -1
- package/dist/components/LookupNotification.d.ts +0 -12
- package/dist/components/LookupNotification.js +0 -231
- package/dist/components/LookupNotification.js.map +0 -1
- package/dist/components/Modal.d.ts +0 -14
- package/dist/components/Modal.js +0 -15
- package/dist/components/Modal.js.map +0 -1
- package/dist/components/NoResourcesYet.d.ts +0 -12
- package/dist/components/NoResourcesYet.js +0 -7
- package/dist/components/NoResourcesYet.js.map +0 -1
- package/dist/components/OnLoading.d.ts +0 -10
- package/dist/components/OnLoading.js +0 -12
- package/dist/components/OnLoading.js.map +0 -1
- package/dist/components/OneBlinkAppsErrorOriginalMessage.d.ts +0 -7
- package/dist/components/OneBlinkAppsErrorOriginalMessage.js +0 -13
- package/dist/components/OneBlinkAppsErrorOriginalMessage.js.map +0 -1
- package/dist/components/OneBlinkFormElements.d.ts +0 -19
- package/dist/components/OneBlinkFormElements.js +0 -196
- package/dist/components/OneBlinkFormElements.js.map +0 -1
- package/dist/components/PageFormElements.d.ts +0 -17
- package/dist/components/PageFormElements.js +0 -49
- package/dist/components/PageFormElements.js.map +0 -1
- package/dist/components/ToggleAllCheckbox.d.ts +0 -13
- package/dist/components/ToggleAllCheckbox.js +0 -27
- package/dist/components/ToggleAllCheckbox.js.map +0 -1
- package/dist/components/attachments/AttachmentStatus.d.ts +0 -12
- package/dist/components/attachments/AttachmentStatus.js +0 -35
- package/dist/components/attachments/AttachmentStatus.js.map +0 -1
- package/dist/components/attachments/FileCard.d.ts +0 -18
- package/dist/components/attachments/FileCard.js +0 -58
- package/dist/components/attachments/FileCard.js.map +0 -1
- package/dist/components/attachments/FileCardContent.d.ts +0 -5
- package/dist/components/attachments/FileCardContent.js +0 -11
- package/dist/components/attachments/FileCardContent.js.map +0 -1
- package/dist/components/attachments/Files.d.ts +0 -14
- package/dist/components/attachments/Files.js +0 -27
- package/dist/components/attachments/Files.js.map +0 -1
- package/dist/components/attachments/ImagePreviewUnavailable.d.ts +0 -4
- package/dist/components/attachments/ImagePreviewUnavailable.js +0 -12
- package/dist/components/attachments/ImagePreviewUnavailable.js.map +0 -1
- package/dist/components/attachments/UploadingAttachment.d.ts +0 -4
- package/dist/components/attachments/UploadingAttachment.js +0 -13
- package/dist/components/attachments/UploadingAttachment.js.map +0 -1
- package/dist/components/formStore/ColumnsConfigurationButton.d.ts +0 -10
- package/dist/components/formStore/ColumnsConfigurationButton.js +0 -29
- package/dist/components/formStore/ColumnsConfigurationButton.js.map +0 -1
- package/dist/components/formStore/DownloadSubmissionDataButton.d.ts +0 -13
- package/dist/components/formStore/DownloadSubmissionDataButton.js +0 -45
- package/dist/components/formStore/DownloadSubmissionDataButton.js.map +0 -1
- package/dist/components/formStore/FormStore.d.ts +0 -9
- package/dist/components/formStore/FormStore.js +0 -103
- package/dist/components/formStore/FormStore.js.map +0 -1
- package/dist/components/formStore/table/index.d.ts +0 -17
- package/dist/components/formStore/table/index.js +0 -194
- package/dist/components/formStore/table/index.js.map +0 -1
- package/dist/components/renderer/attachments/Files.d.ts +0 -14
- package/dist/components/renderer/attachments/Files.js +0 -27
- package/dist/components/renderer/attachments/Files.js.map +0 -1
- package/dist/components/renderer/attachments/UploadingAttachment.d.ts +0 -4
- package/dist/components/renderer/attachments/UploadingAttachment.js +0 -13
- package/dist/components/renderer/attachments/UploadingAttachment.js.map +0 -1
- package/dist/form-elements/FormElementFiles/FormElementFile.d.ts +0 -13
- package/dist/form-elements/FormElementFiles/FormElementFile.js +0 -32
- package/dist/form-elements/FormElementFiles/FormElementFile.js.map +0 -1
- package/dist/form-elements/FormElementFiles/FormElementFileDisplay.d.ts +0 -10
- package/dist/form-elements/FormElementFiles/FormElementFileDisplay.js +0 -11
- package/dist/form-elements/FormElementFiles/FormElementFileDisplay.js.map +0 -1
- package/dist/form-elements/FormElementFiles/FormElementFiles.d.ts +0 -15
- package/dist/form-elements/FormElementFiles/FormElementFiles.js +0 -17
- package/dist/form-elements/FormElementFiles/FormElementFiles.js.map +0 -1
- package/dist/form-elements/FormElementFiles/FormElementFilesInvalidAttachment.d.ts +0 -7
- package/dist/form-elements/FormElementFiles/FormElementFilesInvalidAttachment.js +0 -11
- package/dist/form-elements/FormElementFiles/FormElementFilesInvalidAttachment.js.map +0 -1
- package/dist/form-elements/FormElementFiles/index.d.ts +0 -17
- package/dist/form-elements/FormElementFiles/index.js +0 -18
- package/dist/form-elements/FormElementFiles/index.js.map +0 -1
- package/dist/form-elements/FormElementFiles/legacy/FormElementFiles.d.ts +0 -18
- package/dist/form-elements/FormElementFiles/legacy/FormElementFiles.js +0 -61
- package/dist/form-elements/FormElementFiles/legacy/FormElementFiles.js.map +0 -1
- package/dist/hooks/attachments/useAttachmentObjectURLs.d.ts +0 -24
- package/dist/hooks/attachments/useAttachmentObjectURLs.js +0 -37
- package/dist/hooks/attachments/useAttachmentObjectURLs.js.map +0 -1
- package/dist/hooks/attachments/useLocalAttachmentBlobs.d.ts +0 -24
- package/dist/hooks/attachments/useLocalAttachmentBlobs.js +0 -40
- package/dist/hooks/attachments/useLocalAttachmentBlobs.js.map +0 -1
- package/dist/hooks/useButtonsConfiguration.d.ts +0 -45
- package/dist/hooks/useButtonsConfiguration.js +0 -6
- package/dist/hooks/useButtonsConfiguration.js.map +0 -1
- package/dist/hooks/useChangeEffect.d.ts +0 -1
- package/dist/hooks/useChangeEffect.js +0 -14
- package/dist/hooks/useChangeEffect.js.map +0 -1
- package/dist/hooks/useConditionallyShowOptionCallback.d.ts +0 -5
- package/dist/hooks/useConditionallyShowOptionCallback.js +0 -20
- package/dist/hooks/useConditionallyShowOptionCallback.js.map +0 -1
- package/dist/hooks/useCustomValidation.d.ts +0 -1
- package/dist/hooks/useCustomValidation.js +0 -9
- package/dist/hooks/useCustomValidation.js.map +0 -1
- package/dist/hooks/useDynamicOptionsLoaderEffect.d.ts +0 -7
- package/dist/hooks/useDynamicOptionsLoaderEffect.js +0 -45
- package/dist/hooks/useDynamicOptionsLoaderEffect.js.map +0 -1
- package/dist/hooks/useLegacyElements.d.ts +0 -16
- package/dist/hooks/useLegacyElements.js +0 -55
- package/dist/hooks/useLegacyElements.js.map +0 -1
- package/dist/hooks/useToggleAll.d.ts +0 -6
- package/dist/hooks/useToggleAll.js +0 -24
- package/dist/hooks/useToggleAll.js.map +0 -1
- package/dist/services/checkIfAttachmentsAreUploading.d.ts +0 -3
- package/dist/services/checkIfAttachmentsAreUploading.js +0 -58
- package/dist/services/checkIfAttachmentsAreUploading.js.map +0 -1
- package/dist/services/clean-form-elements-ctrl-model.d.ts +0 -4
- package/dist/services/clean-form-elements-ctrl-model.js +0 -166
- package/dist/services/clean-form-elements-ctrl-model.js.map +0 -1
- package/dist/services/conditionally-show-element.d.ts +0 -11
- package/dist/services/conditionally-show-element.js +0 -92
- package/dist/services/conditionally-show-element.js.map +0 -1
- package/dist/services/conditionally-show-option.d.ts +0 -3
- package/dist/services/conditionally-show-option.js +0 -135
- package/dist/services/conditionally-show-option.js.map +0 -1
- package/dist/services/flattenFormElements.d.ts +0 -2
- package/dist/services/flattenFormElements.js +0 -13
- package/dist/services/flattenFormElements.js.map +0 -1
- package/dist/services/getCorrectDateFromDateOnlyString.d.ts +0 -2
- package/dist/services/getCorrectDateFromDateOnlyString.js +0 -4
- package/dist/services/getCorrectDateFromDateOnlyString.js.map +0 -1
- package/dist/styles/boolean.scss +0 -12
- package/dist/styles/ob-file.scss +0 -63
@@ -1,562 +1,562 @@
|
|
1
|
-
import validate from 'validate.js';
|
2
|
-
import { localisationService } from '@oneblink/apps';
|
3
|
-
import { parseDateValue } from './generate-default-data';
|
4
|
-
import generateCivicaNameRecordElements from './generateCivicaNameRecordElements';
|
5
|
-
import generateFreshdeskDependentFieldElements from './generateFreshdeskDependentFieldElements';
|
6
|
-
export const lookupValidationMessage = 'Lookup is required';
|
7
|
-
// https://validatejs.org/#validators-datetime
|
8
|
-
// Before using it we must add the parse and format functions
|
9
|
-
// Here is a sample implementation using moment.js
|
10
|
-
validate.extend(validate.validators.datetime, {
|
11
|
-
// The value is guaranteed not to be null or undefined but otherwise it
|
12
|
-
// could be anything.
|
13
|
-
parse: function (value) {
|
14
|
-
return Date.parse(value);
|
15
|
-
},
|
16
|
-
// Input is a unix timestamp
|
17
|
-
format: function (value, options) {
|
18
|
-
const dateValue = new Date(value);
|
19
|
-
return options.format(dateValue);
|
20
|
-
},
|
21
|
-
});
|
22
|
-
validate.validators.entries = function (value, { setSchema, entrySchema, }) {
|
23
|
-
const entries = Array.isArray(value) ? value : [];
|
24
|
-
const entryErrors = entries.reduce((errorsByIndex, entry, index) => {
|
25
|
-
const entryValidation = validateSingleMessageError(entry, entrySchema);
|
26
|
-
if (entryValidation) {
|
27
|
-
errorsByIndex[index] = entryValidation;
|
28
|
-
}
|
29
|
-
return errorsByIndex;
|
30
|
-
}, {});
|
31
|
-
const setErrorMessages = validate.single(value, setSchema);
|
32
|
-
if (!setErrorMessages && validate.isEmpty(entryErrors)) {
|
33
|
-
return;
|
34
|
-
}
|
35
|
-
return {
|
36
|
-
type: 'repeatableSet',
|
37
|
-
set: setErrorMessages && setErrorMessages[0],
|
38
|
-
entries: entryErrors,
|
39
|
-
};
|
40
|
-
};
|
41
|
-
validate.validators.nestedElements = function (value, schema) {
|
42
|
-
const errors = validateSingleMessageError(value || {}, schema);
|
43
|
-
if (!errors) {
|
44
|
-
return;
|
45
|
-
}
|
46
|
-
return {
|
47
|
-
type: 'formElements',
|
48
|
-
formElements: errors,
|
49
|
-
};
|
50
|
-
};
|
51
|
-
function getInvalidAttachment(value) {
|
52
|
-
if (value &&
|
53
|
-
typeof value === 'object' &&
|
54
|
-
value.type &&
|
55
|
-
value.type === 'ERROR') {
|
56
|
-
return value;
|
57
|
-
}
|
58
|
-
}
|
59
|
-
function validateAttachments(value) {
|
60
|
-
const invalidAttachmentNames = value === null || value === void 0 ? void 0 : value.reduce((invalidAttachmentNames, att) => {
|
61
|
-
var _a;
|
62
|
-
const attachmentName = (_a = getInvalidAttachment(att)) === null || _a === void 0 ? void 0 : _a.fileName;
|
63
|
-
if (attachmentName) {
|
64
|
-
invalidAttachmentNames.push(attachmentName);
|
65
|
-
}
|
66
|
-
return invalidAttachmentNames;
|
67
|
-
}, []);
|
68
|
-
if (invalidAttachmentNames === null || invalidAttachmentNames === void 0 ? void 0 : invalidAttachmentNames.length) {
|
69
|
-
return `${invalidAttachmentNames.join(', ')} could not be uploaded.`;
|
70
|
-
}
|
71
|
-
}
|
72
|
-
validate.validators.attachment = function (value) {
|
73
|
-
var _a;
|
74
|
-
return (_a = getInvalidAttachment(value)) === null || _a === void 0 ? void 0 : _a.errorMessage;
|
75
|
-
};
|
76
|
-
validate.validators.attachments = function (value) {
|
77
|
-
if (Array.isArray(value)) {
|
78
|
-
return validateAttachments(value);
|
79
|
-
}
|
80
|
-
return validateAttachments(value === null || value === void 0 ? void 0 : value.files);
|
81
|
-
};
|
82
|
-
// Extend validator for lookups
|
83
|
-
validate.validators.lookups = function (value, { elementIdsWithLookupsExecuted, formElement, }) {
|
84
|
-
if (!formElement.isDataLookup && !formElement.isElementLookup) {
|
85
|
-
return;
|
86
|
-
}
|
87
|
-
// Lookups must only be executed on required form elements
|
88
|
-
if (formElement && !formElement.required) {
|
89
|
-
return;
|
90
|
-
}
|
91
|
-
if (elementIdsWithLookupsExecuted.includes(formElement.id)) {
|
92
|
-
return;
|
93
|
-
}
|
94
|
-
return lookupValidationMessage;
|
95
|
-
};
|
96
|
-
validate.validators.numberRegex = function (value, format) {
|
97
|
-
if (!format) {
|
98
|
-
return;
|
99
|
-
}
|
100
|
-
if (typeof value === 'number' && !Number.isNaN(value)) {
|
101
|
-
value = value.toString();
|
102
|
-
}
|
103
|
-
const errorMessages = validate.single(value, { format });
|
104
|
-
return errorMessages && errorMessages[0];
|
105
|
-
};
|
106
|
-
validate.validators.isTrue = function (value, message) {
|
107
|
-
if (!value) {
|
108
|
-
return message || 'Must be set to true';
|
109
|
-
}
|
110
|
-
};
|
111
|
-
validate.validators.needsExtension = function (value, formElement) {
|
112
|
-
const isValid = !Array.isArray(value) ||
|
113
|
-
value.every((file) => {
|
114
|
-
return checkFileNameExtensionIsValid(formElement, file.fileName);
|
115
|
-
});
|
116
|
-
if (!isValid)
|
117
|
-
return 'All files must have extensions';
|
118
|
-
};
|
119
|
-
function getCustomRegexFormatConfig(formElement) {
|
120
|
-
return formElement.regexPattern
|
121
|
-
? {
|
122
|
-
pattern: formElement.regexPattern,
|
123
|
-
flags: formElement.regexFlags,
|
124
|
-
message: formElement.regexMessage,
|
125
|
-
}
|
126
|
-
: undefined;
|
127
|
-
}
|
128
|
-
export function validateSubmission(schema, submission, formElementsConditionallyShown) {
|
129
|
-
const formElementsValidation = validateSingleMessageError(submission, schema);
|
130
|
-
if (formElementsValidation) {
|
131
|
-
clearValidationMessagesForHiddenElements(formElementsValidation, formElementsConditionallyShown);
|
132
|
-
if (!validate.isEmpty(formElementsValidation)) {
|
133
|
-
return formElementsValidation;
|
134
|
-
}
|
135
|
-
}
|
136
|
-
}
|
137
|
-
const clearValidationMessagesForHiddenElements = (formElementsValidation, formElementsConditionallyShown) => {
|
138
|
-
// If there is no validation to check, there are no invalid elements
|
139
|
-
// If there is no conditionally shown elements, all invalid elements should display validation messages,
|
140
|
-
if (!formElementsValidation || !formElementsConditionallyShown) {
|
141
|
-
return;
|
142
|
-
}
|
143
|
-
for (const key in formElementsValidation) {
|
144
|
-
const formElementValidation = formElementsValidation[key];
|
145
|
-
if (!formElementValidation) {
|
146
|
-
continue;
|
147
|
-
}
|
148
|
-
const formElementConditionallyShown = formElementsConditionallyShown[key];
|
149
|
-
// If the validation is for an element that is being hidden,
|
150
|
-
// we can remove the validation message and move to the next validation
|
151
|
-
if (formElementConditionallyShown === null || formElementConditionallyShown === void 0 ? void 0 : formElementConditionallyShown.isHidden) {
|
152
|
-
delete formElementsValidation[key];
|
153
|
-
continue;
|
154
|
-
}
|
155
|
-
// If the validation is for a single element (not nested elements),
|
156
|
-
// we will always show the validation message
|
157
|
-
if (typeof formElementValidation === 'string') {
|
158
|
-
continue;
|
159
|
-
}
|
160
|
-
// Here we will check to see if the nested elements that are
|
161
|
-
// invalid are being shown, if not, remove validation messages
|
162
|
-
switch (formElementValidation.type) {
|
163
|
-
case 'repeatableSet': {
|
164
|
-
for (const index in formElementValidation.entries) {
|
165
|
-
clearValidationMessagesForHiddenElements(formElementValidation.entries[index], formElementConditionallyShown &&
|
166
|
-
formElementConditionallyShown.type === 'repeatableSet'
|
167
|
-
? formElementConditionallyShown.entries[index]
|
168
|
-
: undefined);
|
169
|
-
if (validate.isEmpty(formElementValidation.entries[index])) {
|
170
|
-
delete formElementValidation.entries[index];
|
171
|
-
}
|
172
|
-
}
|
173
|
-
// Remove the validation if all entries are valid and the set is also valid
|
174
|
-
if (validate.isEmpty(formElementValidation.entries) &&
|
175
|
-
!formElementValidation.set) {
|
176
|
-
delete formElementsValidation[key];
|
177
|
-
}
|
178
|
-
break;
|
179
|
-
}
|
180
|
-
case 'formElements': {
|
181
|
-
clearValidationMessagesForHiddenElements(formElementValidation.formElements, (formElementConditionallyShown === null || formElementConditionallyShown === void 0 ? void 0 : formElementConditionallyShown.type) === 'formElements'
|
182
|
-
? formElementConditionallyShown === null || formElementConditionallyShown === void 0 ? void 0 : formElementConditionallyShown.formElements
|
183
|
-
: undefined);
|
184
|
-
if (validate.isEmpty(formElementValidation.formElements)) {
|
185
|
-
delete formElementsValidation[key];
|
186
|
-
}
|
187
|
-
break;
|
188
|
-
}
|
189
|
-
}
|
190
|
-
}
|
191
|
-
};
|
192
|
-
const presence = ({ required, requiredMessage }, message) => (required ? { message: requiredMessage || message } : false);
|
193
|
-
const escapeElementName = (elementName) => {
|
194
|
-
const escapedName = elementName.replace(/\./g, '\\.');
|
195
|
-
return escapedName;
|
196
|
-
};
|
197
|
-
export function generateValidationSchema(elements, elementIdsWithLookupsExecuted) {
|
198
|
-
return elements.reduce((partialSchema, formElement) => {
|
199
|
-
switch (formElement.type) {
|
200
|
-
case 'summary':
|
201
|
-
case 'calculation':
|
202
|
-
case 'image':
|
203
|
-
case 'html':
|
204
|
-
case 'infoPage':
|
205
|
-
case 'heading': {
|
206
|
-
break;
|
207
|
-
}
|
208
|
-
case 'section':
|
209
|
-
case 'page': {
|
210
|
-
const nestedSchema = generateValidationSchema(formElement.elements, elementIdsWithLookupsExecuted);
|
211
|
-
Object.assign(partialSchema, nestedSchema);
|
212
|
-
break;
|
213
|
-
}
|
214
|
-
case 'draw': {
|
215
|
-
partialSchema[escapeElementName(formElement.name)] = {
|
216
|
-
attachment: true,
|
217
|
-
presence: presence(formElement, 'A signature is required'),
|
218
|
-
};
|
219
|
-
break;
|
220
|
-
}
|
221
|
-
case 'camera': {
|
222
|
-
partialSchema[escapeElementName(formElement.name)] = {
|
223
|
-
attachment: true,
|
224
|
-
presence: presence(formElement, 'A photo is required'),
|
225
|
-
};
|
226
|
-
break;
|
227
|
-
}
|
228
|
-
case 'captcha': {
|
229
|
-
partialSchema[escapeElementName(formElement.name)] = {
|
230
|
-
presence: presence({ ...formElement, required: true }, 'Please complete the CAPTCHA successfully'),
|
231
|
-
};
|
232
|
-
break;
|
233
|
-
}
|
234
|
-
case 'location': {
|
235
|
-
partialSchema[escapeElementName(formElement.name)] = {
|
236
|
-
presence: presence(formElement, 'Please select a location'),
|
237
|
-
lookups: {
|
238
|
-
formElement,
|
239
|
-
elementIdsWithLookupsExecuted,
|
240
|
-
},
|
241
|
-
};
|
242
|
-
break;
|
243
|
-
}
|
244
|
-
case 'compliance': {
|
245
|
-
partialSchema[escapeElementName(formElement.name)] = {
|
246
|
-
presence: presence(formElement, 'Required'),
|
247
|
-
lookups: {
|
248
|
-
formElement,
|
249
|
-
elementIdsWithLookupsExecuted,
|
250
|
-
},
|
251
|
-
attachments: true,
|
252
|
-
};
|
253
|
-
break;
|
254
|
-
}
|
255
|
-
case 'abn':
|
256
|
-
case 'geoscapeAddress':
|
257
|
-
case 'pointAddress':
|
258
|
-
case 'civicaStreetName':
|
259
|
-
case 'autocomplete':
|
260
|
-
case 'checkboxes':
|
261
|
-
case 'radio':
|
262
|
-
case 'select': {
|
263
|
-
partialSchema[escapeElementName(formElement.name)] = {
|
264
|
-
presence: presence(formElement, 'Required'),
|
265
|
-
lookups: {
|
266
|
-
formElement,
|
267
|
-
elementIdsWithLookupsExecuted,
|
268
|
-
},
|
269
|
-
};
|
270
|
-
break;
|
271
|
-
}
|
272
|
-
case 'boolean': {
|
273
|
-
partialSchema[escapeElementName(formElement.name)] = {
|
274
|
-
isTrue: formElement.required && 'Required',
|
275
|
-
lookups: {
|
276
|
-
formElement,
|
277
|
-
elementIdsWithLookupsExecuted,
|
278
|
-
},
|
279
|
-
};
|
280
|
-
break;
|
281
|
-
}
|
282
|
-
case 'bsb': {
|
283
|
-
partialSchema[escapeElementName(formElement.name)] = {
|
284
|
-
presence: presence(formElement, 'Please enter a BSB number'),
|
285
|
-
lookups: {
|
286
|
-
formElement,
|
287
|
-
elementIdsWithLookupsExecuted,
|
288
|
-
},
|
289
|
-
format: {
|
290
|
-
pattern: /\d{3}-\d{3}/,
|
291
|
-
message: 'Please enter a valid BSB number',
|
292
|
-
},
|
293
|
-
};
|
294
|
-
break;
|
295
|
-
}
|
296
|
-
case 'barcodeScanner': {
|
297
|
-
partialSchema[escapeElementName(formElement.name)] = {
|
298
|
-
presence: presence(formElement, 'Please scan a barcode or enter a value'),
|
299
|
-
lookups: {
|
300
|
-
formElement,
|
301
|
-
elementIdsWithLookupsExecuted,
|
302
|
-
},
|
303
|
-
format: getCustomRegexFormatConfig(formElement),
|
304
|
-
};
|
305
|
-
break;
|
306
|
-
}
|
307
|
-
case 'text':
|
308
|
-
case 'textarea': {
|
309
|
-
partialSchema[escapeElementName(formElement.name)] = {
|
310
|
-
presence: presence(formElement, 'Please enter a value'),
|
311
|
-
lookups: {
|
312
|
-
formElement,
|
313
|
-
elementIdsWithLookupsExecuted,
|
314
|
-
},
|
315
|
-
length: {
|
316
|
-
minimum: formElement.minLength,
|
317
|
-
tooShort: 'Please enter a value with at least %{count} character(s)',
|
318
|
-
maximum: formElement.maxLength,
|
319
|
-
tooLong: 'Please enter a value with %{count} character(s) or less',
|
320
|
-
},
|
321
|
-
format: getCustomRegexFormatConfig(formElement),
|
322
|
-
};
|
323
|
-
break;
|
324
|
-
}
|
325
|
-
case 'telephone': {
|
326
|
-
partialSchema[escapeElementName(formElement.name)] = {
|
327
|
-
presence: presence(formElement, 'Please enter a phone number'),
|
328
|
-
lookups: {
|
329
|
-
formElement,
|
330
|
-
elementIdsWithLookupsExecuted,
|
331
|
-
},
|
332
|
-
format: getCustomRegexFormatConfig(formElement),
|
333
|
-
};
|
334
|
-
break;
|
335
|
-
}
|
336
|
-
case 'email': {
|
337
|
-
partialSchema[escapeElementName(formElement.name)] = {
|
338
|
-
presence: presence(formElement, 'Please enter an email address'),
|
339
|
-
email: {
|
340
|
-
message: 'Please enter a valid email for this field',
|
341
|
-
},
|
342
|
-
lookups: {
|
343
|
-
formElement,
|
344
|
-
elementIdsWithLookupsExecuted,
|
345
|
-
},
|
346
|
-
format: getCustomRegexFormatConfig(formElement),
|
347
|
-
};
|
348
|
-
break;
|
349
|
-
}
|
350
|
-
case 'time': {
|
351
|
-
partialSchema[escapeElementName(formElement.name)] = {
|
352
|
-
presence: presence(formElement, 'Please select a time'),
|
353
|
-
lookups: {
|
354
|
-
formElement,
|
355
|
-
elementIdsWithLookupsExecuted,
|
356
|
-
},
|
357
|
-
};
|
358
|
-
break;
|
359
|
-
}
|
360
|
-
case 'date': {
|
361
|
-
partialSchema[escapeElementName(formElement.name)] = {
|
362
|
-
presence: presence(formElement, 'Please select a date'),
|
363
|
-
date: {
|
364
|
-
format: (v) => localisationService.formatDate(v),
|
365
|
-
earliest: parseDateValue({
|
366
|
-
dateOnly: true,
|
367
|
-
daysOffset: formElement.fromDateDaysOffset,
|
368
|
-
value: formElement.fromDate,
|
369
|
-
}),
|
370
|
-
latest: parseDateValue({
|
371
|
-
dateOnly: true,
|
372
|
-
daysOffset: formElement.toDateDaysOffset,
|
373
|
-
value: formElement.toDate,
|
374
|
-
}),
|
375
|
-
notValid: 'Please select a valid date',
|
376
|
-
tooEarly: 'Date cannot be before %{date}',
|
377
|
-
tooLate: 'Date cannot be after %{date}',
|
378
|
-
},
|
379
|
-
lookups: {
|
380
|
-
formElement,
|
381
|
-
elementIdsWithLookupsExecuted,
|
382
|
-
},
|
383
|
-
};
|
384
|
-
break;
|
385
|
-
}
|
386
|
-
case 'datetime': {
|
387
|
-
partialSchema[escapeElementName(formElement.name)] = {
|
388
|
-
presence: presence(formElement, 'Please select a date and time'),
|
389
|
-
datetime: {
|
390
|
-
format: (v) => localisationService.formatDatetime(v),
|
391
|
-
earliest: parseDateValue({
|
392
|
-
dateOnly: false,
|
393
|
-
daysOffset: formElement.fromDateDaysOffset,
|
394
|
-
value: formElement.fromDate,
|
395
|
-
}),
|
396
|
-
latest: parseDateValue({
|
397
|
-
dateOnly: false,
|
398
|
-
daysOffset: formElement.toDateDaysOffset,
|
399
|
-
value: formElement.toDate,
|
400
|
-
}),
|
401
|
-
notValid: 'Please select a valid date and time',
|
402
|
-
tooEarly: 'Date and time cannot be before %{date}',
|
403
|
-
tooLate: 'Date and time cannot be after %{date}',
|
404
|
-
},
|
405
|
-
lookups: {
|
406
|
-
formElement,
|
407
|
-
elementIdsWithLookupsExecuted,
|
408
|
-
},
|
409
|
-
};
|
410
|
-
break;
|
411
|
-
}
|
412
|
-
case 'number': {
|
413
|
-
let minErrorMessage = 'Please enter a number greater than or equal to %{count}';
|
414
|
-
let maxErrorMessage = 'Please enter a number less than or equal to %{count}';
|
415
|
-
if (typeof formElement.minNumber === 'number' &&
|
416
|
-
typeof formElement.maxNumber === 'number') {
|
417
|
-
minErrorMessage =
|
418
|
-
maxErrorMessage = `Please enter a number between ${formElement.minNumber} and ${formElement.maxNumber}`;
|
419
|
-
}
|
420
|
-
partialSchema[escapeElementName(formElement.name)] = {
|
421
|
-
type: 'number',
|
422
|
-
presence: presence(formElement, 'Please enter a number'),
|
423
|
-
numericality: {
|
424
|
-
greaterThanOrEqualTo: formElement.minNumber,
|
425
|
-
notGreaterThanOrEqualTo: minErrorMessage,
|
426
|
-
lessThanOrEqualTo: formElement.maxNumber,
|
427
|
-
notLessThanOrEqualTo: maxErrorMessage,
|
428
|
-
onlyInteger: formElement.isInteger,
|
429
|
-
notInteger: 'Please enter a whole number',
|
430
|
-
},
|
431
|
-
lookups: {
|
432
|
-
formElement,
|
433
|
-
elementIdsWithLookupsExecuted,
|
434
|
-
},
|
435
|
-
numberRegex: getCustomRegexFormatConfig(formElement),
|
436
|
-
};
|
437
|
-
break;
|
438
|
-
}
|
439
|
-
case 'files': {
|
440
|
-
partialSchema[escapeElementName(formElement.name)] = {
|
441
|
-
presence: formElement.minEntries
|
442
|
-
? {
|
443
|
-
message: `Please upload at least ${formElement.minEntries} file${formElement.minEntries === 1 ? '' : 's'}`,
|
444
|
-
}
|
445
|
-
: false,
|
446
|
-
length: {
|
447
|
-
minimum: formElement.minEntries,
|
448
|
-
maximum: formElement.maxEntries,
|
449
|
-
tooLong: 'Cannot upload more than %{count} file(s)',
|
450
|
-
tooShort: 'Please upload at least %{count} file(s)',
|
451
|
-
},
|
452
|
-
type: {
|
453
|
-
type: (files) => {
|
454
|
-
return (!Array.isArray(files) ||
|
455
|
-
files.every((file) => {
|
456
|
-
return checkFileNameIsValid(formElement, file.fileName);
|
457
|
-
}));
|
458
|
-
},
|
459
|
-
message: `Only the following file types are accepted: ${(formElement.restrictedFileTypes || []).join(', ')}`,
|
460
|
-
},
|
461
|
-
needsExtension: formElement,
|
462
|
-
attachments: true,
|
463
|
-
};
|
464
|
-
break;
|
465
|
-
}
|
466
|
-
case 'repeatableSet': {
|
467
|
-
partialSchema[escapeElementName(formElement.name)] = {
|
468
|
-
entries: {
|
469
|
-
setSchema: {
|
470
|
-
presence: formElement.minSetEntries
|
471
|
-
? {
|
472
|
-
message: `Must have at least ${formElement.minSetEntries} ${formElement.minSetEntries === 1 ? 'entry' : 'entries'}`,
|
473
|
-
}
|
474
|
-
: false,
|
475
|
-
length: {
|
476
|
-
minimum: formElement.minSetEntries,
|
477
|
-
maximum: formElement.maxSetEntries,
|
478
|
-
tooLong: 'Cannot have more than %{count} entry/entries',
|
479
|
-
tooShort: 'Must have at least %{count} entry/entries',
|
480
|
-
},
|
481
|
-
},
|
482
|
-
entrySchema: generateValidationSchema(formElement.elements, elementIdsWithLookupsExecuted),
|
483
|
-
},
|
484
|
-
};
|
485
|
-
break;
|
486
|
-
}
|
487
|
-
case 'civicaNameRecord': {
|
488
|
-
const nestedElements = generateCivicaNameRecordElements(formElement, []);
|
489
|
-
partialSchema[escapeElementName(formElement.name)] = {
|
490
|
-
nestedElements: generateValidationSchema(nestedElements, elementIdsWithLookupsExecuted),
|
491
|
-
};
|
492
|
-
break;
|
493
|
-
}
|
494
|
-
case 'form': {
|
495
|
-
if (formElement.elements) {
|
496
|
-
partialSchema[escapeElementName(formElement.name)] = {
|
497
|
-
nestedElements: generateValidationSchema(formElement.elements, elementIdsWithLookupsExecuted),
|
498
|
-
};
|
499
|
-
}
|
500
|
-
break;
|
501
|
-
}
|
502
|
-
case 'freshdeskDependentField': {
|
503
|
-
const nestedElements = generateFreshdeskDependentFieldElements(formElement, undefined);
|
504
|
-
partialSchema[escapeElementName(formElement.name)] = {
|
505
|
-
nestedElements: generateValidationSchema(nestedElements, elementIdsWithLookupsExecuted),
|
506
|
-
};
|
507
|
-
break;
|
508
|
-
}
|
509
|
-
default: {
|
510
|
-
console.info('Unsupported form element with validation', formElement);
|
511
|
-
}
|
512
|
-
}
|
513
|
-
return partialSchema;
|
514
|
-
}, {});
|
515
|
-
}
|
516
|
-
const validateSingleMessageError = (submission, schema) => {
|
517
|
-
const errorsAsArray = validate(submission, schema, {
|
518
|
-
format: 'grouped',
|
519
|
-
fullMessages: false,
|
520
|
-
});
|
521
|
-
if (!errorsAsArray || validate.isEmpty(errorsAsArray)) {
|
522
|
-
return;
|
523
|
-
}
|
524
|
-
const errors = Object.keys(errorsAsArray || {}).reduce((messagesByFormElementName, key) => {
|
525
|
-
const validationMessage = errorsAsArray[key][0];
|
526
|
-
if (validationMessage) {
|
527
|
-
messagesByFormElementName[key.replace(/\\./g, '.')] = validationMessage;
|
528
|
-
}
|
529
|
-
return messagesByFormElementName;
|
530
|
-
}, {});
|
531
|
-
if (validate.isEmpty(errors)) {
|
532
|
-
return;
|
533
|
-
}
|
534
|
-
return errors;
|
535
|
-
};
|
536
|
-
export function checkFileNameIsValid(formElement, fileName) {
|
537
|
-
const extension = fileName.split('.').pop();
|
538
|
-
return (!formElement.restrictedFileTypes ||
|
539
|
-
formElement.restrictedFileTypes.some((fileType) => fileType.toLowerCase() === (extension === null || extension === void 0 ? void 0 : extension.toLowerCase())));
|
540
|
-
}
|
541
|
-
export function checkFileNameExtensionIsValid(formElement, fileName) {
|
542
|
-
return (formElement.allowExtensionlessAttachments || fileName.split('.').length >= 2);
|
543
|
-
}
|
544
|
-
export function checkSectionValidity(element, formElementsValidation) {
|
545
|
-
// If everything is valid, no need to check elements
|
546
|
-
if (!formElementsValidation) {
|
547
|
-
return false;
|
548
|
-
}
|
549
|
-
// If there is no elements on the page that are invalid, we will treat as valid
|
550
|
-
return element.elements.some((formElement) => {
|
551
|
-
switch (formElement.type) {
|
552
|
-
case 'page':
|
553
|
-
case 'section': {
|
554
|
-
return checkSectionValidity(formElement, formElementsValidation);
|
555
|
-
}
|
556
|
-
default: {
|
557
|
-
return formElementsValidation[formElement.name];
|
558
|
-
}
|
559
|
-
}
|
560
|
-
});
|
561
|
-
}
|
1
|
+
import validate from 'validate.js';
|
2
|
+
import { localisationService } from '@oneblink/apps';
|
3
|
+
import { parseDateValue } from './generate-default-data';
|
4
|
+
import generateCivicaNameRecordElements from './generateCivicaNameRecordElements';
|
5
|
+
import generateFreshdeskDependentFieldElements from './generateFreshdeskDependentFieldElements';
|
6
|
+
export const lookupValidationMessage = 'Lookup is required';
|
7
|
+
// https://validatejs.org/#validators-datetime
|
8
|
+
// Before using it we must add the parse and format functions
|
9
|
+
// Here is a sample implementation using moment.js
|
10
|
+
validate.extend(validate.validators.datetime, {
|
11
|
+
// The value is guaranteed not to be null or undefined but otherwise it
|
12
|
+
// could be anything.
|
13
|
+
parse: function (value) {
|
14
|
+
return Date.parse(value);
|
15
|
+
},
|
16
|
+
// Input is a unix timestamp
|
17
|
+
format: function (value, options) {
|
18
|
+
const dateValue = new Date(value);
|
19
|
+
return options.format(dateValue);
|
20
|
+
},
|
21
|
+
});
|
22
|
+
validate.validators.entries = function (value, { setSchema, entrySchema, }) {
|
23
|
+
const entries = Array.isArray(value) ? value : [];
|
24
|
+
const entryErrors = entries.reduce((errorsByIndex, entry, index) => {
|
25
|
+
const entryValidation = validateSingleMessageError(entry, entrySchema);
|
26
|
+
if (entryValidation) {
|
27
|
+
errorsByIndex[index] = entryValidation;
|
28
|
+
}
|
29
|
+
return errorsByIndex;
|
30
|
+
}, {});
|
31
|
+
const setErrorMessages = validate.single(value, setSchema);
|
32
|
+
if (!setErrorMessages && validate.isEmpty(entryErrors)) {
|
33
|
+
return;
|
34
|
+
}
|
35
|
+
return {
|
36
|
+
type: 'repeatableSet',
|
37
|
+
set: setErrorMessages && setErrorMessages[0],
|
38
|
+
entries: entryErrors,
|
39
|
+
};
|
40
|
+
};
|
41
|
+
validate.validators.nestedElements = function (value, schema) {
|
42
|
+
const errors = validateSingleMessageError(value || {}, schema);
|
43
|
+
if (!errors) {
|
44
|
+
return;
|
45
|
+
}
|
46
|
+
return {
|
47
|
+
type: 'formElements',
|
48
|
+
formElements: errors,
|
49
|
+
};
|
50
|
+
};
|
51
|
+
function getInvalidAttachment(value) {
|
52
|
+
if (value &&
|
53
|
+
typeof value === 'object' &&
|
54
|
+
value.type &&
|
55
|
+
value.type === 'ERROR') {
|
56
|
+
return value;
|
57
|
+
}
|
58
|
+
}
|
59
|
+
function validateAttachments(value) {
|
60
|
+
const invalidAttachmentNames = value === null || value === void 0 ? void 0 : value.reduce((invalidAttachmentNames, att) => {
|
61
|
+
var _a;
|
62
|
+
const attachmentName = (_a = getInvalidAttachment(att)) === null || _a === void 0 ? void 0 : _a.fileName;
|
63
|
+
if (attachmentName) {
|
64
|
+
invalidAttachmentNames.push(attachmentName);
|
65
|
+
}
|
66
|
+
return invalidAttachmentNames;
|
67
|
+
}, []);
|
68
|
+
if (invalidAttachmentNames === null || invalidAttachmentNames === void 0 ? void 0 : invalidAttachmentNames.length) {
|
69
|
+
return `${invalidAttachmentNames.join(', ')} could not be uploaded.`;
|
70
|
+
}
|
71
|
+
}
|
72
|
+
validate.validators.attachment = function (value) {
|
73
|
+
var _a;
|
74
|
+
return (_a = getInvalidAttachment(value)) === null || _a === void 0 ? void 0 : _a.errorMessage;
|
75
|
+
};
|
76
|
+
validate.validators.attachments = function (value) {
|
77
|
+
if (Array.isArray(value)) {
|
78
|
+
return validateAttachments(value);
|
79
|
+
}
|
80
|
+
return validateAttachments(value === null || value === void 0 ? void 0 : value.files);
|
81
|
+
};
|
82
|
+
// Extend validator for lookups
|
83
|
+
validate.validators.lookups = function (value, { elementIdsWithLookupsExecuted, formElement, }) {
|
84
|
+
if (!formElement.isDataLookup && !formElement.isElementLookup) {
|
85
|
+
return;
|
86
|
+
}
|
87
|
+
// Lookups must only be executed on required form elements
|
88
|
+
if (formElement && !formElement.required) {
|
89
|
+
return;
|
90
|
+
}
|
91
|
+
if (elementIdsWithLookupsExecuted.includes(formElement.id)) {
|
92
|
+
return;
|
93
|
+
}
|
94
|
+
return lookupValidationMessage;
|
95
|
+
};
|
96
|
+
validate.validators.numberRegex = function (value, format) {
|
97
|
+
if (!format) {
|
98
|
+
return;
|
99
|
+
}
|
100
|
+
if (typeof value === 'number' && !Number.isNaN(value)) {
|
101
|
+
value = value.toString();
|
102
|
+
}
|
103
|
+
const errorMessages = validate.single(value, { format });
|
104
|
+
return errorMessages && errorMessages[0];
|
105
|
+
};
|
106
|
+
validate.validators.isTrue = function (value, message) {
|
107
|
+
if (!value) {
|
108
|
+
return message || 'Must be set to true';
|
109
|
+
}
|
110
|
+
};
|
111
|
+
validate.validators.needsExtension = function (value, formElement) {
|
112
|
+
const isValid = !Array.isArray(value) ||
|
113
|
+
value.every((file) => {
|
114
|
+
return checkFileNameExtensionIsValid(formElement, file.fileName);
|
115
|
+
});
|
116
|
+
if (!isValid)
|
117
|
+
return 'All files must have extensions';
|
118
|
+
};
|
119
|
+
function getCustomRegexFormatConfig(formElement) {
|
120
|
+
return formElement.regexPattern
|
121
|
+
? {
|
122
|
+
pattern: formElement.regexPattern,
|
123
|
+
flags: formElement.regexFlags,
|
124
|
+
message: formElement.regexMessage,
|
125
|
+
}
|
126
|
+
: undefined;
|
127
|
+
}
|
128
|
+
export function validateSubmission(schema, submission, formElementsConditionallyShown) {
|
129
|
+
const formElementsValidation = validateSingleMessageError(submission, schema);
|
130
|
+
if (formElementsValidation) {
|
131
|
+
clearValidationMessagesForHiddenElements(formElementsValidation, formElementsConditionallyShown);
|
132
|
+
if (!validate.isEmpty(formElementsValidation)) {
|
133
|
+
return formElementsValidation;
|
134
|
+
}
|
135
|
+
}
|
136
|
+
}
|
137
|
+
const clearValidationMessagesForHiddenElements = (formElementsValidation, formElementsConditionallyShown) => {
|
138
|
+
// If there is no validation to check, there are no invalid elements
|
139
|
+
// If there is no conditionally shown elements, all invalid elements should display validation messages,
|
140
|
+
if (!formElementsValidation || !formElementsConditionallyShown) {
|
141
|
+
return;
|
142
|
+
}
|
143
|
+
for (const key in formElementsValidation) {
|
144
|
+
const formElementValidation = formElementsValidation[key];
|
145
|
+
if (!formElementValidation) {
|
146
|
+
continue;
|
147
|
+
}
|
148
|
+
const formElementConditionallyShown = formElementsConditionallyShown[key];
|
149
|
+
// If the validation is for an element that is being hidden,
|
150
|
+
// we can remove the validation message and move to the next validation
|
151
|
+
if (formElementConditionallyShown === null || formElementConditionallyShown === void 0 ? void 0 : formElementConditionallyShown.isHidden) {
|
152
|
+
delete formElementsValidation[key];
|
153
|
+
continue;
|
154
|
+
}
|
155
|
+
// If the validation is for a single element (not nested elements),
|
156
|
+
// we will always show the validation message
|
157
|
+
if (typeof formElementValidation === 'string') {
|
158
|
+
continue;
|
159
|
+
}
|
160
|
+
// Here we will check to see if the nested elements that are
|
161
|
+
// invalid are being shown, if not, remove validation messages
|
162
|
+
switch (formElementValidation.type) {
|
163
|
+
case 'repeatableSet': {
|
164
|
+
for (const index in formElementValidation.entries) {
|
165
|
+
clearValidationMessagesForHiddenElements(formElementValidation.entries[index], formElementConditionallyShown &&
|
166
|
+
formElementConditionallyShown.type === 'repeatableSet'
|
167
|
+
? formElementConditionallyShown.entries[index]
|
168
|
+
: undefined);
|
169
|
+
if (validate.isEmpty(formElementValidation.entries[index])) {
|
170
|
+
delete formElementValidation.entries[index];
|
171
|
+
}
|
172
|
+
}
|
173
|
+
// Remove the validation if all entries are valid and the set is also valid
|
174
|
+
if (validate.isEmpty(formElementValidation.entries) &&
|
175
|
+
!formElementValidation.set) {
|
176
|
+
delete formElementsValidation[key];
|
177
|
+
}
|
178
|
+
break;
|
179
|
+
}
|
180
|
+
case 'formElements': {
|
181
|
+
clearValidationMessagesForHiddenElements(formElementValidation.formElements, (formElementConditionallyShown === null || formElementConditionallyShown === void 0 ? void 0 : formElementConditionallyShown.type) === 'formElements'
|
182
|
+
? formElementConditionallyShown === null || formElementConditionallyShown === void 0 ? void 0 : formElementConditionallyShown.formElements
|
183
|
+
: undefined);
|
184
|
+
if (validate.isEmpty(formElementValidation.formElements)) {
|
185
|
+
delete formElementsValidation[key];
|
186
|
+
}
|
187
|
+
break;
|
188
|
+
}
|
189
|
+
}
|
190
|
+
}
|
191
|
+
};
|
192
|
+
const presence = ({ required, requiredMessage }, message) => (required ? { message: requiredMessage || message } : false);
|
193
|
+
const escapeElementName = (elementName) => {
|
194
|
+
const escapedName = elementName.replace(/\./g, '\\.');
|
195
|
+
return escapedName;
|
196
|
+
};
|
197
|
+
export function generateValidationSchema(elements, elementIdsWithLookupsExecuted) {
|
198
|
+
return elements.reduce((partialSchema, formElement) => {
|
199
|
+
switch (formElement.type) {
|
200
|
+
case 'summary':
|
201
|
+
case 'calculation':
|
202
|
+
case 'image':
|
203
|
+
case 'html':
|
204
|
+
case 'infoPage':
|
205
|
+
case 'heading': {
|
206
|
+
break;
|
207
|
+
}
|
208
|
+
case 'section':
|
209
|
+
case 'page': {
|
210
|
+
const nestedSchema = generateValidationSchema(formElement.elements, elementIdsWithLookupsExecuted);
|
211
|
+
Object.assign(partialSchema, nestedSchema);
|
212
|
+
break;
|
213
|
+
}
|
214
|
+
case 'draw': {
|
215
|
+
partialSchema[escapeElementName(formElement.name)] = {
|
216
|
+
attachment: true,
|
217
|
+
presence: presence(formElement, 'A signature is required'),
|
218
|
+
};
|
219
|
+
break;
|
220
|
+
}
|
221
|
+
case 'camera': {
|
222
|
+
partialSchema[escapeElementName(formElement.name)] = {
|
223
|
+
attachment: true,
|
224
|
+
presence: presence(formElement, 'A photo is required'),
|
225
|
+
};
|
226
|
+
break;
|
227
|
+
}
|
228
|
+
case 'captcha': {
|
229
|
+
partialSchema[escapeElementName(formElement.name)] = {
|
230
|
+
presence: presence({ ...formElement, required: true }, 'Please complete the CAPTCHA successfully'),
|
231
|
+
};
|
232
|
+
break;
|
233
|
+
}
|
234
|
+
case 'location': {
|
235
|
+
partialSchema[escapeElementName(formElement.name)] = {
|
236
|
+
presence: presence(formElement, 'Please select a location'),
|
237
|
+
lookups: {
|
238
|
+
formElement,
|
239
|
+
elementIdsWithLookupsExecuted,
|
240
|
+
},
|
241
|
+
};
|
242
|
+
break;
|
243
|
+
}
|
244
|
+
case 'compliance': {
|
245
|
+
partialSchema[escapeElementName(formElement.name)] = {
|
246
|
+
presence: presence(formElement, 'Required'),
|
247
|
+
lookups: {
|
248
|
+
formElement,
|
249
|
+
elementIdsWithLookupsExecuted,
|
250
|
+
},
|
251
|
+
attachments: true,
|
252
|
+
};
|
253
|
+
break;
|
254
|
+
}
|
255
|
+
case 'abn':
|
256
|
+
case 'geoscapeAddress':
|
257
|
+
case 'pointAddress':
|
258
|
+
case 'civicaStreetName':
|
259
|
+
case 'autocomplete':
|
260
|
+
case 'checkboxes':
|
261
|
+
case 'radio':
|
262
|
+
case 'select': {
|
263
|
+
partialSchema[escapeElementName(formElement.name)] = {
|
264
|
+
presence: presence(formElement, 'Required'),
|
265
|
+
lookups: {
|
266
|
+
formElement,
|
267
|
+
elementIdsWithLookupsExecuted,
|
268
|
+
},
|
269
|
+
};
|
270
|
+
break;
|
271
|
+
}
|
272
|
+
case 'boolean': {
|
273
|
+
partialSchema[escapeElementName(formElement.name)] = {
|
274
|
+
isTrue: formElement.required && 'Required',
|
275
|
+
lookups: {
|
276
|
+
formElement,
|
277
|
+
elementIdsWithLookupsExecuted,
|
278
|
+
},
|
279
|
+
};
|
280
|
+
break;
|
281
|
+
}
|
282
|
+
case 'bsb': {
|
283
|
+
partialSchema[escapeElementName(formElement.name)] = {
|
284
|
+
presence: presence(formElement, 'Please enter a BSB number'),
|
285
|
+
lookups: {
|
286
|
+
formElement,
|
287
|
+
elementIdsWithLookupsExecuted,
|
288
|
+
},
|
289
|
+
format: {
|
290
|
+
pattern: /\d{3}-\d{3}/,
|
291
|
+
message: 'Please enter a valid BSB number',
|
292
|
+
},
|
293
|
+
};
|
294
|
+
break;
|
295
|
+
}
|
296
|
+
case 'barcodeScanner': {
|
297
|
+
partialSchema[escapeElementName(formElement.name)] = {
|
298
|
+
presence: presence(formElement, 'Please scan a barcode or enter a value'),
|
299
|
+
lookups: {
|
300
|
+
formElement,
|
301
|
+
elementIdsWithLookupsExecuted,
|
302
|
+
},
|
303
|
+
format: getCustomRegexFormatConfig(formElement),
|
304
|
+
};
|
305
|
+
break;
|
306
|
+
}
|
307
|
+
case 'text':
|
308
|
+
case 'textarea': {
|
309
|
+
partialSchema[escapeElementName(formElement.name)] = {
|
310
|
+
presence: presence(formElement, 'Please enter a value'),
|
311
|
+
lookups: {
|
312
|
+
formElement,
|
313
|
+
elementIdsWithLookupsExecuted,
|
314
|
+
},
|
315
|
+
length: {
|
316
|
+
minimum: formElement.minLength,
|
317
|
+
tooShort: 'Please enter a value with at least %{count} character(s)',
|
318
|
+
maximum: formElement.maxLength,
|
319
|
+
tooLong: 'Please enter a value with %{count} character(s) or less',
|
320
|
+
},
|
321
|
+
format: getCustomRegexFormatConfig(formElement),
|
322
|
+
};
|
323
|
+
break;
|
324
|
+
}
|
325
|
+
case 'telephone': {
|
326
|
+
partialSchema[escapeElementName(formElement.name)] = {
|
327
|
+
presence: presence(formElement, 'Please enter a phone number'),
|
328
|
+
lookups: {
|
329
|
+
formElement,
|
330
|
+
elementIdsWithLookupsExecuted,
|
331
|
+
},
|
332
|
+
format: getCustomRegexFormatConfig(formElement),
|
333
|
+
};
|
334
|
+
break;
|
335
|
+
}
|
336
|
+
case 'email': {
|
337
|
+
partialSchema[escapeElementName(formElement.name)] = {
|
338
|
+
presence: presence(formElement, 'Please enter an email address'),
|
339
|
+
email: {
|
340
|
+
message: 'Please enter a valid email for this field',
|
341
|
+
},
|
342
|
+
lookups: {
|
343
|
+
formElement,
|
344
|
+
elementIdsWithLookupsExecuted,
|
345
|
+
},
|
346
|
+
format: getCustomRegexFormatConfig(formElement),
|
347
|
+
};
|
348
|
+
break;
|
349
|
+
}
|
350
|
+
case 'time': {
|
351
|
+
partialSchema[escapeElementName(formElement.name)] = {
|
352
|
+
presence: presence(formElement, 'Please select a time'),
|
353
|
+
lookups: {
|
354
|
+
formElement,
|
355
|
+
elementIdsWithLookupsExecuted,
|
356
|
+
},
|
357
|
+
};
|
358
|
+
break;
|
359
|
+
}
|
360
|
+
case 'date': {
|
361
|
+
partialSchema[escapeElementName(formElement.name)] = {
|
362
|
+
presence: presence(formElement, 'Please select a date'),
|
363
|
+
date: {
|
364
|
+
format: (v) => localisationService.formatDate(v),
|
365
|
+
earliest: parseDateValue({
|
366
|
+
dateOnly: true,
|
367
|
+
daysOffset: formElement.fromDateDaysOffset,
|
368
|
+
value: formElement.fromDate,
|
369
|
+
}),
|
370
|
+
latest: parseDateValue({
|
371
|
+
dateOnly: true,
|
372
|
+
daysOffset: formElement.toDateDaysOffset,
|
373
|
+
value: formElement.toDate,
|
374
|
+
}),
|
375
|
+
notValid: 'Please select a valid date',
|
376
|
+
tooEarly: 'Date cannot be before %{date}',
|
377
|
+
tooLate: 'Date cannot be after %{date}',
|
378
|
+
},
|
379
|
+
lookups: {
|
380
|
+
formElement,
|
381
|
+
elementIdsWithLookupsExecuted,
|
382
|
+
},
|
383
|
+
};
|
384
|
+
break;
|
385
|
+
}
|
386
|
+
case 'datetime': {
|
387
|
+
partialSchema[escapeElementName(formElement.name)] = {
|
388
|
+
presence: presence(formElement, 'Please select a date and time'),
|
389
|
+
datetime: {
|
390
|
+
format: (v) => localisationService.formatDatetime(v),
|
391
|
+
earliest: parseDateValue({
|
392
|
+
dateOnly: false,
|
393
|
+
daysOffset: formElement.fromDateDaysOffset,
|
394
|
+
value: formElement.fromDate,
|
395
|
+
}),
|
396
|
+
latest: parseDateValue({
|
397
|
+
dateOnly: false,
|
398
|
+
daysOffset: formElement.toDateDaysOffset,
|
399
|
+
value: formElement.toDate,
|
400
|
+
}),
|
401
|
+
notValid: 'Please select a valid date and time',
|
402
|
+
tooEarly: 'Date and time cannot be before %{date}',
|
403
|
+
tooLate: 'Date and time cannot be after %{date}',
|
404
|
+
},
|
405
|
+
lookups: {
|
406
|
+
formElement,
|
407
|
+
elementIdsWithLookupsExecuted,
|
408
|
+
},
|
409
|
+
};
|
410
|
+
break;
|
411
|
+
}
|
412
|
+
case 'number': {
|
413
|
+
let minErrorMessage = 'Please enter a number greater than or equal to %{count}';
|
414
|
+
let maxErrorMessage = 'Please enter a number less than or equal to %{count}';
|
415
|
+
if (typeof formElement.minNumber === 'number' &&
|
416
|
+
typeof formElement.maxNumber === 'number') {
|
417
|
+
minErrorMessage =
|
418
|
+
maxErrorMessage = `Please enter a number between ${formElement.minNumber} and ${formElement.maxNumber}`;
|
419
|
+
}
|
420
|
+
partialSchema[escapeElementName(formElement.name)] = {
|
421
|
+
type: 'number',
|
422
|
+
presence: presence(formElement, 'Please enter a number'),
|
423
|
+
numericality: {
|
424
|
+
greaterThanOrEqualTo: formElement.minNumber,
|
425
|
+
notGreaterThanOrEqualTo: minErrorMessage,
|
426
|
+
lessThanOrEqualTo: formElement.maxNumber,
|
427
|
+
notLessThanOrEqualTo: maxErrorMessage,
|
428
|
+
onlyInteger: formElement.isInteger,
|
429
|
+
notInteger: 'Please enter a whole number',
|
430
|
+
},
|
431
|
+
lookups: {
|
432
|
+
formElement,
|
433
|
+
elementIdsWithLookupsExecuted,
|
434
|
+
},
|
435
|
+
numberRegex: getCustomRegexFormatConfig(formElement),
|
436
|
+
};
|
437
|
+
break;
|
438
|
+
}
|
439
|
+
case 'files': {
|
440
|
+
partialSchema[escapeElementName(formElement.name)] = {
|
441
|
+
presence: formElement.minEntries
|
442
|
+
? {
|
443
|
+
message: `Please upload at least ${formElement.minEntries} file${formElement.minEntries === 1 ? '' : 's'}`,
|
444
|
+
}
|
445
|
+
: false,
|
446
|
+
length: {
|
447
|
+
minimum: formElement.minEntries,
|
448
|
+
maximum: formElement.maxEntries,
|
449
|
+
tooLong: 'Cannot upload more than %{count} file(s)',
|
450
|
+
tooShort: 'Please upload at least %{count} file(s)',
|
451
|
+
},
|
452
|
+
type: {
|
453
|
+
type: (files) => {
|
454
|
+
return (!Array.isArray(files) ||
|
455
|
+
files.every((file) => {
|
456
|
+
return checkFileNameIsValid(formElement, file.fileName);
|
457
|
+
}));
|
458
|
+
},
|
459
|
+
message: `Only the following file types are accepted: ${(formElement.restrictedFileTypes || []).join(', ')}`,
|
460
|
+
},
|
461
|
+
needsExtension: formElement,
|
462
|
+
attachments: true,
|
463
|
+
};
|
464
|
+
break;
|
465
|
+
}
|
466
|
+
case 'repeatableSet': {
|
467
|
+
partialSchema[escapeElementName(formElement.name)] = {
|
468
|
+
entries: {
|
469
|
+
setSchema: {
|
470
|
+
presence: formElement.minSetEntries
|
471
|
+
? {
|
472
|
+
message: `Must have at least ${formElement.minSetEntries} ${formElement.minSetEntries === 1 ? 'entry' : 'entries'}`,
|
473
|
+
}
|
474
|
+
: false,
|
475
|
+
length: {
|
476
|
+
minimum: formElement.minSetEntries,
|
477
|
+
maximum: formElement.maxSetEntries,
|
478
|
+
tooLong: 'Cannot have more than %{count} entry/entries',
|
479
|
+
tooShort: 'Must have at least %{count} entry/entries',
|
480
|
+
},
|
481
|
+
},
|
482
|
+
entrySchema: generateValidationSchema(formElement.elements, elementIdsWithLookupsExecuted),
|
483
|
+
},
|
484
|
+
};
|
485
|
+
break;
|
486
|
+
}
|
487
|
+
case 'civicaNameRecord': {
|
488
|
+
const nestedElements = generateCivicaNameRecordElements(formElement, []);
|
489
|
+
partialSchema[escapeElementName(formElement.name)] = {
|
490
|
+
nestedElements: generateValidationSchema(nestedElements, elementIdsWithLookupsExecuted),
|
491
|
+
};
|
492
|
+
break;
|
493
|
+
}
|
494
|
+
case 'form': {
|
495
|
+
if (formElement.elements) {
|
496
|
+
partialSchema[escapeElementName(formElement.name)] = {
|
497
|
+
nestedElements: generateValidationSchema(formElement.elements, elementIdsWithLookupsExecuted),
|
498
|
+
};
|
499
|
+
}
|
500
|
+
break;
|
501
|
+
}
|
502
|
+
case 'freshdeskDependentField': {
|
503
|
+
const nestedElements = generateFreshdeskDependentFieldElements(formElement, undefined);
|
504
|
+
partialSchema[escapeElementName(formElement.name)] = {
|
505
|
+
nestedElements: generateValidationSchema(nestedElements, elementIdsWithLookupsExecuted),
|
506
|
+
};
|
507
|
+
break;
|
508
|
+
}
|
509
|
+
default: {
|
510
|
+
console.info('Unsupported form element with validation', formElement);
|
511
|
+
}
|
512
|
+
}
|
513
|
+
return partialSchema;
|
514
|
+
}, {});
|
515
|
+
}
|
516
|
+
const validateSingleMessageError = (submission, schema) => {
|
517
|
+
const errorsAsArray = validate(submission, schema, {
|
518
|
+
format: 'grouped',
|
519
|
+
fullMessages: false,
|
520
|
+
});
|
521
|
+
if (!errorsAsArray || validate.isEmpty(errorsAsArray)) {
|
522
|
+
return;
|
523
|
+
}
|
524
|
+
const errors = Object.keys(errorsAsArray || {}).reduce((messagesByFormElementName, key) => {
|
525
|
+
const validationMessage = errorsAsArray[key][0];
|
526
|
+
if (validationMessage) {
|
527
|
+
messagesByFormElementName[key.replace(/\\./g, '.')] = validationMessage;
|
528
|
+
}
|
529
|
+
return messagesByFormElementName;
|
530
|
+
}, {});
|
531
|
+
if (validate.isEmpty(errors)) {
|
532
|
+
return;
|
533
|
+
}
|
534
|
+
return errors;
|
535
|
+
};
|
536
|
+
export function checkFileNameIsValid(formElement, fileName) {
|
537
|
+
const extension = fileName.split('.').pop();
|
538
|
+
return (!formElement.restrictedFileTypes ||
|
539
|
+
formElement.restrictedFileTypes.some((fileType) => fileType.toLowerCase() === (extension === null || extension === void 0 ? void 0 : extension.toLowerCase())));
|
540
|
+
}
|
541
|
+
export function checkFileNameExtensionIsValid(formElement, fileName) {
|
542
|
+
return (formElement.allowExtensionlessAttachments || fileName.split('.').length >= 2);
|
543
|
+
}
|
544
|
+
export function checkSectionValidity(element, formElementsValidation) {
|
545
|
+
// If everything is valid, no need to check elements
|
546
|
+
if (!formElementsValidation) {
|
547
|
+
return false;
|
548
|
+
}
|
549
|
+
// If there is no elements on the page that are invalid, we will treat as valid
|
550
|
+
return element.elements.some((formElement) => {
|
551
|
+
switch (formElement.type) {
|
552
|
+
case 'page':
|
553
|
+
case 'section': {
|
554
|
+
return checkSectionValidity(formElement, formElementsValidation);
|
555
|
+
}
|
556
|
+
default: {
|
557
|
+
return formElementsValidation[formElement.name];
|
558
|
+
}
|
559
|
+
}
|
560
|
+
});
|
561
|
+
}
|
562
562
|
//# sourceMappingURL=form-validation.js.map
|