@defra/forms-engine-plugin 5.0.0-alpha.2 → 5.0.0-alpha.21
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/.public/javascripts/application.min.js +1 -1
- package/.public/javascripts/application.min.js.LICENSE.txt +7 -0
- package/.public/javascripts/application.min.js.map +1 -1
- package/.public/javascripts/shared.min.js +1 -1
- package/.public/javascripts/shared.min.js.LICENSE.txt +7 -0
- package/.public/javascripts/shared.min.js.map +1 -1
- package/.public/stylesheets/application.min.css.map +1 -1
- package/.server/client/javascripts/file-upload.js +6 -3
- package/.server/client/javascripts/file-upload.js.map +1 -1
- package/.server/client/javascripts/geospatial-map.d.ts +153 -5
- package/.server/client/javascripts/geospatial-map.js +157 -77
- package/.server/client/javascripts/geospatial-map.js.map +1 -1
- package/.server/client/javascripts/govuk.js +2 -1
- package/.server/client/javascripts/govuk.js.map +1 -1
- package/.server/client/javascripts/location-map.d.ts +44 -0
- package/.server/client/javascripts/location-map.js +54 -5
- package/.server/client/javascripts/location-map.js.map +1 -1
- package/.server/client/javascripts/map-constants.d.ts +3 -0
- package/.server/client/javascripts/map-constants.js +4 -0
- package/.server/client/javascripts/map-constants.js.map +1 -0
- package/.server/client/javascripts/map.d.ts +10 -0
- package/.server/client/javascripts/map.js +42 -0
- package/.server/client/javascripts/map.js.map +1 -1
- package/.server/client/javascripts/maps.d.ts +5 -0
- package/.server/client/javascripts/maps.js +6 -0
- package/.server/client/javascripts/maps.js.map +1 -0
- package/.server/client/javascripts/shared.d.ts +1 -4
- package/.server/client/javascripts/shared.js +1 -4
- package/.server/client/javascripts/shared.js.map +1 -1
- package/.server/client/javascripts/sssi-dataset.d.ts +18 -20
- package/.server/client/javascripts/sssi-dataset.js +37 -39
- package/.server/client/javascripts/sssi-dataset.js.map +1 -1
- package/.server/client/stylesheets/maps.scss +4 -0
- package/.server/client/stylesheets/shared.scss +1 -5
- package/.server/server/constants.d.ts +2 -0
- package/.server/server/constants.js +2 -0
- package/.server/server/constants.js.map +1 -1
- package/.server/server/plugins/engine/__stubs__/definitions.d.ts +29 -0
- package/.server/server/plugins/engine/__stubs__/definitions.js +125 -0
- package/.server/server/plugins/engine/__stubs__/definitions.js.map +1 -0
- package/.server/server/plugins/engine/components/AutocompleteField.d.ts +9 -3
- package/.server/server/plugins/engine/components/AutocompleteField.js +12 -0
- package/.server/server/plugins/engine/components/AutocompleteField.js.map +1 -1
- package/.server/server/plugins/engine/components/CheckboxesField.d.ts +21 -0
- package/.server/server/plugins/engine/components/CheckboxesField.js +30 -5
- package/.server/server/plugins/engine/components/CheckboxesField.js.map +1 -1
- package/.server/server/plugins/engine/components/ComponentBase.d.ts +1 -0
- package/.server/server/plugins/engine/components/ComponentBase.js +2 -0
- package/.server/server/plugins/engine/components/ComponentBase.js.map +1 -1
- package/.server/server/plugins/engine/components/ComponentCollection.js +11 -6
- package/.server/server/plugins/engine/components/ComponentCollection.js.map +1 -1
- package/.server/server/plugins/engine/components/DatePartsField.d.ts +6 -3
- package/.server/server/plugins/engine/components/DatePartsField.js +12 -7
- package/.server/server/plugins/engine/components/DatePartsField.js.map +1 -1
- package/.server/server/plugins/engine/components/DeclarationField.d.ts +5 -2
- package/.server/server/plugins/engine/components/DeclarationField.js +6 -4
- package/.server/server/plugins/engine/components/DeclarationField.js.map +1 -1
- package/.server/server/plugins/engine/components/Details.d.ts +1 -0
- package/.server/server/plugins/engine/components/EastingNorthingField.d.ts +33 -2
- package/.server/server/plugins/engine/components/EastingNorthingField.js +110 -54
- package/.server/server/plugins/engine/components/EastingNorthingField.js.map +1 -1
- package/.server/server/plugins/engine/components/EmailAddressField.d.ts +4 -1
- package/.server/server/plugins/engine/components/EmailAddressField.js +2 -1
- package/.server/server/plugins/engine/components/EmailAddressField.js.map +1 -1
- package/.server/server/plugins/engine/components/FileUploadField.d.ts +21 -0
- package/.server/server/plugins/engine/components/FileUploadField.js +35 -3
- package/.server/server/plugins/engine/components/FileUploadField.js.map +1 -1
- package/.server/server/plugins/engine/components/FormComponent.d.ts +5 -1
- package/.server/server/plugins/engine/components/FormComponent.js +5 -2
- package/.server/server/plugins/engine/components/FormComponent.js.map +1 -1
- package/.server/server/plugins/engine/components/GeospatialField.d.ts +23 -0
- package/.server/server/plugins/engine/components/GeospatialField.js +33 -9
- package/.server/server/plugins/engine/components/GeospatialField.js.map +1 -1
- package/.server/server/plugins/engine/components/Html.d.ts +1 -0
- package/.server/server/plugins/engine/components/InsetText.d.ts +1 -0
- package/.server/server/plugins/engine/components/LatLongField.d.ts +32 -2
- package/.server/server/plugins/engine/components/LatLongField.js +85 -48
- package/.server/server/plugins/engine/components/LatLongField.js.map +1 -1
- package/.server/server/plugins/engine/components/List.d.ts +1 -0
- package/.server/server/plugins/engine/components/ListFormComponent.d.ts +1 -0
- package/.server/server/plugins/engine/components/LocationFieldBase.d.ts +8 -2
- package/.server/server/plugins/engine/components/LocationFieldBase.js +25 -6
- package/.server/server/plugins/engine/components/LocationFieldBase.js.map +1 -1
- package/.server/server/plugins/engine/components/LocationFieldHelpers.d.ts +12 -3
- package/.server/server/plugins/engine/components/LocationFieldHelpers.js +21 -13
- package/.server/server/plugins/engine/components/LocationFieldHelpers.js.map +1 -1
- package/.server/server/plugins/engine/components/Markdown.d.ts +1 -0
- package/.server/server/plugins/engine/components/Markdown.js +1 -1
- package/.server/server/plugins/engine/components/Markdown.js.map +1 -1
- package/.server/server/plugins/engine/components/MonthYearField.d.ts +5 -2
- package/.server/server/plugins/engine/components/MonthYearField.js +13 -9
- package/.server/server/plugins/engine/components/MonthYearField.js.map +1 -1
- package/.server/server/plugins/engine/components/MultilineTextField.d.ts +1 -0
- package/.server/server/plugins/engine/components/NationalGridFieldNumberField.d.ts +2 -1
- package/.server/server/plugins/engine/components/NationalGridFieldNumberField.js +4 -3
- package/.server/server/plugins/engine/components/NationalGridFieldNumberField.js.map +1 -1
- package/.server/server/plugins/engine/components/NotificationBanner.d.ts +1 -0
- package/.server/server/plugins/engine/components/NumberField.d.ts +5 -0
- package/.server/server/plugins/engine/components/NumberField.js +16 -0
- package/.server/server/plugins/engine/components/NumberField.js.map +1 -1
- package/.server/server/plugins/engine/components/OsGridRefField.d.ts +103 -1
- package/.server/server/plugins/engine/components/OsGridRefField.js +13 -3
- package/.server/server/plugins/engine/components/OsGridRefField.js.map +1 -1
- package/.server/server/plugins/engine/components/PaymentField.d.ts +3 -0
- package/.server/server/plugins/engine/components/PaymentField.js +17 -6
- package/.server/server/plugins/engine/components/PaymentField.js.map +1 -1
- package/.server/server/plugins/engine/components/SelectField.d.ts +1 -0
- package/.server/server/plugins/engine/components/SelectionControlField.d.ts +1 -0
- package/.server/server/plugins/engine/components/TelephoneNumberField.d.ts +1 -0
- package/.server/server/plugins/engine/components/UkAddressField.d.ts +1 -0
- package/.server/server/plugins/engine/components/UkAddressField.js +23 -8
- package/.server/server/plugins/engine/components/UkAddressField.js.map +1 -1
- package/.server/server/plugins/engine/components/YesNoField.d.ts +5 -2
- package/.server/server/plugins/engine/components/YesNoField.js +17 -8
- package/.server/server/plugins/engine/components/YesNoField.js.map +1 -1
- package/.server/server/plugins/engine/components/helpers/components.js +3 -3
- package/.server/server/plugins/engine/components/helpers/components.js.map +1 -1
- package/.server/server/plugins/engine/components/helpers/geospatial.d.ts +8 -1
- package/.server/server/plugins/engine/components/helpers/geospatial.js +56 -15
- package/.server/server/plugins/engine/components/helpers/geospatial.js.map +1 -1
- package/.server/server/plugins/engine/components/helpers/index.d.ts +7 -0
- package/.server/server/plugins/engine/components/helpers/index.js +13 -1
- package/.server/server/plugins/engine/components/helpers/index.js.map +1 -1
- package/.server/server/plugins/engine/components/types.d.ts +1 -0
- package/.server/server/plugins/engine/components/types.js.map +1 -1
- package/.server/server/plugins/engine/errors.d.ts +49 -0
- package/.server/server/plugins/engine/errors.js +75 -0
- package/.server/server/plugins/engine/errors.js.map +1 -0
- package/.server/server/plugins/engine/form-availability.d.ts +3 -2
- package/.server/server/plugins/engine/form-availability.js +3 -2
- package/.server/server/plugins/engine/form-availability.js.map +1 -1
- package/.server/server/plugins/engine/form-context.js +2 -2
- package/.server/server/plugins/engine/form-context.js.map +1 -1
- package/.server/server/plugins/engine/helpers.d.ts +22 -2
- package/.server/server/plugins/engine/helpers.js +44 -5
- package/.server/server/plugins/engine/helpers.js.map +1 -1
- package/.server/server/plugins/engine/i18n/buildValidationMessages.d.ts +4 -1
- package/.server/server/plugins/engine/i18n/buildValidationMessages.js +31 -7
- package/.server/server/plugins/engine/i18n/buildValidationMessages.js.map +1 -1
- package/.server/server/plugins/engine/i18n/createFormTranslator.d.ts +4 -4
- package/.server/server/plugins/engine/i18n/createFormTranslator.js +33 -4
- package/.server/server/plugins/engine/i18n/createFormTranslator.js.map +1 -1
- package/.server/server/plugins/engine/i18n/extractBaseTranslations.d.ts +1 -1
- package/.server/server/plugins/engine/i18n/extractBaseTranslations.js +9 -0
- package/.server/server/plugins/engine/i18n/extractBaseTranslations.js.map +1 -1
- package/.server/server/plugins/engine/i18n/form.d.ts +13 -0
- package/.server/server/plugins/engine/i18n/form.js +35 -0
- package/.server/server/plugins/engine/i18n/form.js.map +1 -0
- package/.server/server/plugins/engine/i18n/languages.d.ts +10 -0
- package/.server/server/plugins/engine/i18n/languages.js +19 -0
- package/.server/server/plugins/engine/i18n/languages.js.map +1 -0
- package/.server/server/plugins/engine/i18n/translations/cy.json +192 -9
- package/.server/server/plugins/engine/i18n/translations/en-GB.json +125 -7
- package/.server/server/plugins/engine/i18n/types.d.ts +3 -0
- package/.server/server/plugins/engine/i18n/types.js.map +1 -1
- package/.server/server/plugins/engine/index.d.ts +4 -0
- package/.server/server/plugins/engine/index.js +4 -0
- package/.server/server/plugins/engine/index.js.map +1 -1
- package/.server/server/plugins/engine/models/FormModel.d.ts +0 -4
- package/.server/server/plugins/engine/models/FormModel.js +35 -23
- package/.server/server/plugins/engine/models/FormModel.js.map +1 -1
- package/.server/server/plugins/engine/models/SummaryViewModel.js +9 -4
- package/.server/server/plugins/engine/models/SummaryViewModel.js.map +1 -1
- package/.server/server/plugins/engine/models/types.d.ts +28 -1
- package/.server/server/plugins/engine/models/types.js.map +1 -1
- package/.server/server/plugins/engine/models/unavailable-view-model.d.ts +11 -2
- package/.server/server/plugins/engine/models/unavailable-view-model.js +23 -4
- package/.server/server/plugins/engine/models/unavailable-view-model.js.map +1 -1
- package/.server/server/plugins/engine/outputFormatters/adapter/v1.js +14 -6
- package/.server/server/plugins/engine/outputFormatters/adapter/v1.js.map +1 -1
- package/.server/server/plugins/engine/outputFormatters/human/v1.js +2 -1
- package/.server/server/plugins/engine/outputFormatters/human/v1.js.map +1 -1
- package/.server/server/plugins/engine/outputFormatters/machine/v2.d.ts +2 -0
- package/.server/server/plugins/engine/outputFormatters/machine/v2.js +2 -0
- package/.server/server/plugins/engine/outputFormatters/machine/v2.js.map +1 -1
- package/.server/server/plugins/engine/pageControllers/FileUploadPageController.d.ts +7 -1
- package/.server/server/plugins/engine/pageControllers/FileUploadPageController.js +56 -10
- package/.server/server/plugins/engine/pageControllers/FileUploadPageController.js.map +1 -1
- package/.server/server/plugins/engine/pageControllers/QuestionPageController.d.ts +1 -1
- package/.server/server/plugins/engine/pageControllers/QuestionPageController.js +7 -3
- package/.server/server/plugins/engine/pageControllers/QuestionPageController.js.map +1 -1
- package/.server/server/plugins/engine/pageControllers/RepeatPageController.js +3 -4
- package/.server/server/plugins/engine/pageControllers/RepeatPageController.js.map +1 -1
- package/.server/server/plugins/engine/pageControllers/SummaryPageController.js +10 -4
- package/.server/server/plugins/engine/pageControllers/SummaryPageController.js.map +1 -1
- package/.server/server/plugins/engine/pageControllers/helpers/pages.js +2 -1
- package/.server/server/plugins/engine/pageControllers/helpers/pages.js.map +1 -1
- package/.server/server/plugins/engine/pageControllers/helpers/submission.d.ts +35 -2
- package/.server/server/plugins/engine/pageControllers/helpers/submission.js +100 -3
- package/.server/server/plugins/engine/pageControllers/helpers/submission.js.map +1 -1
- package/.server/server/plugins/engine/pageControllers/validationOptions.d.ts +1 -1
- package/.server/server/plugins/engine/pageControllers/validationOptions.js +24 -3
- package/.server/server/plugins/engine/pageControllers/validationOptions.js.map +1 -1
- package/.server/server/plugins/engine/types/enums.d.ts +3 -3
- package/.server/server/plugins/engine/types/enums.js +5 -4
- package/.server/server/plugins/engine/types/enums.js.map +1 -1
- package/.server/server/plugins/engine/types/schema.js +10 -3
- package/.server/server/plugins/engine/types/schema.js.map +1 -1
- package/.server/server/plugins/engine/types.d.ts +18 -2
- package/.server/server/plugins/engine/types.js.map +1 -1
- package/.server/server/plugins/engine/unavailable-response.js +5 -2
- package/.server/server/plugins/engine/unavailable-response.js.map +1 -1
- package/.server/server/plugins/engine/views/components/_location-field-base.html +4 -2
- package/.server/server/plugins/engine/views/components/fileuploadfield.html +1 -1
- package/.server/server/plugins/engine/views/components/geospatialfield.html +1 -0
- package/.server/server/plugins/engine/views/components/multilinetextfield.html +12 -1
- package/.server/server/plugins/engine/views/components/osgridreffield.html +4 -1
- package/.server/server/plugins/engine/views/components/paymentfield.html +1 -1
- package/.server/server/plugins/engine/views/components/ukaddressfield.html +1 -1
- package/.server/server/plugins/engine/views/file-upload.html +1 -1
- package/.server/server/plugins/engine/views/partials/preview-banner.html +3 -1
- package/.server/server/plugins/engine/views/unavailable.html +14 -11
- package/.server/server/plugins/nunjucks/filters/applyUrlParam.d.ts +9 -0
- package/.server/server/plugins/nunjucks/filters/applyUrlParam.js +17 -0
- package/.server/server/plugins/nunjucks/filters/applyUrlParam.js.map +1 -0
- package/.server/server/plugins/nunjucks/filters/applyUrlParam.test.js +17 -0
- package/.server/server/plugins/nunjucks/filters/applyUrlParam.test.js.map +1 -0
- package/.server/server/plugins/nunjucks/filters/field.d.ts +1 -1
- package/.server/server/plugins/nunjucks/filters/index.d.ts +1 -0
- package/.server/server/plugins/nunjucks/filters/index.js +1 -0
- package/.server/server/plugins/nunjucks/filters/index.js.map +1 -1
- package/.server/server/plugins/payment/helper.d.ts +11 -1
- package/.server/server/plugins/payment/helper.js +18 -2
- package/.server/server/plugins/payment/helper.js.map +1 -1
- package/.server/server/plugins/payment/helper.test.js +2 -1
- package/.server/server/plugins/payment/helper.test.js.map +1 -1
- package/.server/server/plugins/payment/service.d.ts +2 -1
- package/.server/server/plugins/payment/service.js +5 -2
- package/.server/server/plugins/payment/service.js.map +1 -1
- package/.server/server/plugins/payment/service.test.js +7 -3
- package/.server/server/plugins/payment/service.test.js.map +1 -1
- package/.server/server/plugins/payment/types.d.ts +4 -0
- package/.server/server/plugins/payment/types.js +1 -0
- package/.server/server/plugins/payment/types.js.map +1 -1
- package/.server/server/plugins/postcode-lookup/models/index.d.ts +249 -3
- package/.server/server/plugins/postcode-lookup/models/index.js +87 -33
- package/.server/server/plugins/postcode-lookup/models/index.js.map +1 -1
- package/.server/server/plugins/postcode-lookup/routes/index.d.ts +15 -1
- package/.server/server/plugins/postcode-lookup/routes/index.js +47 -15
- package/.server/server/plugins/postcode-lookup/routes/index.js.map +1 -1
- package/.server/server/plugins/postcode-lookup/routes/index.test.js +84 -0
- package/.server/server/plugins/postcode-lookup/routes/index.test.js.map +1 -0
- package/.server/server/plugins/postcode-lookup/types.d.ts +12 -0
- package/.server/server/plugins/postcode-lookup/types.js +6 -1
- package/.server/server/plugins/postcode-lookup/types.js.map +1 -1
- package/.server/server/plugins/postcode-lookup/views/postcode-lookup-details.html +3 -3
- package/.server/server/utils/type-utils.d.ts +1 -2
- package/.server/server/utils/type-utils.js +0 -3
- package/.server/server/utils/type-utils.js.map +1 -1
- package/.server/server/utils/utils.d.ts +6 -0
- package/.server/server/utils/utils.js +18 -1
- package/.server/server/utils/utils.js.map +1 -1
- package/.server/server/utils/utils.test.js +21 -1
- package/.server/server/utils/utils.test.js.map +1 -1
- package/package.json +20 -5
- package/src/client/javascripts/file-upload.js +11 -3
- package/src/client/javascripts/geospatial-map.js +176 -81
- package/src/client/javascripts/govuk.js +2 -0
- package/src/client/javascripts/location-map.js +60 -4
- package/src/client/javascripts/map-constants.js +3 -0
- package/src/client/javascripts/map.js +47 -0
- package/src/client/javascripts/maps.js +5 -0
- package/src/client/javascripts/shared.js +1 -4
- package/src/client/javascripts/sssi-dataset.js +39 -41
- package/src/client/stylesheets/maps.scss +4 -0
- package/src/client/stylesheets/shared.scss +1 -5
- package/src/server/constants.js +2 -0
- package/src/server/plugins/engine/__stubs__/definitions.ts +155 -0
- package/src/server/plugins/engine/components/AutocompleteField.ts +13 -0
- package/src/server/plugins/engine/components/CheckboxesField.ts +38 -5
- package/src/server/plugins/engine/components/ComponentBase.ts +2 -0
- package/src/server/plugins/engine/components/ComponentCollection.ts +16 -11
- package/src/server/plugins/engine/components/DatePartsField.ts +20 -9
- package/src/server/plugins/engine/components/DeclarationField.ts +7 -6
- package/src/server/plugins/engine/components/EastingNorthingField.ts +185 -89
- package/src/server/plugins/engine/components/EmailAddressField.ts +2 -1
- package/src/server/plugins/engine/components/FileUploadField.ts +44 -3
- package/src/server/plugins/engine/components/FormComponent.ts +6 -5
- package/src/server/plugins/engine/components/GeospatialField.ts +47 -9
- package/src/server/plugins/engine/components/LatLongField.ts +128 -58
- package/src/server/plugins/engine/components/LocationFieldBase.ts +30 -7
- package/src/server/plugins/engine/components/LocationFieldHelpers.ts +28 -14
- package/src/server/plugins/engine/components/Markdown.ts +2 -3
- package/src/server/plugins/engine/components/MonthYearField.ts +20 -15
- package/src/server/plugins/engine/components/NationalGridFieldNumberField.ts +9 -3
- package/src/server/plugins/engine/components/NumberField.ts +21 -1
- package/src/server/plugins/engine/components/OsGridRefField.ts +22 -3
- package/src/server/plugins/engine/components/PaymentField.ts +15 -5
- package/src/server/plugins/engine/components/UkAddressField.ts +30 -7
- package/src/server/plugins/engine/components/YesNoField.ts +17 -9
- package/src/server/plugins/engine/components/helpers/components.ts +3 -3
- package/src/server/plugins/engine/components/helpers/geospatial.ts +84 -21
- package/src/server/plugins/engine/components/helpers/index.ts +19 -0
- package/src/server/plugins/engine/components/types.ts +1 -0
- package/src/server/plugins/engine/errors.ts +78 -0
- package/src/server/plugins/engine/form-availability.ts +8 -2
- package/src/server/plugins/engine/form-context.ts +4 -2
- package/src/server/plugins/engine/helpers.ts +52 -5
- package/src/server/plugins/engine/i18n/buildValidationMessages.ts +16 -8
- package/src/server/plugins/engine/i18n/createFormTranslator.ts +62 -11
- package/src/server/plugins/engine/i18n/extractBaseTranslations.ts +7 -1
- package/src/server/plugins/engine/i18n/form.ts +54 -0
- package/src/server/plugins/engine/i18n/languages.ts +19 -0
- package/src/server/plugins/engine/i18n/translations/cy.json +192 -9
- package/src/server/plugins/engine/i18n/translations/en-GB.json +125 -7
- package/src/server/plugins/engine/i18n/types.ts +3 -0
- package/src/server/plugins/engine/index.ts +7 -0
- package/src/server/plugins/engine/models/FormModel.ts +46 -23
- package/src/server/plugins/engine/models/SummaryViewModel.ts +6 -5
- package/src/server/plugins/engine/models/types.ts +31 -0
- package/src/server/plugins/engine/models/unavailable-view-model.ts +26 -5
- package/src/server/plugins/engine/outputFormatters/adapter/v1.ts +18 -7
- package/src/server/plugins/engine/outputFormatters/human/v1.ts +2 -1
- package/src/server/plugins/engine/outputFormatters/machine/v2.ts +3 -0
- package/src/server/plugins/engine/pageControllers/FileUploadPageController.ts +60 -9
- package/src/server/plugins/engine/pageControllers/QuestionPageController.ts +10 -5
- package/src/server/plugins/engine/pageControllers/RepeatPageController.ts +2 -2
- package/src/server/plugins/engine/pageControllers/SummaryPageController.ts +15 -4
- package/src/server/plugins/engine/pageControllers/helpers/pages.ts +2 -1
- package/src/server/plugins/engine/pageControllers/helpers/submission.ts +143 -4
- package/src/server/plugins/engine/pageControllers/validationOptions.ts +29 -4
- package/src/server/plugins/engine/types/enums.ts +4 -3
- package/src/server/plugins/engine/types/schema.ts +17 -4
- package/src/server/plugins/engine/types.ts +19 -1
- package/src/server/plugins/engine/unavailable-response.ts +6 -2
- package/src/server/plugins/engine/views/components/_location-field-base.html +4 -2
- package/src/server/plugins/engine/views/components/fileuploadfield.html +1 -1
- package/src/server/plugins/engine/views/components/geospatialfield.html +1 -0
- package/src/server/plugins/engine/views/components/multilinetextfield.html +12 -1
- package/src/server/plugins/engine/views/components/osgridreffield.html +4 -1
- package/src/server/plugins/engine/views/components/paymentfield.html +1 -1
- package/src/server/plugins/engine/views/components/ukaddressfield.html +1 -1
- package/src/server/plugins/engine/views/file-upload.html +1 -1
- package/src/server/plugins/engine/views/partials/preview-banner.html +3 -1
- package/src/server/plugins/engine/views/unavailable.html +14 -11
- package/src/server/plugins/nunjucks/filters/applyUrlParam.js +17 -0
- package/src/server/plugins/nunjucks/filters/index.js +1 -0
- package/src/server/plugins/payment/helper.js +22 -2
- package/src/server/plugins/payment/service.js +6 -2
- package/src/server/plugins/payment/types.js +1 -0
- package/src/server/plugins/postcode-lookup/models/index.js +75 -43
- package/src/server/plugins/postcode-lookup/routes/index.js +73 -16
- package/src/server/plugins/postcode-lookup/types.js +6 -1
- package/src/server/plugins/postcode-lookup/views/postcode-lookup-details.html +3 -3
- package/src/server/utils/type-utils.ts +1 -11
- package/src/server/utils/utils.js +19 -1
|
@@ -42,6 +42,7 @@ import {
|
|
|
42
42
|
type FormRequestPayload,
|
|
43
43
|
type FormResponseToolkit
|
|
44
44
|
} from '../../../routes/types.js'
|
|
45
|
+
import { joinWithOr } from '../../../utils/utils.js'
|
|
45
46
|
|
|
46
47
|
const MAX_UPLOADS = 25
|
|
47
48
|
const CDP_UPLOAD_TIMEOUT_MS = 60000 // 1 minute
|
|
@@ -188,17 +189,19 @@ export class FileUploadPageController extends QuestionPageController {
|
|
|
188
189
|
|
|
189
190
|
const { filename } = fileToRemove.status.form.file
|
|
190
191
|
|
|
191
|
-
const
|
|
192
|
+
const translator = this.getTranslator(request)
|
|
193
|
+
const { t } = translator
|
|
192
194
|
|
|
193
195
|
return h.view(this.fileDeleteViewName, {
|
|
194
196
|
...viewModel,
|
|
195
197
|
context,
|
|
196
198
|
backLink: this.getBackLink(request, context, t),
|
|
197
|
-
pageTitle:
|
|
199
|
+
pageTitle: t('pages.fileUpload.removeFileTitle'),
|
|
198
200
|
itemTitle: filename,
|
|
199
|
-
confirmation: { text: '
|
|
200
|
-
buttonConfirm: { text: '
|
|
201
|
-
buttonCancel: { text: '
|
|
201
|
+
confirmation: { text: t('pages.fileUpload.removeFileBody') },
|
|
202
|
+
buttonConfirm: { text: t('pages.fileUpload.removeFileButton') },
|
|
203
|
+
buttonCancel: { text: t('pages.fileUpload.cancel') },
|
|
204
|
+
t
|
|
202
205
|
} satisfies ItemDeletePageViewModel)
|
|
203
206
|
}
|
|
204
207
|
}
|
|
@@ -224,7 +227,7 @@ export class FileUploadPageController extends QuestionPageController {
|
|
|
224
227
|
}
|
|
225
228
|
}
|
|
226
229
|
|
|
227
|
-
getErrors(details?: ValidationErrorItem[]) {
|
|
230
|
+
getErrors(details?: ValidationErrorItem[], language?: string) {
|
|
228
231
|
const { fileUpload } = this
|
|
229
232
|
|
|
230
233
|
if (details) {
|
|
@@ -237,7 +240,7 @@ export class FileUploadPageController extends QuestionPageController {
|
|
|
237
240
|
if (!isUploadError || isUploadRootError) {
|
|
238
241
|
// The error is for the root of the upload or another
|
|
239
242
|
// field on the page so defer to the getError helper
|
|
240
|
-
errors.push(getError(error))
|
|
243
|
+
errors.push(getError(language, error))
|
|
241
244
|
} else {
|
|
242
245
|
const { context, path, type } = error
|
|
243
246
|
|
|
@@ -266,6 +269,7 @@ export class FileUploadPageController extends QuestionPageController {
|
|
|
266
269
|
): FeaturedFormPageViewModel {
|
|
267
270
|
const { fileUpload } = this
|
|
268
271
|
const { state } = context
|
|
272
|
+
const { t } = translator
|
|
269
273
|
|
|
270
274
|
const upload = this.getUploadFromState(state)
|
|
271
275
|
|
|
@@ -277,6 +281,19 @@ export class FileUploadPageController extends QuestionPageController {
|
|
|
277
281
|
({ model }) => model.id === fileUpload.name
|
|
278
282
|
)
|
|
279
283
|
|
|
284
|
+
formComponent.model.upload = {
|
|
285
|
+
count: formComponent.model.upload?.count ?? 0,
|
|
286
|
+
summaryList: formComponent.model.upload?.summaryList ?? { rows: [] },
|
|
287
|
+
uploadingLabel: t('components.fileUploadField.uploading')
|
|
288
|
+
}
|
|
289
|
+
formComponent.model = {
|
|
290
|
+
...formComponent.model,
|
|
291
|
+
javascript: true,
|
|
292
|
+
chooseFilesButtonText: t('components.fileUploadField.chooseFile'),
|
|
293
|
+
dropInstructionText: t('components.fileUploadField.dropFile'),
|
|
294
|
+
noFileChosenText: t('components.fileUploadField.noFileChosen')
|
|
295
|
+
}
|
|
296
|
+
|
|
280
297
|
const index = components.indexOf(formComponent)
|
|
281
298
|
|
|
282
299
|
const proxyUrl = getProxyUrlForLocalDevelopment(upload?.uploadUrl)
|
|
@@ -290,7 +307,8 @@ export class FileUploadPageController extends QuestionPageController {
|
|
|
290
307
|
// Split out components before/after
|
|
291
308
|
componentsBefore: components.slice(0, index),
|
|
292
309
|
components: components.slice(index),
|
|
293
|
-
proxyUrl
|
|
310
|
+
proxyUrl,
|
|
311
|
+
t
|
|
294
312
|
}
|
|
295
313
|
}
|
|
296
314
|
|
|
@@ -441,6 +459,9 @@ export class FileUploadPageController extends QuestionPageController {
|
|
|
441
459
|
|
|
442
460
|
const allErrors: FormSubmissionError[] = []
|
|
443
461
|
|
|
462
|
+
const translator = this.getTranslator(request)
|
|
463
|
+
const { t } = translator
|
|
464
|
+
|
|
444
465
|
for (const file of uploadedFiles) {
|
|
445
466
|
if (file.fileStatus === FileStatus.complete) {
|
|
446
467
|
const perFileState: FileState = {
|
|
@@ -455,7 +476,14 @@ export class FileUploadPageController extends QuestionPageController {
|
|
|
455
476
|
// Collect the error for rejected/pending files.
|
|
456
477
|
const { fileUpload } = this
|
|
457
478
|
const name = fileUpload.name
|
|
458
|
-
const
|
|
479
|
+
const errorParams = this.expandErrorParams(
|
|
480
|
+
file.errorParams,
|
|
481
|
+
t('common.or')
|
|
482
|
+
)
|
|
483
|
+
const text = t(
|
|
484
|
+
`pages.fileUpload.${file.errorCode ?? 'FILE_ERROR_UNKNOWN'}`,
|
|
485
|
+
errorParams
|
|
486
|
+
)
|
|
459
487
|
allErrors.push({ path: [name], href: `#${name}`, name, text })
|
|
460
488
|
}
|
|
461
489
|
}
|
|
@@ -472,6 +500,29 @@ export class FileUploadPageController extends QuestionPageController {
|
|
|
472
500
|
}
|
|
473
501
|
}
|
|
474
502
|
|
|
503
|
+
/**
|
|
504
|
+
* Process the error parameters so any arrays get expanded (joined), ready to be passed into the error message
|
|
505
|
+
* @param errorParams - received from the file upload (may be a number, a string, or a string array)
|
|
506
|
+
* @param finalSeparator - 'or' in English, and 'neu' in Welsh
|
|
507
|
+
*/
|
|
508
|
+
private expandErrorParams(
|
|
509
|
+
errorParams: Record<string, number | string | string[]> | undefined,
|
|
510
|
+
finalSeparator: string
|
|
511
|
+
) {
|
|
512
|
+
if (!errorParams) {
|
|
513
|
+
return {}
|
|
514
|
+
}
|
|
515
|
+
const expanded = {} as Record<string, number | string>
|
|
516
|
+
for (const [key, value] of Object.entries(errorParams)) {
|
|
517
|
+
if (Array.isArray(value)) {
|
|
518
|
+
expanded[key] = joinWithOr(value, finalSeparator)
|
|
519
|
+
} else {
|
|
520
|
+
expanded[key] = value
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
return expanded
|
|
524
|
+
}
|
|
525
|
+
|
|
475
526
|
/**
|
|
476
527
|
* Checks the payload for a file getting removed
|
|
477
528
|
* and removes it from the upload files if found
|
|
@@ -174,9 +174,14 @@ export class QuestionPageController extends PageController {
|
|
|
174
174
|
if (!pageTitle) {
|
|
175
175
|
pageTitle = labelOrLegend.text
|
|
176
176
|
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
177
|
+
|
|
178
|
+
// The question text may have already appended 'optional' in the relevant language
|
|
179
|
+
const optionalWord = t('common.optional')
|
|
180
|
+
const optionalAlreadyAppended = pageTitle.endsWith(` ${optionalWord}`)
|
|
181
|
+
labelOrLegend.text =
|
|
182
|
+
isOptional && !optionalAlreadyAppended
|
|
183
|
+
? `${pageTitle} ${optionalWord}`
|
|
184
|
+
: pageTitle
|
|
180
185
|
}
|
|
181
186
|
|
|
182
187
|
// Fallback if still no pageTitle set
|
|
@@ -359,8 +364,8 @@ export class QuestionPageController extends PageController {
|
|
|
359
364
|
return this.collection.getStateFromValidForm(payload)
|
|
360
365
|
}
|
|
361
366
|
|
|
362
|
-
getErrors(details?: ValidationErrorItem[]) {
|
|
363
|
-
return getErrors(details)
|
|
367
|
+
getErrors(details?: ValidationErrorItem[], language?: string) {
|
|
368
|
+
return getErrors(language, details)
|
|
364
369
|
}
|
|
365
370
|
|
|
366
371
|
async getState(request: AnyFormRequest) {
|
|
@@ -406,9 +406,9 @@ export class RepeatPageController extends QuestionPageController {
|
|
|
406
406
|
const { query } = request
|
|
407
407
|
const { isForceAccess, errors } = context
|
|
408
408
|
|
|
409
|
-
const { t } = translator
|
|
409
|
+
const { t, tPage } = translator
|
|
410
410
|
|
|
411
|
-
const
|
|
411
|
+
const title = tPage(this.pageDef, 'repeatTitle') || repeat.options.title
|
|
412
412
|
|
|
413
413
|
const summaryList: SummaryList = {
|
|
414
414
|
classes: 'govuk-summary-list--long-actions',
|
|
@@ -114,7 +114,7 @@ export class SummaryPageController extends QuestionPageController {
|
|
|
114
114
|
viewModel.paymentDetails = this.buildPaymentDetails(
|
|
115
115
|
paymentField,
|
|
116
116
|
paymentState,
|
|
117
|
-
|
|
117
|
+
translator
|
|
118
118
|
)
|
|
119
119
|
}
|
|
120
120
|
|
|
@@ -151,8 +151,9 @@ export class SummaryPageController extends QuestionPageController {
|
|
|
151
151
|
paymentState: NonNullable<
|
|
152
152
|
ReturnType<PaymentField['getPaymentStateFromState']>
|
|
153
153
|
>,
|
|
154
|
-
|
|
154
|
+
translator: Translator
|
|
155
155
|
) {
|
|
156
|
+
const { t } = translator
|
|
156
157
|
const rows = [
|
|
157
158
|
{
|
|
158
159
|
key: { text: t('pages.summary.paymentFor') },
|
|
@@ -171,7 +172,12 @@ export class SummaryPageController extends QuestionPageController {
|
|
|
171
172
|
if (paymentState.preAuth?.createdAt) {
|
|
172
173
|
rows.push({
|
|
173
174
|
key: { text: t('pages.summary.dateOfPayment') },
|
|
174
|
-
value: {
|
|
175
|
+
value: {
|
|
176
|
+
text: formatPaymentDate(
|
|
177
|
+
paymentState.preAuth.createdAt,
|
|
178
|
+
translator.language
|
|
179
|
+
)
|
|
180
|
+
}
|
|
175
181
|
})
|
|
176
182
|
}
|
|
177
183
|
|
|
@@ -557,7 +563,12 @@ function submitData(
|
|
|
557
563
|
retrievalKey,
|
|
558
564
|
referenceNumber,
|
|
559
565
|
main: buildMainRecords(items, translator),
|
|
560
|
-
repeaters: buildRepeaterRecords(items, translator)
|
|
566
|
+
repeaters: buildRepeaterRecords(items, translator),
|
|
567
|
+
// Only populate the language property if the form is multi-language enabled
|
|
568
|
+
// @ts-expect-error - dynamic language property
|
|
569
|
+
language: model.def.metadata?.translations?.cy
|
|
570
|
+
? translator.language
|
|
571
|
+
: undefined
|
|
561
572
|
}
|
|
562
573
|
return submit(payload)
|
|
563
574
|
}
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
type Page
|
|
5
5
|
} from '@defra/forms-model'
|
|
6
6
|
|
|
7
|
+
import { UnknownPageControllerError } from '../../errors.js'
|
|
7
8
|
import { type FormModel } from '../../models/index.js'
|
|
8
9
|
import * as PageControllers from '../index.js'
|
|
9
10
|
|
|
@@ -66,7 +67,7 @@ export function createPage(model: FormModel, pageDef: Page) {
|
|
|
66
67
|
}
|
|
67
68
|
|
|
68
69
|
if (typeof controller === 'undefined') {
|
|
69
|
-
throw new
|
|
70
|
+
throw new UnknownPageControllerError(pageDef.controller)
|
|
70
71
|
}
|
|
71
72
|
|
|
72
73
|
return controller
|
|
@@ -1,13 +1,27 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
isConditionWrapperV2,
|
|
3
|
+
type ConditionDataV2,
|
|
4
|
+
type ConditionRefDataV2,
|
|
5
|
+
type ConditionWrapperV2,
|
|
6
|
+
type SubmitConditionEvaluation,
|
|
7
|
+
type SubmitConditionReference,
|
|
8
|
+
type SubmitPayload
|
|
9
|
+
} from '@defra/forms-model'
|
|
2
10
|
|
|
3
11
|
import { GeospatialField } from '../../components/GeospatialField.js'
|
|
4
12
|
import { PaymentField } from '../../components/PaymentField.js'
|
|
5
13
|
import { getAnswer } from '../../components/helpers/components.js'
|
|
6
14
|
import { type Translator } from '../../i18n/types.js'
|
|
15
|
+
import { type FormModel } from '../../models/FormModel.js'
|
|
7
16
|
import {
|
|
8
17
|
type DetailItem,
|
|
9
18
|
type DetailItemField
|
|
10
19
|
} from '../../models/types.js'
|
|
20
|
+
import {
|
|
21
|
+
type FormContext,
|
|
22
|
+
type FormState,
|
|
23
|
+
type FormStateValue
|
|
24
|
+
} from '../../types.js'
|
|
11
25
|
import {
|
|
12
26
|
formatCurrency,
|
|
13
27
|
formatPaymentDate
|
|
@@ -36,7 +50,7 @@ export function buildMainRecords(
|
|
|
36
50
|
|
|
37
51
|
for (const item of fieldItems) {
|
|
38
52
|
if (item.field instanceof PaymentField) {
|
|
39
|
-
records.push(...buildPaymentRecords(item))
|
|
53
|
+
records.push(...buildPaymentRecords(item, translator))
|
|
40
54
|
} else if (item.field instanceof GeospatialField) {
|
|
41
55
|
// Stringify of GeoJSON is done here rather than inside `getContextValueFromState`
|
|
42
56
|
// so we don't incur the overhead of JSON.stringify on every request when building context
|
|
@@ -67,7 +81,10 @@ export function buildMainRecords(
|
|
|
67
81
|
*
|
|
68
82
|
* Returns an empty array if no payment state exists.
|
|
69
83
|
*/
|
|
70
|
-
export function buildPaymentRecords(
|
|
84
|
+
export function buildPaymentRecords(
|
|
85
|
+
item: DetailItemField,
|
|
86
|
+
translator: Translator
|
|
87
|
+
): SubmitRecord[] {
|
|
71
88
|
const paymentState = (item.field as PaymentField).getPaymentStateFromState(
|
|
72
89
|
item.state
|
|
73
90
|
)
|
|
@@ -96,7 +113,7 @@ export function buildPaymentRecords(item: DetailItemField): SubmitRecord[] {
|
|
|
96
113
|
name: `${item.name}_paymentDate`,
|
|
97
114
|
title: 'Payment date',
|
|
98
115
|
value: paymentState.preAuth?.createdAt
|
|
99
|
-
? formatPaymentDate(paymentState.preAuth.createdAt)
|
|
116
|
+
? formatPaymentDate(paymentState.preAuth.createdAt, translator.language)
|
|
100
117
|
: ''
|
|
101
118
|
}
|
|
102
119
|
]
|
|
@@ -138,3 +155,125 @@ export function buildRepeaterRecords(
|
|
|
138
155
|
)
|
|
139
156
|
}))
|
|
140
157
|
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Records the outcome of every condition in the form definition, evaluated
|
|
161
|
+
* against the answers as they stand at the point of submission.
|
|
162
|
+
*
|
|
163
|
+
* Evaluated here rather than by the consumer because only the engine holds
|
|
164
|
+
* the context to evaluate against: `evaluationState` is built by walking the
|
|
165
|
+
* form from its start page along the path taken, applying page conditions as
|
|
166
|
+
* it goes. A consumer receives the flat submitted answers, not that walked
|
|
167
|
+
* state, and reproducing the walk in a second codebase would leave two
|
|
168
|
+
* implementations of the same logic free to diverge.
|
|
169
|
+
*
|
|
170
|
+
* Each record carries the components the condition depends on and whether each
|
|
171
|
+
* was answered. An unanswered question still yields a boolean - negative
|
|
172
|
+
* operators such as "is not" return `true` against the seeded `null` - so the
|
|
173
|
+
* outcome alone cannot be read as evidence that the user gave that answer.
|
|
174
|
+
*
|
|
175
|
+
* V2 definitions only. `conditionId` is the V2 condition id, and the
|
|
176
|
+
* references are resolved from the component ids V2 conditions carry - V1
|
|
177
|
+
* conditions reference components by name, and V1 components need not have
|
|
178
|
+
* an id at all.
|
|
179
|
+
*/
|
|
180
|
+
export function buildConditionEvaluations(
|
|
181
|
+
model: FormModel,
|
|
182
|
+
context: FormContext
|
|
183
|
+
): SubmitConditionEvaluation[] {
|
|
184
|
+
const { evaluationState } = context
|
|
185
|
+
|
|
186
|
+
return model.def.conditions
|
|
187
|
+
.filter(isConditionWrapperV2)
|
|
188
|
+
.flatMap((conditionDef) => {
|
|
189
|
+
const condition = model.conditions[conditionDef.id]
|
|
190
|
+
|
|
191
|
+
if (!condition) {
|
|
192
|
+
return []
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const { outcome } = condition.evaluate(evaluationState)
|
|
196
|
+
|
|
197
|
+
const references = collectReferences(model, conditionDef, evaluationState)
|
|
198
|
+
|
|
199
|
+
return {
|
|
200
|
+
conditionId: conditionDef.id,
|
|
201
|
+
outcome,
|
|
202
|
+
references: [...references.values()]
|
|
203
|
+
}
|
|
204
|
+
})
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Whether a component held an answer at the point a condition was evaluated.
|
|
209
|
+
*
|
|
210
|
+
* The engine seeds every component in `evaluationState` with `null` before the
|
|
211
|
+
* page walk begins, so an unanswered question is present but empty rather than
|
|
212
|
+
* absent.
|
|
213
|
+
* @see {@link FormModel.initialiseContext}
|
|
214
|
+
*/
|
|
215
|
+
export function isAnswered(value: FormStateValue | undefined) {
|
|
216
|
+
if (value === undefined || value === null) {
|
|
217
|
+
return false
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
if (Array.isArray(value)) {
|
|
221
|
+
return value.length > 0
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
return value !== ''
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
function isConditionDataV2(
|
|
228
|
+
item: ConditionDataV2 | ConditionRefDataV2
|
|
229
|
+
): item is ConditionDataV2 {
|
|
230
|
+
return 'componentId' in item
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Recursive function that collects every component a condition depends on, following nested condition
|
|
235
|
+
* references. Results are keyed by component id so a component referenced more
|
|
236
|
+
* than once is reported once.
|
|
237
|
+
*/
|
|
238
|
+
function collectReferences(
|
|
239
|
+
model: FormModel,
|
|
240
|
+
conditionDef: ConditionWrapperV2,
|
|
241
|
+
evaluationState: FormState,
|
|
242
|
+
references: Map<string, SubmitConditionReference> = new Map<
|
|
243
|
+
string,
|
|
244
|
+
SubmitConditionReference
|
|
245
|
+
>(),
|
|
246
|
+
visited: Set<string> = new Set<string>()
|
|
247
|
+
) {
|
|
248
|
+
if (visited.has(conditionDef.id)) {
|
|
249
|
+
return references
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
visited.add(conditionDef.id)
|
|
253
|
+
|
|
254
|
+
for (const item of conditionDef.items) {
|
|
255
|
+
if (isConditionDataV2(item)) {
|
|
256
|
+
const component = model.getComponentById(item.componentId)
|
|
257
|
+
|
|
258
|
+
// A condition referencing a component that no longer exists cannot be
|
|
259
|
+
// resolved to a name, so there is nothing meaningful to report for it
|
|
260
|
+
if (component) {
|
|
261
|
+
references.set(item.componentId, {
|
|
262
|
+
componentId: item.componentId,
|
|
263
|
+
componentName: component.name,
|
|
264
|
+
answered: isAnswered(evaluationState[component.name])
|
|
265
|
+
})
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
continue
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
const referenced = model.getConditionById(item.conditionId)
|
|
272
|
+
|
|
273
|
+
if (referenced) {
|
|
274
|
+
collectReferences(model, referenced, evaluationState, references, visited)
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
return references
|
|
279
|
+
}
|
|
@@ -26,7 +26,7 @@ export const opts = {
|
|
|
26
26
|
* import messageTemplate directly and get the English version.
|
|
27
27
|
*/
|
|
28
28
|
export const messageTemplate: ValidationMessages = buildValidationMessages(
|
|
29
|
-
(key) => t(key, 'en-GB')
|
|
29
|
+
(key, options) => t(key, 'en-GB', options)
|
|
30
30
|
)
|
|
31
31
|
|
|
32
32
|
export const messages: LanguageMessagesExt = {
|
|
@@ -58,14 +58,28 @@ export const messages: LanguageMessagesExt = {
|
|
|
58
58
|
'date.min': messageTemplate.dateMin,
|
|
59
59
|
'date.max': messageTemplate.dateMax,
|
|
60
60
|
|
|
61
|
-
'
|
|
61
|
+
'array.min': messageTemplate.arrayMin,
|
|
62
|
+
'array.max': messageTemplate.arrayMax,
|
|
63
|
+
'array.length': messageTemplate.arrayLength,
|
|
64
|
+
|
|
65
|
+
'features.min': messageTemplate.featuresMin,
|
|
66
|
+
'features.max': messageTemplate.featuresMax,
|
|
67
|
+
'features.length': messageTemplate.featuresLength,
|
|
68
|
+
|
|
69
|
+
'files.min': messageTemplate.filesMin,
|
|
70
|
+
'files.max': messageTemplate.filesMax,
|
|
71
|
+
'filees.length': messageTemplate.filesLength,
|
|
72
|
+
|
|
73
|
+
'object.invalidjson': messageTemplate.format,
|
|
74
|
+
|
|
75
|
+
'phoneNumber.invalid': messageTemplate.format
|
|
62
76
|
}
|
|
63
77
|
|
|
64
78
|
export const messagesPre: LanguageMessages =
|
|
65
79
|
messages as unknown as LanguageMessages
|
|
66
80
|
|
|
67
81
|
export function buildLanguageMessages(
|
|
68
|
-
t: (key: string) => string
|
|
82
|
+
t: (key: string, options?: Record<string, unknown>) => string
|
|
69
83
|
): LanguageMessages {
|
|
70
84
|
const vm = buildValidationMessages(t)
|
|
71
85
|
return {
|
|
@@ -76,6 +90,7 @@ export function buildLanguageMessages(
|
|
|
76
90
|
'string.email': vm.format,
|
|
77
91
|
'string.pattern.base': vm.pattern,
|
|
78
92
|
'string.maxWords': vm.maxWords,
|
|
93
|
+
'string.unicode': vm.unicode,
|
|
79
94
|
'number.base': vm.number,
|
|
80
95
|
'number.precision': vm.numberPrecision,
|
|
81
96
|
'number.integer': vm.numberInteger,
|
|
@@ -91,7 +106,17 @@ export function buildLanguageMessages(
|
|
|
91
106
|
'date.format': vm.dateFormat,
|
|
92
107
|
'date.min': vm.dateMin,
|
|
93
108
|
'date.max': vm.dateMax,
|
|
94
|
-
'
|
|
109
|
+
'array.min': vm.arrayMin,
|
|
110
|
+
'array.max': vm.arrayMax,
|
|
111
|
+
'array.length': vm.arrayLength,
|
|
112
|
+
'features.min': vm.featuresMin,
|
|
113
|
+
'features.max': vm.featuresMax,
|
|
114
|
+
'features.length': vm.featuresLength,
|
|
115
|
+
'files.min': vm.filesMin,
|
|
116
|
+
'files.max': vm.filesMax,
|
|
117
|
+
'files.length': vm.filesLength,
|
|
118
|
+
'object.invalidjson': vm.format,
|
|
119
|
+
'phoneNumber.invalid': vm.format
|
|
95
120
|
} as unknown as LanguageMessages
|
|
96
121
|
}
|
|
97
122
|
|
|
@@ -10,6 +10,7 @@ export enum FileStatus {
|
|
|
10
10
|
pending = 'pending'
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
// Changed from an enum to enforce numeric values
|
|
14
|
+
export const FormAdapterSubmissionSchemaVersion = {
|
|
15
|
+
V1: 1
|
|
16
|
+
} as const satisfies Record<string, number>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
FormStatus,
|
|
3
|
+
formSubmitConditionEvaluationSchema,
|
|
3
4
|
formVersionMetadataSchema,
|
|
4
5
|
idSchema,
|
|
5
6
|
notificationEmailAddressSchema,
|
|
@@ -18,9 +19,9 @@ import {
|
|
|
18
19
|
|
|
19
20
|
export const formAdapterSubmissionMessageMetaSchema =
|
|
20
21
|
Joi.object<FormAdapterSubmissionMessageMeta>().keys({
|
|
21
|
-
schemaVersion: Joi.
|
|
22
|
-
...Object.values(FormAdapterSubmissionSchemaVersion)
|
|
23
|
-
|
|
22
|
+
schemaVersion: Joi.number()
|
|
23
|
+
.valid(...Object.values(FormAdapterSubmissionSchemaVersion))
|
|
24
|
+
.required(),
|
|
24
25
|
timestamp: Joi.date().required(),
|
|
25
26
|
referenceNumber: Joi.string().required(),
|
|
26
27
|
formName: titleSchema,
|
|
@@ -50,6 +51,7 @@ export const formAdapterSubmissionMessageDataSchema =
|
|
|
50
51
|
reference: Joi.string().required(),
|
|
51
52
|
amount: Joi.number().required(),
|
|
52
53
|
description: Joi.string().required(),
|
|
54
|
+
descriptionInEng: Joi.string().optional(),
|
|
53
55
|
createdAt: Joi.string().required()
|
|
54
56
|
})
|
|
55
57
|
.optional(),
|
|
@@ -79,5 +81,16 @@ export const formAdapterSubmissionMessagePayloadSchema =
|
|
|
79
81
|
Joi.object<FormAdapterSubmissionMessagePayload>().keys({
|
|
80
82
|
meta: formAdapterSubmissionMessageMetaSchema.required(),
|
|
81
83
|
data: formAdapterSubmissionMessageDataSchema.required(),
|
|
82
|
-
result: formAdapterSubmissionMessageResultSchema.required()
|
|
84
|
+
result: formAdapterSubmissionMessageResultSchema.required(),
|
|
85
|
+
// Optional so that messages published before this existed - which may
|
|
86
|
+
// still be in flight or sitting on a dead-letter queue - continue to
|
|
87
|
+
// validate. Consumers treat its absence as "resolve the recipients from
|
|
88
|
+
// the form definition yourself"
|
|
89
|
+
// This should be required at a later point in time.
|
|
90
|
+
conditionEvaluations: Joi.array()
|
|
91
|
+
.items(formSubmitConditionEvaluationSchema)
|
|
92
|
+
.optional()
|
|
93
|
+
.description(
|
|
94
|
+
'Outcome of every condition in the form definition, evaluated against the final answers at submission'
|
|
95
|
+
)
|
|
83
96
|
})
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
type List,
|
|
7
7
|
type Page,
|
|
8
8
|
type PaymentFieldComponent,
|
|
9
|
+
type SubmitConditionEvaluation,
|
|
9
10
|
type UkAddressFieldComponent
|
|
10
11
|
} from '@defra/forms-model'
|
|
11
12
|
import {
|
|
@@ -245,11 +246,15 @@ export type FileUpload = {
|
|
|
245
246
|
} & (
|
|
246
247
|
| {
|
|
247
248
|
fileStatus: FileStatus.complete | FileStatus.rejected | FileStatus.pending
|
|
249
|
+
errorCode?: string
|
|
248
250
|
errorMessage?: string
|
|
251
|
+
errorParams?: Record<string, number | string | string[]>
|
|
249
252
|
}
|
|
250
253
|
| {
|
|
251
254
|
fileStatus: FileStatus.complete
|
|
255
|
+
errorCode?: string
|
|
252
256
|
errorMessage?: undefined
|
|
257
|
+
errorParams?: Record<string, number | string | string[]>
|
|
253
258
|
}
|
|
254
259
|
)
|
|
255
260
|
|
|
@@ -525,7 +530,7 @@ export interface PluginOptions {
|
|
|
525
530
|
}
|
|
526
531
|
|
|
527
532
|
export interface FormAdapterSubmissionMessageMeta {
|
|
528
|
-
schemaVersion: FormAdapterSubmissionSchemaVersion
|
|
533
|
+
schemaVersion: (typeof FormAdapterSubmissionSchemaVersion)[keyof typeof FormAdapterSubmissionSchemaVersion]
|
|
529
534
|
timestamp: Date
|
|
530
535
|
referenceNumber: string
|
|
531
536
|
formName: string
|
|
@@ -558,6 +563,7 @@ export interface FormAdapterPayment {
|
|
|
558
563
|
reference: string
|
|
559
564
|
amount: number
|
|
560
565
|
description: string
|
|
566
|
+
descriptionInEng?: string
|
|
561
567
|
createdAt: string
|
|
562
568
|
}
|
|
563
569
|
|
|
@@ -602,6 +608,18 @@ export interface FormAdapterSubmissionMessagePayload {
|
|
|
602
608
|
meta: FormAdapterSubmissionMessageMeta
|
|
603
609
|
data: FormAdapterSubmissionMessageData
|
|
604
610
|
result: FormAdapterSubmissionMessageResult
|
|
611
|
+
|
|
612
|
+
/**
|
|
613
|
+
* The outcome of every condition in the form definition, evaluated against
|
|
614
|
+
* the final answers at the point of submission.
|
|
615
|
+
*
|
|
616
|
+
* Always emitted, empty when there is nothing to report - a V1-engine form
|
|
617
|
+
* has no stable condition ids to record against. Optional only for
|
|
618
|
+
* backwards compatibility: a message published before this existed carries
|
|
619
|
+
* no evaluations at all, and consumers fall back to resolving the recipients
|
|
620
|
+
* from the form definition themselves.
|
|
621
|
+
*/
|
|
622
|
+
conditionEvaluations?: SubmitConditionEvaluation[]
|
|
605
623
|
}
|
|
606
624
|
|
|
607
625
|
export interface FormAdapterSubmissionMessage extends FormAdapterSubmissionMessagePayload {
|
|
@@ -2,6 +2,8 @@ import { type Request, type ResponseToolkit, type Server } from '@hapi/hapi'
|
|
|
2
2
|
|
|
3
3
|
import { isOfflineBoom } from './form-availability.js'
|
|
4
4
|
import { unavailableViewModel } from './models/unavailable-view-model.js'
|
|
5
|
+
import { type AnyFormRequest } from './types.js'
|
|
6
|
+
import { resolveLanguage } from '../../utils/utils.js'
|
|
5
7
|
|
|
6
8
|
/**
|
|
7
9
|
* Registers a server-wide onPreResponse extension that intercepts the offline
|
|
@@ -17,10 +19,12 @@ export function registerUnavailableResponse(server: Server) {
|
|
|
17
19
|
return h.continue
|
|
18
20
|
}
|
|
19
21
|
|
|
20
|
-
const { metadata } = response.data
|
|
22
|
+
const { metadata, definition } = response.data
|
|
23
|
+
|
|
24
|
+
const language = resolveLanguage(request as unknown as AnyFormRequest)
|
|
21
25
|
|
|
22
26
|
return h
|
|
23
|
-
.view('unavailable', unavailableViewModel(metadata))
|
|
27
|
+
.view('unavailable', unavailableViewModel(metadata, definition, language))
|
|
24
28
|
.header('Cache-Control', 'no-store, no-cache, must-revalidate')
|
|
25
29
|
.header('X-Robots-Tag', 'noindex, nofollow')
|
|
26
30
|
.code(200)
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
{% set detailsHtml %}
|
|
62
62
|
{% if component.model.instructionText %}
|
|
63
63
|
{{ govukDetails({
|
|
64
|
-
summaryText:
|
|
64
|
+
summaryText: component.model.instructionSummary,
|
|
65
65
|
html: component.model.instructionText | markdown | safe,
|
|
66
66
|
classes: "govuk-!-margin-top-3"
|
|
67
67
|
}) }}
|
|
@@ -70,8 +70,10 @@
|
|
|
70
70
|
|
|
71
71
|
{% set hasErrors = showFieldsetError and component.model.errorMessage %}
|
|
72
72
|
|
|
73
|
-
<div class="govuk-form-group app-location-field {{ "govuk-form-group--error" if hasErrors }}"
|
|
73
|
+
<div id="{{component.model.name}}" class="govuk-form-group app-location-field {{ "govuk-form-group--error" if hasErrors }}"
|
|
74
74
|
data-locationtype="{{component.type | lower}}"
|
|
75
|
+
data-country="{{component.model.country}}"
|
|
76
|
+
data-lang="{{component.model.lang}}"
|
|
75
77
|
data-maplayers="{{component.model.mapLayers}}">
|
|
76
78
|
{{ govukFieldset({
|
|
77
79
|
legend: {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
{% macro FileUploadField(component) %}
|
|
4
4
|
{% set upload = component.model.upload %}
|
|
5
5
|
|
|
6
|
-
<div id="uploadedFilesContainer">
|
|
6
|
+
<div id="uploadedFilesContainer" data-uploadinglabel="{{ upload.uploadingLabel }}">
|
|
7
7
|
<h2 class="govuk-heading-m">{{ t('components.fileUploadField.uploadedFilesHeading') }}</h2>
|
|
8
8
|
{% if upload.count %}
|
|
9
9
|
<p class="govuk-body" role="alert">{{ t('components.fileUploadField.filesCount', { count: upload.count }) }}</p>
|