@defra/forms-engine-plugin 5.0.0-alpha.1 → 5.0.0-alpha.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.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.js +10 -31
- 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.js +11 -2
- package/.server/client/javascripts/location-map.js.map +1 -1
- package/.server/client/javascripts/map.d.ts +6 -0
- package/.server/client/javascripts/map.js +37 -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 -3
- package/.server/client/javascripts/shared.js +1 -3
- 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/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 +4 -1
- package/.server/server/plugins/engine/components/CheckboxesField.js +13 -0
- 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 +29 -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 +12 -0
- package/.server/server/plugins/engine/components/FileUploadField.js +23 -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 +1 -0
- package/.server/server/plugins/engine/components/GeospatialField.js +1 -1
- 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 +28 -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 +18 -5
- package/.server/server/plugins/engine/components/LocationFieldBase.js.map +1 -1
- package/.server/server/plugins/engine/components/LocationFieldHelpers.d.ts +8 -3
- package/.server/server/plugins/engine/components/LocationFieldHelpers.js +13 -12
- 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 +2 -1
- package/.server/server/plugins/engine/components/OsGridRefField.js +4 -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 +1 -2
- package/.server/server/plugins/engine/components/helpers/components.js.map +1 -1
- package/.server/server/plugins/engine/components/helpers/geospatial.d.ts +3 -1
- package/.server/server/plugins/engine/components/helpers/geospatial.js +32 -0
- 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/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 +3 -0
- package/.server/server/plugins/engine/i18n/buildValidationMessages.js +10 -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 +85 -8
- package/.server/server/plugins/engine/i18n/translations/en-GB.json +55 -6
- package/.server/server/plugins/engine/i18n/types.d.ts +2 -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 +9 -15
- 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/outputFormatters/adapter/v1.js +3 -5
- 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/submission.d.ts +1 -1
- package/.server/server/plugins/engine/pageControllers/helpers/submission.js +3 -3
- package/.server/server/plugins/engine/pageControllers/helpers/submission.js.map +1 -1
- package/.server/server/plugins/engine/pageControllers/validationOptions.js +23 -2
- package/.server/server/plugins/engine/pageControllers/validationOptions.js.map +1 -1
- package/.server/server/plugins/engine/types/schema.js +1 -0
- package/.server/server/plugins/engine/types/schema.js.map +1 -1
- package/.server/server/plugins/engine/types.d.ts +5 -0
- package/.server/server/plugins/engine/types.js.map +1 -1
- package/.server/server/plugins/engine/views/components/_location-field-base.html +2 -1
- package/.server/server/plugins/engine/views/components/fileuploadfield.html +1 -1
- package/.server/server/plugins/engine/views/components/multilinetextfield.html +12 -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/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 +9 -2
- package/src/client/javascripts/file-upload.js +11 -3
- package/src/client/javascripts/geospatial-map.js +7 -34
- package/src/client/javascripts/govuk.js +2 -0
- package/src/client/javascripts/location-map.js +9 -1
- package/src/client/javascripts/map.js +42 -0
- package/src/client/javascripts/maps.js +5 -0
- package/src/client/javascripts/shared.js +1 -3
- 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/components/AutocompleteField.ts +13 -0
- package/src/server/plugins/engine/components/CheckboxesField.ts +13 -1
- 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 +24 -3
- package/src/server/plugins/engine/components/FormComponent.ts +6 -5
- package/src/server/plugins/engine/components/GeospatialField.ts +6 -1
- package/src/server/plugins/engine/components/LatLongField.ts +128 -58
- package/src/server/plugins/engine/components/LocationFieldBase.ts +23 -6
- package/src/server/plugins/engine/components/LocationFieldHelpers.ts +20 -13
- 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 +9 -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 +1 -2
- package/src/server/plugins/engine/components/helpers/geospatial.ts +53 -0
- 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/helpers.ts +52 -5
- package/src/server/plugins/engine/i18n/buildValidationMessages.ts +10 -7
- 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 +85 -8
- package/src/server/plugins/engine/i18n/translations/en-GB.json +55 -6
- package/src/server/plugins/engine/i18n/types.ts +2 -0
- package/src/server/plugins/engine/index.ts +7 -0
- package/src/server/plugins/engine/models/FormModel.ts +9 -15
- package/src/server/plugins/engine/models/SummaryViewModel.ts +6 -5
- package/src/server/plugins/engine/outputFormatters/adapter/v1.ts +3 -6
- 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/submission.ts +6 -3
- package/src/server/plugins/engine/pageControllers/validationOptions.ts +27 -2
- package/src/server/plugins/engine/types/schema.ts +1 -0
- package/src/server/plugins/engine/types.ts +5 -0
- package/src/server/plugins/engine/views/components/_location-field-base.html +2 -1
- package/src/server/plugins/engine/views/components/fileuploadfield.html +1 -1
- package/src/server/plugins/engine/views/components/multilinetextfield.html +12 -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/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
|
@@ -4,11 +4,9 @@ import { ComponentCollection } from "./ComponentCollection.js";
|
|
|
4
4
|
import { FormComponent, isFormState } from "./FormComponent.js";
|
|
5
5
|
import { deduplicateErrorsByHref, getLocationFieldViewModel } from "./LocationFieldHelpers.js";
|
|
6
6
|
import { NumberField } from "./NumberField.js";
|
|
7
|
-
import { createLowerFirstExpression } from "./helpers/index.js";
|
|
7
|
+
import { createLowerFirstExpression, getTranslatedLabel } from "./helpers/index.js";
|
|
8
8
|
import { t as tPlugin } from "../i18n/index.js";
|
|
9
9
|
import { messageTemplate } from "../pageControllers/validationOptions.js";
|
|
10
|
-
import { convertToLanguageMessages } from "../../../utils/type-utils.js";
|
|
11
|
-
|
|
12
10
|
// Precision constants
|
|
13
11
|
// UK latitude/longitude requires high precision for accurate location (within ~11mm)
|
|
14
12
|
const DECIMAL_PRECISION = 7; // 7 decimal places
|
|
@@ -22,45 +20,16 @@ export class LatLongField extends FormComponent {
|
|
|
22
20
|
schema
|
|
23
21
|
} = def;
|
|
24
22
|
const isRequired = options.required !== false;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
});
|
|
36
|
-
const latitudeRangeMessage = tPlugin('components.latLongField.latitudeRange', 'en-GB', {
|
|
37
|
-
fieldLabel,
|
|
38
|
-
min: latitudeMin,
|
|
39
|
-
max: latitudeMax
|
|
40
|
-
});
|
|
41
|
-
const longitudeRangeMessage = tPlugin('components.latLongField.longitudeRange', 'en-GB', {
|
|
42
|
-
fieldLabel,
|
|
43
|
-
min: longitudeMin,
|
|
44
|
-
max: longitudeMax
|
|
45
|
-
});
|
|
46
|
-
const latitudeMessages = convertToLanguageMessages({
|
|
47
|
-
...customValidationMessages,
|
|
48
|
-
'any.required': tPlugin('components.latLongField.latitudeRequired', 'en-GB'),
|
|
49
|
-
'number.base': tPlugin('components.latLongField.latitudeBase', 'en-GB', {
|
|
50
|
-
fieldLabel
|
|
51
|
-
}),
|
|
52
|
-
'number.min': latitudeRangeMessage,
|
|
53
|
-
'number.max': latitudeRangeMessage
|
|
54
|
-
});
|
|
55
|
-
const longitudeMessages = convertToLanguageMessages({
|
|
56
|
-
...customValidationMessages,
|
|
57
|
-
'any.required': tPlugin('components.latLongField.longitudeRequired', 'en-GB'),
|
|
58
|
-
'number.base': tPlugin('components.latLongField.longitudeBase', 'en-GB', {
|
|
59
|
-
fieldLabel
|
|
60
|
-
}),
|
|
61
|
-
'number.min': longitudeRangeMessage,
|
|
62
|
-
'number.max': longitudeRangeMessage
|
|
63
|
-
});
|
|
23
|
+
const {
|
|
24
|
+
latitudeMin,
|
|
25
|
+
latitudeMax,
|
|
26
|
+
longitudeMin,
|
|
27
|
+
longitudeMax
|
|
28
|
+
} = LatLongField.getMinMax(schema);
|
|
29
|
+
const {
|
|
30
|
+
latitudeMessages,
|
|
31
|
+
longitudeMessages
|
|
32
|
+
} = LatLongField.buildErrorMessages(this.label, latitudeMin, latitudeMax, longitudeMin, longitudeMax, 'en-GB');
|
|
64
33
|
this.collection = new ComponentCollection([{
|
|
65
34
|
type: ComponentType.NumberField,
|
|
66
35
|
name: `${name}__latitude`,
|
|
@@ -107,13 +76,16 @@ export class LatLongField extends FormComponent {
|
|
|
107
76
|
const value = super.getFormValueFromState(state);
|
|
108
77
|
return LatLongField.isLatLong(value) ? value : undefined;
|
|
109
78
|
}
|
|
110
|
-
getDisplayStringFromFormValue(value,
|
|
79
|
+
getDisplayStringFromFormValue(value, translator) {
|
|
111
80
|
if (!value) {
|
|
112
81
|
return '';
|
|
113
82
|
}
|
|
83
|
+
const {
|
|
84
|
+
t
|
|
85
|
+
} = translator;
|
|
114
86
|
|
|
115
|
-
//
|
|
116
|
-
return `${value.latitude}
|
|
87
|
+
// Output format: Latitude: <<entry>>\nLongitude: <<entry>>
|
|
88
|
+
return `${t('components.latLongField.latitude')}: ${value.latitude}\n${t('components.latLongField.longitude')}: ${value.longitude}`;
|
|
117
89
|
}
|
|
118
90
|
getDisplayStringFromState(state, translator) {
|
|
119
91
|
const value = this.getFormValueFromState(state);
|
|
@@ -123,9 +95,7 @@ export class LatLongField extends FormComponent {
|
|
|
123
95
|
if (!value) {
|
|
124
96
|
return null;
|
|
125
97
|
}
|
|
126
|
-
|
|
127
|
-
// Output format: Latitude: <<entry>>\nLongitude: <<entry>>
|
|
128
|
-
return `Latitude: ${value.latitude}\nLongitude: ${value.longitude}`;
|
|
98
|
+
return `${value.latitude}, ${value.longitude}`;
|
|
129
99
|
}
|
|
130
100
|
getContextValueFromState(state) {
|
|
131
101
|
const value = this.getFormValueFromState(state);
|
|
@@ -142,6 +112,24 @@ export class LatLongField extends FormComponent {
|
|
|
142
112
|
isState(value) {
|
|
143
113
|
return LatLongField.isLatLong(value);
|
|
144
114
|
}
|
|
115
|
+
getValidationMessagesOverride(translator) {
|
|
116
|
+
const def = this.def;
|
|
117
|
+
const translatedLabel = getTranslatedLabel(def, translator);
|
|
118
|
+
const {
|
|
119
|
+
latitudeMin,
|
|
120
|
+
latitudeMax,
|
|
121
|
+
longitudeMin,
|
|
122
|
+
longitudeMax
|
|
123
|
+
} = LatLongField.getMinMax(def.schema);
|
|
124
|
+
const {
|
|
125
|
+
latitudeMessages,
|
|
126
|
+
longitudeMessages
|
|
127
|
+
} = LatLongField.buildErrorMessages(translatedLabel, latitudeMin, latitudeMax, longitudeMin, longitudeMax, translator.language);
|
|
128
|
+
return {
|
|
129
|
+
[`${this.name}__latitude`]: latitudeMessages,
|
|
130
|
+
[`${this.name}__longitude`]: longitudeMessages
|
|
131
|
+
};
|
|
132
|
+
}
|
|
145
133
|
|
|
146
134
|
/**
|
|
147
135
|
* For error preview page that shows all possible errors on a component
|
|
@@ -183,5 +171,54 @@ export class LatLongField extends FormComponent {
|
|
|
183
171
|
static isLatLong(value) {
|
|
184
172
|
return isFormState(value) && NumberField.isNumber(value.latitude) && NumberField.isNumber(value.longitude);
|
|
185
173
|
}
|
|
174
|
+
static buildErrorMessages(label, latitudeMin, latitudeMax, longitudeMin, longitudeMax, language) {
|
|
175
|
+
const fieldLabel = lowerFirst(label);
|
|
176
|
+
const customValidationMessages = {
|
|
177
|
+
'number.precision': tPlugin('components.latLongField.precision', language),
|
|
178
|
+
'number.unsafe': tPlugin('components.latLongField.notANumber', language)
|
|
179
|
+
};
|
|
180
|
+
const latitudeRangeMessage = tPlugin('components.latLongField.latitudeRange', language, {
|
|
181
|
+
fieldLabel,
|
|
182
|
+
min: latitudeMin,
|
|
183
|
+
max: latitudeMax
|
|
184
|
+
});
|
|
185
|
+
const longitudeRangeMessage = tPlugin('components.latLongField.longitudeRange', language, {
|
|
186
|
+
fieldLabel,
|
|
187
|
+
min: longitudeMin,
|
|
188
|
+
max: longitudeMax
|
|
189
|
+
});
|
|
190
|
+
const latitudeMessages = {
|
|
191
|
+
...customValidationMessages,
|
|
192
|
+
'any.required': tPlugin('components.latLongField.latitudeRequired', language),
|
|
193
|
+
'number.base': tPlugin('components.latLongField.latitudeBase', language, {
|
|
194
|
+
fieldLabel
|
|
195
|
+
}),
|
|
196
|
+
'number.min': latitudeRangeMessage,
|
|
197
|
+
'number.max': latitudeRangeMessage
|
|
198
|
+
};
|
|
199
|
+
const longitudeMessages = {
|
|
200
|
+
...customValidationMessages,
|
|
201
|
+
'any.required': tPlugin('components.latLongField.longitudeRequired', language),
|
|
202
|
+
'number.base': tPlugin('components.latLongField.longitudeBase', language, {
|
|
203
|
+
fieldLabel
|
|
204
|
+
}),
|
|
205
|
+
'number.min': longitudeRangeMessage,
|
|
206
|
+
'number.max': longitudeRangeMessage
|
|
207
|
+
};
|
|
208
|
+
return {
|
|
209
|
+
latitudeMessages,
|
|
210
|
+
longitudeMessages
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Read schema values from def.schema with fallback defaults
|
|
215
|
+
static getMinMax(schema) {
|
|
216
|
+
return {
|
|
217
|
+
latitudeMin: schema?.latitude?.min ?? 49.85,
|
|
218
|
+
latitudeMax: schema?.latitude?.max ?? 60.859,
|
|
219
|
+
longitudeMin: schema?.longitude?.min ?? -13.687,
|
|
220
|
+
longitudeMax: schema?.longitude?.max ?? 1.767
|
|
221
|
+
};
|
|
222
|
+
}
|
|
186
223
|
}
|
|
187
224
|
//# sourceMappingURL=LatLongField.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LatLongField.js","names":["ComponentType","lowerFirst","ComponentCollection","FormComponent","isFormState","deduplicateErrorsByHref","getLocationFieldViewModel","NumberField","createLowerFirstExpression","t","tPlugin","messageTemplate","convertToLanguageMessages","DECIMAL_PRECISION","LatLongField","constructor","def","props","name","options","schema","isRequired","required","latitudeMin","latitude","min","latitudeMax","max","longitudeMin","longitude","longitudeMax","fieldLabel","label","customValidationMessages","latitudeRangeMessage","longitudeRangeMessage","latitudeMessages","longitudeMessages","collection","type","title","precision","optionalText","classes","suffix","parent","peers","formSchema","stateSchema","getFormValueFromState","state","value","isLatLong","undefined","getDisplayStringFromFormValue","_translator","getDisplayStringFromState","translator","getContextValueFromFormValue","getContextValueFromState","getViewModel","context","viewModel","getViewErrors","errors","allErrors","getErrors","isState","getAllPossibleErrors","baseErrors","template","advancedSettingsErrors","isNumber"],"sources":["../../../../../src/server/plugins/engine/components/LatLongField.ts"],"sourcesContent":["import { ComponentType, type LatLongFieldComponent } from '@defra/forms-model'\nimport { type LanguageMessages, type ObjectSchema } from 'joi'\nimport lowerFirst from 'lodash/lowerFirst.js'\n\nimport { ComponentCollection } from '~/src/server/plugins/engine/components/ComponentCollection.js'\nimport {\n FormComponent,\n isFormState\n} from '~/src/server/plugins/engine/components/FormComponent.js'\nimport {\n deduplicateErrorsByHref,\n getLocationFieldViewModel\n} from '~/src/server/plugins/engine/components/LocationFieldHelpers.js'\nimport { NumberField } from '~/src/server/plugins/engine/components/NumberField.js'\nimport { createLowerFirstExpression } from '~/src/server/plugins/engine/components/helpers/index.js'\nimport {\n type LatLongState,\n type RenderContext\n} from '~/src/server/plugins/engine/components/types.js'\nimport { t as tPlugin } from '~/src/server/plugins/engine/i18n/index.js'\nimport { type Translator } from '~/src/server/plugins/engine/i18n/types.js'\nimport { messageTemplate } from '~/src/server/plugins/engine/pageControllers/validationOptions.js'\nimport {\n type ErrorMessageTemplateList,\n type FormPayload,\n type FormState,\n type FormStateValue,\n type FormSubmissionError,\n type FormSubmissionState\n} from '~/src/server/plugins/engine/types.js'\nimport { convertToLanguageMessages } from '~/src/server/utils/type-utils.js'\n\n// Precision constants\n// UK latitude/longitude requires high precision for accurate location (within ~11mm)\nconst DECIMAL_PRECISION = 7 // 7 decimal places\n\nexport class LatLongField extends FormComponent {\n declare options: LatLongFieldComponent['options']\n declare formSchema: ObjectSchema<FormPayload>\n declare stateSchema: ObjectSchema<FormState>\n declare collection: ComponentCollection\n\n constructor(\n def: LatLongFieldComponent,\n props: ConstructorParameters<typeof FormComponent>[1]\n ) {\n super(def, props)\n\n const { name, options, schema } = def\n\n const isRequired = options.required !== false\n\n // Read schema values from def.schema with fallback defaults\n const latitudeMin = schema?.latitude?.min ?? 49.85\n const latitudeMax = schema?.latitude?.max ?? 60.859\n const longitudeMin = schema?.longitude?.min ?? -13.687\n const longitudeMax = schema?.longitude?.max ?? 1.767\n\n const fieldLabel = lowerFirst(this.label)\n\n const customValidationMessages: LanguageMessages =\n convertToLanguageMessages({\n 'number.precision': tPlugin(\n 'components.latLongField.precision',\n 'en-GB'\n ),\n 'number.unsafe': tPlugin('components.latLongField.notANumber', 'en-GB')\n })\n\n const latitudeRangeMessage = tPlugin(\n 'components.latLongField.latitudeRange',\n 'en-GB',\n { fieldLabel, min: latitudeMin, max: latitudeMax }\n )\n const longitudeRangeMessage = tPlugin(\n 'components.latLongField.longitudeRange',\n 'en-GB',\n { fieldLabel, min: longitudeMin, max: longitudeMax }\n )\n\n const latitudeMessages: LanguageMessages = convertToLanguageMessages({\n ...customValidationMessages,\n 'any.required': tPlugin(\n 'components.latLongField.latitudeRequired',\n 'en-GB'\n ),\n 'number.base': tPlugin('components.latLongField.latitudeBase', 'en-GB', {\n fieldLabel\n }),\n 'number.min': latitudeRangeMessage,\n 'number.max': latitudeRangeMessage\n })\n\n const longitudeMessages: LanguageMessages = convertToLanguageMessages({\n ...customValidationMessages,\n 'any.required': tPlugin(\n 'components.latLongField.longitudeRequired',\n 'en-GB'\n ),\n 'number.base': tPlugin('components.latLongField.longitudeBase', 'en-GB', {\n fieldLabel\n }),\n 'number.min': longitudeRangeMessage,\n 'number.max': longitudeRangeMessage\n })\n\n this.collection = new ComponentCollection(\n [\n {\n type: ComponentType.NumberField,\n name: `${name}__latitude`,\n title: 'components.latLongField.latitude',\n schema: {\n min: latitudeMin,\n max: latitudeMax,\n precision: DECIMAL_PRECISION\n },\n options: {\n required: isRequired,\n optionalText: true,\n classes: 'govuk-input--width-10',\n suffix: '°',\n customValidationMessages: latitudeMessages\n }\n },\n {\n type: ComponentType.NumberField,\n name: `${name}__longitude`,\n title: 'components.latLongField.longitude',\n schema: {\n min: longitudeMin,\n max: longitudeMax,\n precision: DECIMAL_PRECISION\n },\n options: {\n required: isRequired,\n optionalText: true,\n classes: 'govuk-input--width-10',\n suffix: '°',\n customValidationMessages: longitudeMessages\n }\n }\n ],\n { ...props, parent: this },\n {\n peers: [`${name}__latitude`, `${name}__longitude`]\n }\n )\n\n this.options = options\n this.formSchema = this.collection.formSchema\n this.stateSchema = this.collection.stateSchema\n }\n\n getFormValueFromState(state: FormSubmissionState) {\n const value = super.getFormValueFromState(state)\n return LatLongField.isLatLong(value) ? value : undefined\n }\n\n getDisplayStringFromFormValue(\n value: LatLongState | undefined,\n _translator: Translator\n ): string {\n if (!value) {\n return ''\n }\n\n // CYA page format: <<latvalue, langvalue>>\n return `${value.latitude}, ${value.longitude}`\n }\n\n getDisplayStringFromState(\n state: FormSubmissionState,\n translator: Translator\n ) {\n const value = this.getFormValueFromState(state)\n\n return this.getDisplayStringFromFormValue(value, translator)\n }\n\n getContextValueFromFormValue(value: LatLongState | undefined): string | null {\n if (!value) {\n return null\n }\n\n // Output format: Latitude: <<entry>>\\nLongitude: <<entry>>\n return `Latitude: ${value.latitude}\\nLongitude: ${value.longitude}`\n }\n\n getContextValueFromState(state: FormSubmissionState) {\n const value = this.getFormValueFromState(state)\n\n return this.getContextValueFromFormValue(value)\n }\n\n getViewModel(context: RenderContext) {\n const viewModel = super.getViewModel(context)\n return getLocationFieldViewModel(this, viewModel, context)\n }\n\n getViewErrors(\n translator: Translator,\n errors?: FormSubmissionError[]\n ): FormSubmissionError[] | undefined {\n const allErrors = this.getErrors(translator, errors)\n return deduplicateErrorsByHref(allErrors)\n }\n\n isState(value?: FormStateValue | FormState) {\n return LatLongField.isLatLong(value)\n }\n\n /**\n * For error preview page that shows all possible errors on a component\n */\n getAllPossibleErrors(): ErrorMessageTemplateList {\n return LatLongField.getAllPossibleErrors()\n }\n\n /**\n * Static version of getAllPossibleErrors that doesn't require a component instance.\n */\n static getAllPossibleErrors(): ErrorMessageTemplateList {\n return {\n baseErrors: [\n { type: 'required', template: messageTemplate.required },\n {\n type: 'latitudeFormat',\n template: createLowerFirstExpression(\n 'Enter a valid latitude for {{lowerFirst(#title)}} like 51.519450'\n )\n },\n {\n type: 'longitudeFormat',\n template: createLowerFirstExpression(\n 'Enter a valid longitude for {{lowerFirst(#title)}} like -0.127758'\n )\n }\n ],\n advancedSettingsErrors: [\n {\n type: 'latitudeMin',\n template: createLowerFirstExpression(\n 'Latitude for {{lowerFirst(#title)}} must be between 49 and 60'\n )\n },\n {\n type: 'latitudeMax',\n template: createLowerFirstExpression(\n 'Latitude for {{lowerFirst(#title)}} must be between 49 and 60'\n )\n },\n {\n type: 'longitudeMin',\n template: createLowerFirstExpression(\n 'Longitude for {{lowerFirst(#title)}} must be between -9 and 2'\n )\n },\n {\n type: 'longitudeMax',\n template: createLowerFirstExpression(\n 'Longitude for {{lowerFirst(#title)}} must be between -9 and 2'\n )\n }\n ]\n }\n }\n\n static isLatLong(value?: FormStateValue | FormState): value is LatLongState {\n return (\n isFormState(value) &&\n NumberField.isNumber(value.latitude) &&\n NumberField.isNumber(value.longitude)\n )\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"LatLongField.js","names":["ComponentType","lowerFirst","ComponentCollection","FormComponent","isFormState","deduplicateErrorsByHref","getLocationFieldViewModel","NumberField","createLowerFirstExpression","getTranslatedLabel","t","tPlugin","messageTemplate","DECIMAL_PRECISION","LatLongField","constructor","def","props","name","options","schema","isRequired","required","latitudeMin","latitudeMax","longitudeMin","longitudeMax","getMinMax","latitudeMessages","longitudeMessages","buildErrorMessages","label","collection","type","title","min","max","precision","optionalText","classes","suffix","customValidationMessages","parent","peers","formSchema","stateSchema","getFormValueFromState","state","value","isLatLong","undefined","getDisplayStringFromFormValue","translator","latitude","longitude","getDisplayStringFromState","getContextValueFromFormValue","getContextValueFromState","getViewModel","context","viewModel","getViewErrors","errors","allErrors","getErrors","isState","getValidationMessagesOverride","translatedLabel","language","getAllPossibleErrors","baseErrors","template","advancedSettingsErrors","isNumber","fieldLabel","latitudeRangeMessage","longitudeRangeMessage"],"sources":["../../../../../src/server/plugins/engine/components/LatLongField.ts"],"sourcesContent":["import { ComponentType, type LatLongFieldComponent } from '@defra/forms-model'\nimport { type LanguageMessages, type ObjectSchema } from 'joi'\nimport lowerFirst from 'lodash/lowerFirst.js'\n\nimport { ComponentCollection } from '~/src/server/plugins/engine/components/ComponentCollection.js'\nimport {\n FormComponent,\n isFormState\n} from '~/src/server/plugins/engine/components/FormComponent.js'\nimport {\n deduplicateErrorsByHref,\n getLocationFieldViewModel\n} from '~/src/server/plugins/engine/components/LocationFieldHelpers.js'\nimport { NumberField } from '~/src/server/plugins/engine/components/NumberField.js'\nimport {\n createLowerFirstExpression,\n getTranslatedLabel\n} from '~/src/server/plugins/engine/components/helpers/index.js'\nimport {\n type LatLongState,\n type RenderContext\n} from '~/src/server/plugins/engine/components/types.js'\nimport { t as tPlugin } from '~/src/server/plugins/engine/i18n/index.js'\nimport { type Translator } from '~/src/server/plugins/engine/i18n/types.js'\nimport { messageTemplate } from '~/src/server/plugins/engine/pageControllers/validationOptions.js'\nimport {\n type ErrorMessageTemplateList,\n type FormPayload,\n type FormState,\n type FormStateValue,\n type FormSubmissionError,\n type FormSubmissionState\n} from '~/src/server/plugins/engine/types.js'\n\n// Precision constants\n// UK latitude/longitude requires high precision for accurate location (within ~11mm)\nconst DECIMAL_PRECISION = 7 // 7 decimal places\n\nexport class LatLongField extends FormComponent {\n declare options: LatLongFieldComponent['options']\n declare formSchema: ObjectSchema<FormPayload>\n declare stateSchema: ObjectSchema<FormState>\n declare collection: ComponentCollection\n\n constructor(\n def: LatLongFieldComponent,\n props: ConstructorParameters<typeof FormComponent>[1]\n ) {\n super(def, props)\n\n const { name, options, schema } = def\n\n const isRequired = options.required !== false\n\n const { latitudeMin, latitudeMax, longitudeMin, longitudeMax } =\n LatLongField.getMinMax(schema)\n\n const { latitudeMessages, longitudeMessages } =\n LatLongField.buildErrorMessages(\n this.label,\n latitudeMin,\n latitudeMax,\n longitudeMin,\n longitudeMax,\n 'en-GB'\n )\n\n this.collection = new ComponentCollection(\n [\n {\n type: ComponentType.NumberField,\n name: `${name}__latitude`,\n title: 'components.latLongField.latitude',\n schema: {\n min: latitudeMin,\n max: latitudeMax,\n precision: DECIMAL_PRECISION\n },\n options: {\n required: isRequired,\n optionalText: true,\n classes: 'govuk-input--width-10',\n suffix: '°',\n customValidationMessages: latitudeMessages\n }\n },\n {\n type: ComponentType.NumberField,\n name: `${name}__longitude`,\n title: 'components.latLongField.longitude',\n schema: {\n min: longitudeMin,\n max: longitudeMax,\n precision: DECIMAL_PRECISION\n },\n options: {\n required: isRequired,\n optionalText: true,\n classes: 'govuk-input--width-10',\n suffix: '°',\n customValidationMessages: longitudeMessages\n }\n }\n ],\n { ...props, parent: this },\n {\n peers: [`${name}__latitude`, `${name}__longitude`]\n }\n )\n\n this.options = options\n this.formSchema = this.collection.formSchema\n this.stateSchema = this.collection.stateSchema\n }\n\n getFormValueFromState(state: FormSubmissionState) {\n const value = super.getFormValueFromState(state)\n return LatLongField.isLatLong(value) ? value : undefined\n }\n\n getDisplayStringFromFormValue(\n value: LatLongState | undefined,\n translator: Translator\n ): string {\n if (!value) {\n return ''\n }\n\n const { t } = translator\n\n // Output format: Latitude: <<entry>>\\nLongitude: <<entry>>\n return `${t('components.latLongField.latitude')}: ${value.latitude}\\n${t('components.latLongField.longitude')}: ${value.longitude}`\n }\n\n getDisplayStringFromState(\n state: FormSubmissionState,\n translator: Translator\n ) {\n const value = this.getFormValueFromState(state)\n\n return this.getDisplayStringFromFormValue(value, translator)\n }\n\n getContextValueFromFormValue(value: LatLongState | undefined): string | null {\n if (!value) {\n return null\n }\n\n return `${value.latitude}, ${value.longitude}`\n }\n\n getContextValueFromState(state: FormSubmissionState) {\n const value = this.getFormValueFromState(state)\n\n return this.getContextValueFromFormValue(value)\n }\n\n getViewModel(context: RenderContext) {\n const viewModel = super.getViewModel(context)\n return getLocationFieldViewModel(this, viewModel, context)\n }\n\n getViewErrors(\n translator: Translator,\n errors?: FormSubmissionError[]\n ): FormSubmissionError[] | undefined {\n const allErrors = this.getErrors(translator, errors)\n return deduplicateErrorsByHref(allErrors)\n }\n\n isState(value?: FormStateValue | FormState) {\n return LatLongField.isLatLong(value)\n }\n\n getValidationMessagesOverride(translator: Translator) {\n const def = this.def as LatLongFieldComponent\n const translatedLabel = getTranslatedLabel(def, translator)\n const { latitudeMin, latitudeMax, longitudeMin, longitudeMax } =\n LatLongField.getMinMax(def.schema)\n const { latitudeMessages, longitudeMessages } =\n LatLongField.buildErrorMessages(\n translatedLabel,\n latitudeMin,\n latitudeMax,\n longitudeMin,\n longitudeMax,\n translator.language\n )\n return {\n [`${this.name}__latitude`]: latitudeMessages,\n [`${this.name}__longitude`]: longitudeMessages\n }\n }\n\n /**\n * For error preview page that shows all possible errors on a component\n */\n getAllPossibleErrors(): ErrorMessageTemplateList {\n return LatLongField.getAllPossibleErrors()\n }\n\n /**\n * Static version of getAllPossibleErrors that doesn't require a component instance.\n */\n static getAllPossibleErrors(): ErrorMessageTemplateList {\n return {\n baseErrors: [\n { type: 'required', template: messageTemplate.required },\n {\n type: 'latitudeFormat',\n template: createLowerFirstExpression(\n 'Enter a valid latitude for {{lowerFirst(#title)}} like 51.519450'\n )\n },\n {\n type: 'longitudeFormat',\n template: createLowerFirstExpression(\n 'Enter a valid longitude for {{lowerFirst(#title)}} like -0.127758'\n )\n }\n ],\n advancedSettingsErrors: [\n {\n type: 'latitudeMin',\n template: createLowerFirstExpression(\n 'Latitude for {{lowerFirst(#title)}} must be between 49 and 60'\n )\n },\n {\n type: 'latitudeMax',\n template: createLowerFirstExpression(\n 'Latitude for {{lowerFirst(#title)}} must be between 49 and 60'\n )\n },\n {\n type: 'longitudeMin',\n template: createLowerFirstExpression(\n 'Longitude for {{lowerFirst(#title)}} must be between -9 and 2'\n )\n },\n {\n type: 'longitudeMax',\n template: createLowerFirstExpression(\n 'Longitude for {{lowerFirst(#title)}} must be between -9 and 2'\n )\n }\n ]\n }\n }\n\n static isLatLong(value?: FormStateValue | FormState): value is LatLongState {\n return (\n isFormState(value) &&\n NumberField.isNumber(value.latitude) &&\n NumberField.isNumber(value.longitude)\n )\n }\n\n static buildErrorMessages(\n label: string,\n latitudeMin: number,\n latitudeMax: number,\n longitudeMin: number,\n longitudeMax: number,\n language: string\n ) {\n const fieldLabel = lowerFirst(label)\n\n const customValidationMessages: LanguageMessages = {\n 'number.precision': tPlugin(\n 'components.latLongField.precision',\n language\n ),\n 'number.unsafe': tPlugin('components.latLongField.notANumber', language)\n }\n\n const latitudeRangeMessage = tPlugin(\n 'components.latLongField.latitudeRange',\n language,\n { fieldLabel, min: latitudeMin, max: latitudeMax }\n )\n const longitudeRangeMessage = tPlugin(\n 'components.latLongField.longitudeRange',\n language,\n { fieldLabel, min: longitudeMin, max: longitudeMax }\n )\n\n const latitudeMessages: LanguageMessages = {\n ...customValidationMessages,\n 'any.required': tPlugin(\n 'components.latLongField.latitudeRequired',\n language\n ),\n 'number.base': tPlugin('components.latLongField.latitudeBase', language, {\n fieldLabel\n }),\n 'number.min': latitudeRangeMessage,\n 'number.max': latitudeRangeMessage\n }\n\n const longitudeMessages: LanguageMessages = {\n ...customValidationMessages,\n 'any.required': tPlugin(\n 'components.latLongField.longitudeRequired',\n language\n ),\n 'number.base': tPlugin(\n 'components.latLongField.longitudeBase',\n language,\n {\n fieldLabel\n }\n ),\n 'number.min': longitudeRangeMessage,\n 'number.max': longitudeRangeMessage\n }\n\n return {\n latitudeMessages,\n longitudeMessages\n }\n }\n\n // Read schema values from def.schema with fallback defaults\n static getMinMax(\n schema:\n | {\n latitude?: {\n min?: number\n max?: number\n }\n longitude?: {\n min?: number\n max?: number\n }\n }\n | undefined\n ) {\n return {\n latitudeMin: schema?.latitude?.min ?? 49.85,\n latitudeMax: schema?.latitude?.max ?? 60.859,\n longitudeMin: schema?.longitude?.min ?? -13.687,\n longitudeMax: schema?.longitude?.max ?? 1.767\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { type FormComponentsDef } from '@defra/forms-model';
|
|
2
|
-
import { type JoiExpression, type LanguageMessages, type StringSchema } from 'joi';
|
|
2
|
+
import joi, { type JoiExpression, type LanguageMessages, type StringSchema } from 'joi';
|
|
3
3
|
import { FormComponent } from '../../../../server/plugins/engine/components/FormComponent.js';
|
|
4
4
|
import { type RenderContext } from '../../../../server/plugins/engine/components/types.js';
|
|
5
|
+
import { type Translator } from '../../../../server/plugins/engine/types/index.js';
|
|
5
6
|
import { type ErrorMessageTemplateList, type FormState, type FormStateValue, type FormSubmissionState } from '../../../../server/plugins/engine/types.js';
|
|
6
7
|
interface LocationFieldOptions {
|
|
7
8
|
instructionText?: string;
|
|
@@ -23,7 +24,7 @@ export declare abstract class LocationFieldBase extends FormComponent {
|
|
|
23
24
|
formSchema: StringSchema;
|
|
24
25
|
stateSchema: StringSchema;
|
|
25
26
|
instructionText?: string;
|
|
26
|
-
protected abstract getValidationConfig(): ValidationConfig;
|
|
27
|
+
protected abstract getValidationConfig(translator: Translator | undefined): ValidationConfig;
|
|
27
28
|
protected abstract getErrorTemplates(): {
|
|
28
29
|
type: string;
|
|
29
30
|
template: JoiExpression;
|
|
@@ -79,6 +80,7 @@ export declare abstract class LocationFieldBase extends FormComponent {
|
|
|
79
80
|
upload?: {
|
|
80
81
|
count: number;
|
|
81
82
|
summaryList: import("../../../../server/plugins/engine/types.js").SummaryList;
|
|
83
|
+
uploadingLabel?: string;
|
|
82
84
|
};
|
|
83
85
|
} | {
|
|
84
86
|
instructionText: string;
|
|
@@ -128,8 +130,12 @@ export declare abstract class LocationFieldBase extends FormComponent {
|
|
|
128
130
|
upload?: {
|
|
129
131
|
count: number;
|
|
130
132
|
summaryList: import("../../../../server/plugins/engine/types.js").SummaryList;
|
|
133
|
+
uploadingLabel?: string;
|
|
131
134
|
};
|
|
132
135
|
};
|
|
136
|
+
getValidationMessagesOverride(translator: Translator): {
|
|
137
|
+
[x: string]: joi.LanguageMessages;
|
|
138
|
+
};
|
|
133
139
|
getAllPossibleErrors(): ErrorMessageTemplateList;
|
|
134
140
|
static isText(value?: FormStateValue | FormState): value is string;
|
|
135
141
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import joi from 'joi';
|
|
2
2
|
import { FormComponent, isFormValue } from "./FormComponent.js";
|
|
3
3
|
import { addClassOptionIfNone } from "./helpers/index.js";
|
|
4
|
+
import { buildValidationMessages } from "../i18n/buildValidationMessages.js";
|
|
4
5
|
import { messageTemplate } from "../pageControllers/validationOptions.js";
|
|
5
|
-
import { convertToLanguageMessages } from "../../../utils/type-utils.js";
|
|
6
6
|
/**
|
|
7
7
|
* Abstract base class for location-based field components
|
|
8
8
|
*/
|
|
@@ -16,13 +16,13 @@ export class LocationFieldBase extends FormComponent {
|
|
|
16
16
|
const locationOptions = options;
|
|
17
17
|
this.instructionText = locationOptions.instructionText;
|
|
18
18
|
addClassOptionIfNone(locationOptions, 'govuk-input--width-10');
|
|
19
|
-
const config = this.getValidationConfig();
|
|
19
|
+
const config = this.getValidationConfig(undefined);
|
|
20
20
|
const requiredMessage = config.requiredMessage ?? messageTemplate.required;
|
|
21
|
-
const messages =
|
|
21
|
+
const messages = {
|
|
22
22
|
'any.required': requiredMessage,
|
|
23
23
|
'string.empty': requiredMessage,
|
|
24
24
|
'string.pattern.base': config.patternErrorMessage
|
|
25
|
-
}
|
|
25
|
+
};
|
|
26
26
|
let formSchema = joi.string().trim().label(this.label).required().pattern(config.pattern).messages(messages);
|
|
27
27
|
if (locationOptions.required === false) {
|
|
28
28
|
formSchema = formSchema.allow('');
|
|
@@ -64,8 +64,21 @@ export class LocationFieldBase extends FormComponent {
|
|
|
64
64
|
}
|
|
65
65
|
return viewModel;
|
|
66
66
|
}
|
|
67
|
+
getValidationMessagesOverride(translator) {
|
|
68
|
+
const {
|
|
69
|
+
t
|
|
70
|
+
} = translator;
|
|
71
|
+
const config = this.getValidationConfig(translator);
|
|
72
|
+
return {
|
|
73
|
+
[this.name]: {
|
|
74
|
+
'any.required': config.requiredMessage ?? buildValidationMessages(t).objectRequired,
|
|
75
|
+
'string.empty': config.requiredMessage ?? buildValidationMessages(t).objectRequired,
|
|
76
|
+
'string.pattern.base': config.patternErrorMessage
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
}
|
|
67
80
|
getAllPossibleErrors() {
|
|
68
|
-
const config = this.getValidationConfig();
|
|
81
|
+
const config = this.getValidationConfig(undefined);
|
|
69
82
|
return {
|
|
70
83
|
baseErrors: [{
|
|
71
84
|
type: 'required',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LocationFieldBase.js","names":["joi","FormComponent","isFormValue","addClassOptionIfNone","
|
|
1
|
+
{"version":3,"file":"LocationFieldBase.js","names":["joi","FormComponent","isFormValue","addClassOptionIfNone","buildValidationMessages","messageTemplate","LocationFieldBase","instructionText","constructor","def","props","options","locationOptions","config","getValidationConfig","undefined","requiredMessage","required","messages","patternErrorMessage","formSchema","string","trim","label","pattern","allow","customValidationMessage","message","messageKeys","reduce","acc","key","customValidationMessages","default","stateSchema","getFormValueFromState","state","name","getFormValue","value","isValue","isText","getViewModel","context","viewModel","getValidationMessagesOverride","translator","t","objectRequired","getAllPossibleErrors","baseErrors","type","template","getErrorTemplates","advancedSettingsErrors"],"sources":["../../../../../src/server/plugins/engine/components/LocationFieldBase.ts"],"sourcesContent":["import { type FormComponentsDef } from '@defra/forms-model'\nimport joi, {\n type JoiExpression,\n type LanguageMessages,\n type StringSchema\n} from 'joi'\n\nimport {\n FormComponent,\n isFormValue\n} from '~/src/server/plugins/engine/components/FormComponent.js'\nimport { addClassOptionIfNone } from '~/src/server/plugins/engine/components/helpers/index.js'\nimport { type RenderContext } from '~/src/server/plugins/engine/components/types.js'\nimport { buildValidationMessages } from '~/src/server/plugins/engine/i18n/buildValidationMessages.js'\nimport { messageTemplate } from '~/src/server/plugins/engine/pageControllers/validationOptions.js'\nimport { type Translator } from '~/src/server/plugins/engine/types/index.js'\nimport {\n type ErrorMessageTemplateList,\n type FormState,\n type FormStateValue,\n type FormSubmissionState\n} from '~/src/server/plugins/engine/types.js'\n\ninterface LocationFieldOptions {\n instructionText?: string\n required?: boolean\n customValidationMessage?: string\n customValidationMessages?: LanguageMessages\n classes?: string\n}\n\ninterface ValidationConfig {\n pattern: RegExp\n patternErrorMessage: JoiExpression\n requiredMessage?: JoiExpression\n}\n\n/**\n * Abstract base class for location-based field components\n */\nexport abstract class LocationFieldBase extends FormComponent {\n declare options: LocationFieldOptions\n declare formSchema: StringSchema\n declare stateSchema: StringSchema\n instructionText?: string\n\n protected abstract getValidationConfig(\n translator: Translator | undefined\n ): ValidationConfig\n protected abstract getErrorTemplates(): {\n type: string\n template: JoiExpression\n }[]\n\n constructor(\n def: FormComponentsDef,\n props: ConstructorParameters<typeof FormComponent>[1]\n ) {\n super(def, props)\n\n const { options } = def\n const locationOptions = options as LocationFieldOptions\n this.instructionText = locationOptions.instructionText\n\n addClassOptionIfNone(locationOptions, 'govuk-input--width-10')\n\n const config = this.getValidationConfig(undefined)\n const requiredMessage = config.requiredMessage ?? messageTemplate.required\n\n const messages = {\n 'any.required': requiredMessage,\n 'string.empty': requiredMessage,\n 'string.pattern.base': config.patternErrorMessage\n } as LanguageMessages\n\n let formSchema = joi\n .string()\n .trim()\n .label(this.label)\n .required()\n .pattern(config.pattern)\n .messages(messages)\n\n if (locationOptions.required === false) {\n formSchema = formSchema.allow('')\n }\n\n if (locationOptions.customValidationMessage) {\n const message = locationOptions.customValidationMessage\n const messageKeys = [\n 'any.required',\n 'string.empty',\n 'string.pattern.base'\n ]\n\n const messages = messageKeys.reduce<LanguageMessages>((acc, key) => {\n acc[key] = message\n return acc\n }, {})\n\n formSchema = formSchema.messages(messages)\n } else if (locationOptions.customValidationMessages) {\n formSchema = formSchema.messages(locationOptions.customValidationMessages)\n }\n\n this.formSchema = formSchema.default('')\n this.stateSchema = formSchema.default(null).allow(null)\n this.options = locationOptions\n }\n\n getFormValueFromState(state: FormSubmissionState) {\n const { name } = this\n return this.getFormValue(state[name])\n }\n\n getFormValue(value?: FormStateValue | FormState) {\n return this.isValue(value) ? value : undefined\n }\n\n isValue(value?: FormStateValue | FormState): value is string {\n return LocationFieldBase.isText(value)\n }\n\n getViewModel(context: RenderContext) {\n const viewModel = super.getViewModel(context)\n\n if (this.instructionText) {\n return {\n ...viewModel,\n instructionText: this.instructionText\n }\n }\n\n return viewModel\n }\n\n getValidationMessagesOverride(translator: Translator) {\n const { t } = translator\n const config = this.getValidationConfig(translator)\n return {\n [this.name]: {\n 'any.required':\n config.requiredMessage ?? buildValidationMessages(t).objectRequired,\n 'string.empty':\n config.requiredMessage ?? buildValidationMessages(t).objectRequired,\n 'string.pattern.base': config.patternErrorMessage\n } as LanguageMessages\n }\n }\n\n getAllPossibleErrors(): ErrorMessageTemplateList {\n const config = this.getValidationConfig(undefined)\n\n return {\n baseErrors: [\n {\n type: 'required',\n template: config.requiredMessage ?? messageTemplate.required\n },\n ...this.getErrorTemplates()\n ],\n advancedSettingsErrors: []\n }\n }\n\n static isText(value?: FormStateValue | FormState): value is string {\n return isFormValue(value) && typeof value === 'string'\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { type CustomValidator } from 'joi';
|
|
2
|
-
import {
|
|
2
|
+
import { EastingNorthingField } from '../../../../server/plugins/engine/components/EastingNorthingField.js';
|
|
3
3
|
import { type GeospatialField } from '../../../../server/plugins/engine/components/GeospatialField.js';
|
|
4
4
|
import { type LatLongField } from '../../../../server/plugins/engine/components/LatLongField.js';
|
|
5
5
|
import { type OsGridRefField } from '../../../../server/plugins/engine/components/OsGridRefField.js';
|
|
6
6
|
import { type DateInputItem, type Label, type RenderContext, type ViewModel } from '../../../../server/plugins/engine/components/types.js';
|
|
7
|
+
import { type Translator } from '../../../../server/plugins/engine/i18n/types.js';
|
|
7
8
|
import { type FormSubmissionError, type FormValue } from '../../../../server/plugins/engine/types.js';
|
|
8
9
|
export type LocationField = InstanceType<typeof EastingNorthingField> | InstanceType<typeof LatLongField>;
|
|
9
|
-
export declare function joinWithAnd(items: string[]): string;
|
|
10
|
-
export declare function formatErrorList(messages: string[]): string;
|
|
10
|
+
export declare function joinWithAnd(items: string[], translator: Translator): string;
|
|
11
|
+
export declare function formatErrorList(messages: string[], translator: Translator): string;
|
|
11
12
|
export declare function mergeCssClasses(...classNames: (string | undefined)[]): string | undefined;
|
|
12
13
|
export declare function deduplicateErrorsByHref(errors?: FormSubmissionError[]): FormSubmissionError[] | undefined;
|
|
13
14
|
export declare function getMapLayers(component: GeospatialField | OsGridRefField | LatLongField | EastingNorthingField): string;
|
|
@@ -23,6 +24,7 @@ export declare function getLocationFieldViewModel(component: LocationField, view
|
|
|
23
24
|
};
|
|
24
25
|
items: DateInputItem[];
|
|
25
26
|
mapLayers: string;
|
|
27
|
+
country: import("@defra/forms-model").GeospatialFieldOptionsCountry | undefined;
|
|
26
28
|
label: Label;
|
|
27
29
|
type?: string;
|
|
28
30
|
id: string;
|
|
@@ -62,6 +64,7 @@ export declare function getLocationFieldViewModel(component: LocationField, view
|
|
|
62
64
|
upload?: {
|
|
63
65
|
count: number;
|
|
64
66
|
summaryList: import("../../../../server/plugins/engine/types.js").SummaryList;
|
|
67
|
+
uploadingLabel?: string;
|
|
65
68
|
};
|
|
66
69
|
} | {
|
|
67
70
|
instructionText: string;
|
|
@@ -71,6 +74,7 @@ export declare function getLocationFieldViewModel(component: LocationField, view
|
|
|
71
74
|
};
|
|
72
75
|
items: DateInputItem[];
|
|
73
76
|
mapLayers: string;
|
|
77
|
+
country: import("@defra/forms-model").GeospatialFieldOptionsCountry | undefined;
|
|
74
78
|
label: Label;
|
|
75
79
|
type?: string;
|
|
76
80
|
id: string;
|
|
@@ -110,6 +114,7 @@ export declare function getLocationFieldViewModel(component: LocationField, view
|
|
|
110
114
|
upload?: {
|
|
111
115
|
count: number;
|
|
112
116
|
summaryList: import("../../../../server/plugins/engine/types.js").SummaryList;
|
|
117
|
+
uploadingLabel?: string;
|
|
113
118
|
};
|
|
114
119
|
};
|
|
115
120
|
/**
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { EastingNorthingField } from "./EastingNorthingField.js";
|
|
1
2
|
import { isFormValue } from "./FormComponent.js";
|
|
2
3
|
/**
|
|
3
4
|
* Lowercases the start of a message for concatenation.
|
|
@@ -7,22 +8,21 @@ import { isFormValue } from "./FormComponent.js";
|
|
|
7
8
|
* - "latitude must be..." -> "latitude must be..."
|
|
8
9
|
*/
|
|
9
10
|
function lowercaseMessageStart(message) {
|
|
10
|
-
|
|
11
|
-
return 'enter' + message.slice(5);
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
// Lowercase first character for any other message
|
|
11
|
+
// Lowercase first character for a message
|
|
15
12
|
return message.charAt(0).toLowerCase() + message.slice(1);
|
|
16
13
|
}
|
|
17
|
-
export function joinWithAnd(items) {
|
|
14
|
+
export function joinWithAnd(items, translator) {
|
|
15
|
+
const {
|
|
16
|
+
t
|
|
17
|
+
} = translator;
|
|
18
18
|
if (items.length === 2) {
|
|
19
|
-
return `${items[0]} and ${items[1]}`;
|
|
19
|
+
return `${items[0]} ${t('common.and')} ${items[1]}`;
|
|
20
20
|
}
|
|
21
21
|
const leading = items.slice(0, -1).join(', ');
|
|
22
22
|
const last = items[items.length - 1];
|
|
23
|
-
return `${leading} and ${last}`;
|
|
23
|
+
return `${leading} ${t('common.and')} ${last}`;
|
|
24
24
|
}
|
|
25
|
-
export function formatErrorList(messages) {
|
|
25
|
+
export function formatErrorList(messages, translator) {
|
|
26
26
|
if (!messages.length) {
|
|
27
27
|
return '';
|
|
28
28
|
}
|
|
@@ -30,7 +30,7 @@ export function formatErrorList(messages) {
|
|
|
30
30
|
return messages[0];
|
|
31
31
|
}
|
|
32
32
|
const formattedMessages = messages.map((msg, index) => index === 0 ? msg : lowercaseMessageStart(msg));
|
|
33
|
-
return joinWithAnd(formattedMessages);
|
|
33
|
+
return joinWithAnd(formattedMessages, translator);
|
|
34
34
|
}
|
|
35
35
|
export function mergeCssClasses(...classNames) {
|
|
36
36
|
const tokens = classNames.flatMap(name => name?.split(/\s+/) ?? []).map(token => token.trim()).filter(Boolean);
|
|
@@ -110,7 +110,7 @@ export function getLocationFieldViewModel(component, viewModel, context) {
|
|
|
110
110
|
viewModel.showFieldsetError = showFieldsetError;
|
|
111
111
|
if (hasFieldErrors) {
|
|
112
112
|
viewModel.errorMessage = {
|
|
113
|
-
text: fieldErrors.length === 1 ? fieldErrors[0] : formatErrorList(fieldErrors)
|
|
113
|
+
text: fieldErrors.length === 1 ? fieldErrors[0] : formatErrorList(fieldErrors, context.translator)
|
|
114
114
|
};
|
|
115
115
|
}
|
|
116
116
|
const fieldset = existingFieldset ?? {
|
|
@@ -123,7 +123,8 @@ export function getLocationFieldViewModel(component, viewModel, context) {
|
|
|
123
123
|
...viewModel,
|
|
124
124
|
fieldset,
|
|
125
125
|
items,
|
|
126
|
-
mapLayers: getMapLayers(component)
|
|
126
|
+
mapLayers: getMapLayers(component),
|
|
127
|
+
country: component instanceof EastingNorthingField ? component.options.countries?.at(0) : undefined
|
|
127
128
|
};
|
|
128
129
|
if (component.options.instructionText) {
|
|
129
130
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LocationFieldHelpers.js","names":["isFormValue","lowercaseMessageStart","message","startsWith","slice","charAt","toLowerCase","joinWithAnd","items","length","leading","join","last","formatErrorList","messages","formattedMessages","map","msg","index","mergeCssClasses","classNames","tokens","flatMap","name","split","token","trim","filter","Boolean","undefined","Array","from","Set","deduplicateErrorsByHref","errors","error","self","findIndex","err","href","getMapLayers","component","mapLayers","options","layers","sssi","push","getLocationFieldViewModel","viewModel","context","collection","fieldset","existingFieldset","label","subViewModels","getViewModel","fieldErrors","forEach","model","errorMessage","text","hasFieldErrors","type","value","classes","prefix","suffix","toString","baseItem","id","showFieldsetError","legend","result","instructionText","createLocationFieldValidator","payload","helpers","values","getFormValueFromState","getStateFromValidForm","missing","keys","key","isState","required"],"sources":["../../../../../src/server/plugins/engine/components/LocationFieldHelpers.ts"],"sourcesContent":["import { type Context, type CustomValidator } from 'joi'\n\nimport { type EastingNorthingField } from '~/src/server/plugins/engine/components/EastingNorthingField.js'\nimport { isFormValue } from '~/src/server/plugins/engine/components/FormComponent.js'\nimport { type GeospatialField } from '~/src/server/plugins/engine/components/GeospatialField.js'\nimport { type LatLongField } from '~/src/server/plugins/engine/components/LatLongField.js'\nimport { type OsGridRefField } from '~/src/server/plugins/engine/components/OsGridRefField.js'\nimport {\n type DateInputItem,\n type Label,\n type RenderContext,\n type ViewModel\n} from '~/src/server/plugins/engine/components/types.js'\nimport {\n type FormPayload,\n type FormSubmissionError,\n type FormValue\n} from '~/src/server/plugins/engine/types.js'\n\nexport type LocationField =\n | InstanceType<typeof EastingNorthingField>\n | InstanceType<typeof LatLongField>\n\n/**\n * Lowercases the start of a message for concatenation.\n * Handles patterns like:\n * - \"Enter latitude\" -> \"enter latitude\"\n * - \"Enter a valid latitude...\" -> \"enter a valid latitude...\"\n * - \"latitude must be...\" -> \"latitude must be...\"\n */\nfunction lowercaseMessageStart(message: string): string {\n if (message.startsWith('Enter ')) {\n return 'enter' + message.slice(5)\n }\n\n // Lowercase first character for any other message\n return message.charAt(0).toLowerCase() + message.slice(1)\n}\n\nexport function joinWithAnd(items: string[]): string {\n if (items.length === 2) {\n return `${items[0]} and ${items[1]}`\n }\n\n const leading = items.slice(0, -1).join(', ')\n const last = items[items.length - 1]\n return `${leading} and ${last}`\n}\n\nexport function formatErrorList(messages: string[]): string {\n if (!messages.length) {\n return ''\n }\n\n if (messages.length === 1) {\n return messages[0]\n }\n\n const formattedMessages = messages.map((msg, index) =>\n index === 0 ? msg : lowercaseMessageStart(msg)\n )\n\n return joinWithAnd(formattedMessages)\n}\n\nexport function mergeCssClasses(...classNames: (string | undefined)[]) {\n const tokens = classNames\n .flatMap((name) => name?.split(/\\s+/) ?? [])\n .map((token) => token.trim())\n .filter(Boolean)\n\n if (!tokens.length) {\n return undefined\n }\n\n return Array.from(new Set(tokens)).join(' ')\n}\n\nexport function deduplicateErrorsByHref(\n errors?: FormSubmissionError[]\n): FormSubmissionError[] | undefined {\n if (!errors?.length) {\n return undefined\n }\n\n return errors.filter(\n (error, index, self) =>\n index === self.findIndex((err) => err.href === error.href)\n )\n}\n\nexport function getMapLayers(\n component:\n | GeospatialField\n | OsGridRefField\n | LatLongField\n | EastingNorthingField\n) {\n const { mapLayers } = component.options\n const layers = []\n\n if (mapLayers?.sssi) {\n layers.push('sssi')\n }\n\n return layers.join(',')\n}\n\nexport function getLocationFieldViewModel(\n component: LocationField,\n viewModel: ViewModel & {\n label: Label\n id: string\n name: string\n value: FormValue\n },\n context: RenderContext\n) {\n const { collection } = component\n const { fieldset: existingFieldset, label } = viewModel\n\n const subViewModels = collection.getViewModel(context)\n\n const fieldErrors: string[] = []\n subViewModels.forEach(({ model }) => {\n if (model.errorMessage?.text) {\n fieldErrors.push(model.errorMessage.text)\n }\n })\n\n const hasFieldErrors = fieldErrors.length > 0\n\n const items: DateInputItem[] = subViewModels.map(\n ({ model }): DateInputItem => {\n let { label, type, value, classes, prefix, suffix, errorMessage } = model\n\n if (label) {\n label.toString = () => label.text\n }\n\n if (!isFormValue(value)) {\n value = undefined\n }\n\n const baseItem: DateInputItem = {\n label,\n id: model.id,\n name: model.name,\n type,\n value,\n classes: mergeCssClasses(\n classes,\n hasFieldErrors ? 'govuk-input--error' : undefined\n ),\n prefix,\n suffix\n }\n\n if (!hasFieldErrors && errorMessage) {\n baseItem.errorMessage = errorMessage\n }\n\n return baseItem\n }\n )\n\n const showFieldsetError =\n hasFieldErrors || Boolean(viewModel.errorMessage?.text)\n\n viewModel.showFieldsetError = showFieldsetError\n\n if (hasFieldErrors) {\n viewModel.errorMessage = {\n text:\n fieldErrors.length === 1 ? fieldErrors[0] : formatErrorList(fieldErrors)\n }\n }\n\n const fieldset = existingFieldset ?? {\n legend: {\n text: label.text,\n classes: 'govuk-fieldset__legend--m'\n }\n }\n\n const result = {\n ...viewModel,\n fieldset,\n items,\n mapLayers: getMapLayers(component)\n }\n\n if (component.options.instructionText) {\n return {\n ...result,\n instructionText: component.options.instructionText\n }\n }\n\n return result\n}\n\n/**\n * Validator factory for location-based fields.\n * This creates a validator that ensures all required fields are present.\n */\nexport function createLocationFieldValidator(\n component: LocationField\n): CustomValidator {\n return (payload: FormPayload, helpers) => {\n const { collection, name, options } = component\n\n const values = component.getFormValueFromState(\n component.getStateFromValidForm(payload)\n )\n\n const context: Context = {\n missing: collection.keys,\n key: name\n }\n\n if (!component.isState(values)) {\n return options.required !== false\n ? helpers.error('object.required', context)\n : payload\n }\n\n return payload\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"LocationFieldHelpers.js","names":["EastingNorthingField","isFormValue","lowercaseMessageStart","message","charAt","toLowerCase","slice","joinWithAnd","items","translator","t","length","leading","join","last","formatErrorList","messages","formattedMessages","map","msg","index","mergeCssClasses","classNames","tokens","flatMap","name","split","token","trim","filter","Boolean","undefined","Array","from","Set","deduplicateErrorsByHref","errors","error","self","findIndex","err","href","getMapLayers","component","mapLayers","options","layers","sssi","push","getLocationFieldViewModel","viewModel","context","collection","fieldset","existingFieldset","label","subViewModels","getViewModel","fieldErrors","forEach","model","errorMessage","text","hasFieldErrors","type","value","classes","prefix","suffix","toString","baseItem","id","showFieldsetError","legend","result","country","countries","at","instructionText","createLocationFieldValidator","payload","helpers","values","getFormValueFromState","getStateFromValidForm","missing","keys","key","isState","required"],"sources":["../../../../../src/server/plugins/engine/components/LocationFieldHelpers.ts"],"sourcesContent":["import { type Context, type CustomValidator } from 'joi'\n\nimport { EastingNorthingField } from '~/src/server/plugins/engine/components/EastingNorthingField.js'\nimport { isFormValue } from '~/src/server/plugins/engine/components/FormComponent.js'\nimport { type GeospatialField } from '~/src/server/plugins/engine/components/GeospatialField.js'\nimport { type LatLongField } from '~/src/server/plugins/engine/components/LatLongField.js'\nimport { type OsGridRefField } from '~/src/server/plugins/engine/components/OsGridRefField.js'\nimport {\n type DateInputItem,\n type Label,\n type RenderContext,\n type ViewModel\n} from '~/src/server/plugins/engine/components/types.js'\nimport { type Translator } from '~/src/server/plugins/engine/i18n/types.js'\nimport {\n type FormPayload,\n type FormSubmissionError,\n type FormValue\n} from '~/src/server/plugins/engine/types.js'\n\nexport type LocationField =\n | InstanceType<typeof EastingNorthingField>\n | InstanceType<typeof LatLongField>\n\n/**\n * Lowercases the start of a message for concatenation.\n * Handles patterns like:\n * - \"Enter latitude\" -> \"enter latitude\"\n * - \"Enter a valid latitude...\" -> \"enter a valid latitude...\"\n * - \"latitude must be...\" -> \"latitude must be...\"\n */\nfunction lowercaseMessageStart(message: string): string {\n // Lowercase first character for a message\n return message.charAt(0).toLowerCase() + message.slice(1)\n}\n\nexport function joinWithAnd(items: string[], translator: Translator): string {\n const { t } = translator\n if (items.length === 2) {\n return `${items[0]} ${t('common.and')} ${items[1]}`\n }\n\n const leading = items.slice(0, -1).join(', ')\n const last = items[items.length - 1]\n return `${leading} ${t('common.and')} ${last}`\n}\n\nexport function formatErrorList(\n messages: string[],\n translator: Translator\n): string {\n if (!messages.length) {\n return ''\n }\n\n if (messages.length === 1) {\n return messages[0]\n }\n\n const formattedMessages = messages.map((msg, index) =>\n index === 0 ? msg : lowercaseMessageStart(msg)\n )\n\n return joinWithAnd(formattedMessages, translator)\n}\n\nexport function mergeCssClasses(...classNames: (string | undefined)[]) {\n const tokens = classNames\n .flatMap((name) => name?.split(/\\s+/) ?? [])\n .map((token) => token.trim())\n .filter(Boolean)\n\n if (!tokens.length) {\n return undefined\n }\n\n return Array.from(new Set(tokens)).join(' ')\n}\n\nexport function deduplicateErrorsByHref(\n errors?: FormSubmissionError[]\n): FormSubmissionError[] | undefined {\n if (!errors?.length) {\n return undefined\n }\n\n return errors.filter(\n (error, index, self) =>\n index === self.findIndex((err) => err.href === error.href)\n )\n}\n\nexport function getMapLayers(\n component:\n | GeospatialField\n | OsGridRefField\n | LatLongField\n | EastingNorthingField\n) {\n const { mapLayers } = component.options\n const layers = []\n\n if (mapLayers?.sssi) {\n layers.push('sssi')\n }\n\n return layers.join(',')\n}\n\nexport function getLocationFieldViewModel(\n component: LocationField,\n viewModel: ViewModel & {\n label: Label\n id: string\n name: string\n value: FormValue\n },\n context: RenderContext\n) {\n const { collection } = component\n const { fieldset: existingFieldset, label } = viewModel\n\n const subViewModels = collection.getViewModel(context)\n\n const fieldErrors: string[] = []\n subViewModels.forEach(({ model }) => {\n if (model.errorMessage?.text) {\n fieldErrors.push(model.errorMessage.text)\n }\n })\n\n const hasFieldErrors = fieldErrors.length > 0\n\n const items: DateInputItem[] = subViewModels.map(\n ({ model }): DateInputItem => {\n let { label, type, value, classes, prefix, suffix, errorMessage } = model\n\n if (label) {\n label.toString = () => label.text\n }\n\n if (!isFormValue(value)) {\n value = undefined\n }\n\n const baseItem: DateInputItem = {\n label,\n id: model.id,\n name: model.name,\n type,\n value,\n classes: mergeCssClasses(\n classes,\n hasFieldErrors ? 'govuk-input--error' : undefined\n ),\n prefix,\n suffix\n }\n\n if (!hasFieldErrors && errorMessage) {\n baseItem.errorMessage = errorMessage\n }\n\n return baseItem\n }\n )\n\n const showFieldsetError =\n hasFieldErrors || Boolean(viewModel.errorMessage?.text)\n\n viewModel.showFieldsetError = showFieldsetError\n\n if (hasFieldErrors) {\n viewModel.errorMessage = {\n text:\n fieldErrors.length === 1\n ? fieldErrors[0]\n : formatErrorList(fieldErrors, context.translator)\n }\n }\n\n const fieldset = existingFieldset ?? {\n legend: {\n text: label.text,\n classes: 'govuk-fieldset__legend--m'\n }\n }\n\n const result = {\n ...viewModel,\n fieldset,\n items,\n mapLayers: getMapLayers(component),\n country:\n component instanceof EastingNorthingField\n ? component.options.countries?.at(0)\n : undefined\n }\n\n if (component.options.instructionText) {\n return {\n ...result,\n instructionText: component.options.instructionText\n }\n }\n\n return result\n}\n\n/**\n * Validator factory for location-based fields.\n * This creates a validator that ensures all required fields are present.\n */\nexport function createLocationFieldValidator(\n component: LocationField\n): CustomValidator {\n return (payload: FormPayload, helpers) => {\n const { collection, name, options } = component\n\n const values = component.getFormValueFromState(\n component.getStateFromValidForm(payload)\n )\n\n const context: Context = {\n missing: collection.keys,\n key: name\n }\n\n if (!component.isState(values)) {\n return options.required !== false\n ? helpers.error('object.required', context)\n : payload\n }\n\n return payload\n }\n}\n"],"mappings":"AAEA,SAASA,oBAAoB;AAC7B,SAASC,WAAW;AAqBpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASC,qBAAqBA,CAACC,OAAe,EAAU;EACtD;EACA,OAAOA,OAAO,CAACC,MAAM,CAAC,CAAC,CAAC,CAACC,WAAW,CAAC,CAAC,GAAGF,OAAO,CAACG,KAAK,CAAC,CAAC,CAAC;AAC3D;AAEA,OAAO,SAASC,WAAWA,CAACC,KAAe,EAAEC,UAAsB,EAAU;EAC3E,MAAM;IAAEC;EAAE,CAAC,GAAGD,UAAU;EACxB,IAAID,KAAK,CAACG,MAAM,KAAK,CAAC,EAAE;IACtB,OAAO,GAAGH,KAAK,CAAC,CAAC,CAAC,IAAIE,CAAC,CAAC,YAAY,CAAC,IAAIF,KAAK,CAAC,CAAC,CAAC,EAAE;EACrD;EAEA,MAAMI,OAAO,GAAGJ,KAAK,CAACF,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAACO,IAAI,CAAC,IAAI,CAAC;EAC7C,MAAMC,IAAI,GAAGN,KAAK,CAACA,KAAK,CAACG,MAAM,GAAG,CAAC,CAAC;EACpC,OAAO,GAAGC,OAAO,IAAIF,CAAC,CAAC,YAAY,CAAC,IAAII,IAAI,EAAE;AAChD;AAEA,OAAO,SAASC,eAAeA,CAC7BC,QAAkB,EAClBP,UAAsB,EACd;EACR,IAAI,CAACO,QAAQ,CAACL,MAAM,EAAE;IACpB,OAAO,EAAE;EACX;EAEA,IAAIK,QAAQ,CAACL,MAAM,KAAK,CAAC,EAAE;IACzB,OAAOK,QAAQ,CAAC,CAAC,CAAC;EACpB;EAEA,MAAMC,iBAAiB,GAAGD,QAAQ,CAACE,GAAG,CAAC,CAACC,GAAG,EAAEC,KAAK,KAChDA,KAAK,KAAK,CAAC,GAAGD,GAAG,GAAGjB,qBAAqB,CAACiB,GAAG,CAC/C,CAAC;EAED,OAAOZ,WAAW,CAACU,iBAAiB,EAAER,UAAU,CAAC;AACnD;AAEA,OAAO,SAASY,eAAeA,CAAC,GAAGC,UAAkC,EAAE;EACrE,MAAMC,MAAM,GAAGD,UAAU,CACtBE,OAAO,CAAEC,IAAI,IAAKA,IAAI,EAAEC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAC3CR,GAAG,CAAES,KAAK,IAAKA,KAAK,CAACC,IAAI,CAAC,CAAC,CAAC,CAC5BC,MAAM,CAACC,OAAO,CAAC;EAElB,IAAI,CAACP,MAAM,CAACZ,MAAM,EAAE;IAClB,OAAOoB,SAAS;EAClB;EAEA,OAAOC,KAAK,CAACC,IAAI,CAAC,IAAIC,GAAG,CAACX,MAAM,CAAC,CAAC,CAACV,IAAI,CAAC,GAAG,CAAC;AAC9C;AAEA,OAAO,SAASsB,uBAAuBA,CACrCC,MAA8B,EACK;EACnC,IAAI,CAACA,MAAM,EAAEzB,MAAM,EAAE;IACnB,OAAOoB,SAAS;EAClB;EAEA,OAAOK,MAAM,CAACP,MAAM,CAClB,CAACQ,KAAK,EAAEjB,KAAK,EAAEkB,IAAI,KACjBlB,KAAK,KAAKkB,IAAI,CAACC,SAAS,CAAEC,GAAG,IAAKA,GAAG,CAACC,IAAI,KAAKJ,KAAK,CAACI,IAAI,CAC7D,CAAC;AACH;AAEA,OAAO,SAASC,YAAYA,CAC1BC,SAIwB,EACxB;EACA,MAAM;IAAEC;EAAU,CAAC,GAAGD,SAAS,CAACE,OAAO;EACvC,MAAMC,MAAM,GAAG,EAAE;EAEjB,IAAIF,SAAS,EAAEG,IAAI,EAAE;IACnBD,MAAM,CAACE,IAAI,CAAC,MAAM,CAAC;EACrB;EAEA,OAAOF,MAAM,CAACjC,IAAI,CAAC,GAAG,CAAC;AACzB;AAEA,OAAO,SAASoC,yBAAyBA,CACvCN,SAAwB,EACxBO,SAKC,EACDC,OAAsB,EACtB;EACA,MAAM;IAAEC;EAAW,CAAC,GAAGT,SAAS;EAChC,MAAM;IAAEU,QAAQ,EAAEC,gBAAgB;IAAEC;EAAM,CAAC,GAAGL,SAAS;EAEvD,MAAMM,aAAa,GAAGJ,UAAU,CAACK,YAAY,CAACN,OAAO,CAAC;EAEtD,MAAMO,WAAqB,GAAG,EAAE;EAChCF,aAAa,CAACG,OAAO,CAAC,CAAC;IAAEC;EAAM,CAAC,KAAK;IACnC,IAAIA,KAAK,CAACC,YAAY,EAAEC,IAAI,EAAE;MAC5BJ,WAAW,CAACV,IAAI,CAACY,KAAK,CAACC,YAAY,CAACC,IAAI,CAAC;IAC3C;EACF,CAAC,CAAC;EAEF,MAAMC,cAAc,GAAGL,WAAW,CAAC/C,MAAM,GAAG,CAAC;EAE7C,MAAMH,KAAsB,GAAGgD,aAAa,CAACtC,GAAG,CAC9C,CAAC;IAAE0C;EAAM,CAAC,KAAoB;IAC5B,IAAI;MAAEL,KAAK;MAAES,IAAI;MAAEC,KAAK;MAAEC,OAAO;MAAEC,MAAM;MAAEC,MAAM;MAAEP;IAAa,CAAC,GAAGD,KAAK;IAEzE,IAAIL,KAAK,EAAE;MACTA,KAAK,CAACc,QAAQ,GAAG,MAAMd,KAAK,CAACO,IAAI;IACnC;IAEA,IAAI,CAAC7D,WAAW,CAACgE,KAAK,CAAC,EAAE;MACvBA,KAAK,GAAGlC,SAAS;IACnB;IAEA,MAAMuC,QAAuB,GAAG;MAC9Bf,KAAK;MACLgB,EAAE,EAAEX,KAAK,CAACW,EAAE;MACZ9C,IAAI,EAAEmC,KAAK,CAACnC,IAAI;MAChBuC,IAAI;MACJC,KAAK;MACLC,OAAO,EAAE7C,eAAe,CACtB6C,OAAO,EACPH,cAAc,GAAG,oBAAoB,GAAGhC,SAC1C,CAAC;MACDoC,MAAM;MACNC;IACF,CAAC;IAED,IAAI,CAACL,cAAc,IAAIF,YAAY,EAAE;MACnCS,QAAQ,CAACT,YAAY,GAAGA,YAAY;IACtC;IAEA,OAAOS,QAAQ;EACjB,CACF,CAAC;EAED,MAAME,iBAAiB,GACrBT,cAAc,IAAIjC,OAAO,CAACoB,SAAS,CAACW,YAAY,EAAEC,IAAI,CAAC;EAEzDZ,SAAS,CAACsB,iBAAiB,GAAGA,iBAAiB;EAE/C,IAAIT,cAAc,EAAE;IAClBb,SAAS,CAACW,YAAY,GAAG;MACvBC,IAAI,EACFJ,WAAW,CAAC/C,MAAM,KAAK,CAAC,GACpB+C,WAAW,CAAC,CAAC,CAAC,GACd3C,eAAe,CAAC2C,WAAW,EAAEP,OAAO,CAAC1C,UAAU;IACvD,CAAC;EACH;EAEA,MAAM4C,QAAQ,GAAGC,gBAAgB,IAAI;IACnCmB,MAAM,EAAE;MACNX,IAAI,EAAEP,KAAK,CAACO,IAAI;MAChBI,OAAO,EAAE;IACX;EACF,CAAC;EAED,MAAMQ,MAAM,GAAG;IACb,GAAGxB,SAAS;IACZG,QAAQ;IACR7C,KAAK;IACLoC,SAAS,EAAEF,YAAY,CAACC,SAAS,CAAC;IAClCgC,OAAO,EACLhC,SAAS,YAAY3C,oBAAoB,GACrC2C,SAAS,CAACE,OAAO,CAAC+B,SAAS,EAAEC,EAAE,CAAC,CAAC,CAAC,GAClC9C;EACR,CAAC;EAED,IAAIY,SAAS,CAACE,OAAO,CAACiC,eAAe,EAAE;IACrC,OAAO;MACL,GAAGJ,MAAM;MACTI,eAAe,EAAEnC,SAAS,CAACE,OAAO,CAACiC;IACrC,CAAC;EACH;EAEA,OAAOJ,MAAM;AACf;;AAEA;AACA;AACA;AACA;AACA,OAAO,SAASK,4BAA4BA,CAC1CpC,SAAwB,EACP;EACjB,OAAO,CAACqC,OAAoB,EAAEC,OAAO,KAAK;IACxC,MAAM;MAAE7B,UAAU;MAAE3B,IAAI;MAAEoB;IAAQ,CAAC,GAAGF,SAAS;IAE/C,MAAMuC,MAAM,GAAGvC,SAAS,CAACwC,qBAAqB,CAC5CxC,SAAS,CAACyC,qBAAqB,CAACJ,OAAO,CACzC,CAAC;IAED,MAAM7B,OAAgB,GAAG;MACvBkC,OAAO,EAAEjC,UAAU,CAACkC,IAAI;MACxBC,GAAG,EAAE9D;IACP,CAAC;IAED,IAAI,CAACkB,SAAS,CAAC6C,OAAO,CAACN,MAAM,CAAC,EAAE;MAC9B,OAAOrC,OAAO,CAAC4C,QAAQ,KAAK,KAAK,GAC7BR,OAAO,CAAC5C,KAAK,CAAC,iBAAiB,EAAEc,OAAO,CAAC,GACzC6B,OAAO;IACb;IAEA,OAAOA,OAAO;EAChB,CAAC;AACH","ignoreList":[]}
|
|
@@ -22,7 +22,7 @@ export class Markdown extends ComponentBase {
|
|
|
22
22
|
} = context.translator;
|
|
23
23
|
return {
|
|
24
24
|
...viewModel,
|
|
25
|
-
content: tComponent(this, 'content') || content,
|
|
25
|
+
content: tComponent(this.def, 'content') || content,
|
|
26
26
|
headerStartLevel: this.headerStartLevel
|
|
27
27
|
};
|
|
28
28
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Markdown.js","names":["ComponentBase","Markdown","content","headerStartLevel","constructor","def","props","options","getViewModel","context","viewModel","tComponent","translator"],"sources":["../../../../../src/server/plugins/engine/components/Markdown.ts"],"sourcesContent":["import { type
|
|
1
|
+
{"version":3,"file":"Markdown.js","names":["ComponentBase","Markdown","content","headerStartLevel","constructor","def","props","options","getViewModel","context","viewModel","tComponent","translator"],"sources":["../../../../../src/server/plugins/engine/components/Markdown.ts"],"sourcesContent":["import { type MarkdownComponent } from '@defra/forms-model'\n\nimport { ComponentBase } from '~/src/server/plugins/engine/components/ComponentBase.js'\nimport { type RenderContext } from '~/src/server/plugins/engine/components/types.js'\n\nexport class Markdown extends ComponentBase {\n declare options: MarkdownComponent['options']\n content: MarkdownComponent['content']\n headerStartLevel: number\n\n constructor(\n def: MarkdownComponent,\n props: ConstructorParameters<typeof ComponentBase>[1]\n ) {\n super(def, props)\n\n const { content, options } = def\n\n this.content = content\n this.options = options\n this.headerStartLevel = 2\n }\n\n getViewModel(context: RenderContext) {\n const { content, viewModel } = this\n\n const { tComponent } = context.translator\n\n return {\n ...viewModel,\n content: tComponent(this.def, 'content') || content,\n headerStartLevel: this.headerStartLevel\n }\n }\n}\n"],"mappings":"AAEA,SAASA,aAAa;AAGtB,OAAO,MAAMC,QAAQ,SAASD,aAAa,CAAC;EAE1CE,OAAO;EACPC,gBAAgB;EAEhBC,WAAWA,CACTC,GAAsB,EACtBC,KAAqD,EACrD;IACA,KAAK,CAACD,GAAG,EAAEC,KAAK,CAAC;IAEjB,MAAM;MAAEJ,OAAO;MAAEK;IAAQ,CAAC,GAAGF,GAAG;IAEhC,IAAI,CAACH,OAAO,GAAGA,OAAO;IACtB,IAAI,CAACK,OAAO,GAAGA,OAAO;IACtB,IAAI,CAACJ,gBAAgB,GAAG,CAAC;EAC3B;EAEAK,YAAYA,CAACC,OAAsB,EAAE;IACnC,MAAM;MAAEP,OAAO;MAAEQ;IAAU,CAAC,GAAG,IAAI;IAEnC,MAAM;MAAEC;IAAW,CAAC,GAAGF,OAAO,CAACG,UAAU;IAEzC,OAAO;MACL,GAAGF,SAAS;MACZR,OAAO,EAAES,UAAU,CAAC,IAAI,CAACN,GAAG,EAAE,SAAS,CAAC,IAAIH,OAAO;MACnDC,gBAAgB,EAAE,IAAI,CAACA;IACzB,CAAC;EACH;AACF","ignoreList":[]}
|