@defra/forms-engine-plugin 4.0.15 → 4.0.17
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/.server/server/plugins/engine/components/AutocompleteField.d.ts +1 -0
- package/.server/server/plugins/engine/components/DatePartsField.d.ts +1 -0
- package/.server/server/plugins/engine/components/DeclarationField.d.ts +1 -0
- package/.server/server/plugins/engine/components/DeclarationField.js +1 -1
- 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 +3 -1
- package/.server/server/plugins/engine/components/EastingNorthingField.js +28 -26
- package/.server/server/plugins/engine/components/EastingNorthingField.js.map +1 -1
- package/.server/server/plugins/engine/components/EmailAddressField.d.ts +1 -0
- package/.server/server/plugins/engine/components/FileUploadField.d.ts +1 -0
- package/.server/server/plugins/engine/components/FormComponent.d.ts +1 -0
- 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 +3 -1
- package/.server/server/plugins/engine/components/LatLongField.js +23 -19
- 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 +2 -0
- package/.server/server/plugins/engine/components/LocationFieldHelpers.d.ts +6 -0
- package/.server/server/plugins/engine/components/LocationFieldHelpers.js +72 -11
- 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/MonthYearField.d.ts +1 -0
- package/.server/server/plugins/engine/components/MultilineTextField.d.ts +1 -0
- package/.server/server/plugins/engine/components/NationalGridFieldNumberField.js +1 -1
- package/.server/server/plugins/engine/components/NationalGridFieldNumberField.js.map +1 -1
- package/.server/server/plugins/engine/components/NumberField.d.ts +1 -0
- package/.server/server/plugins/engine/components/OsGridRefField.js +1 -1
- package/.server/server/plugins/engine/components/OsGridRefField.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/types.d.ts +1 -0
- package/.server/server/plugins/engine/components/types.js.map +1 -1
- package/.server/server/plugins/engine/views/components/_location-field-base.html +40 -16
- package/.server/server/plugins/engine/views/components/eastingnorthingfield.html +1 -1
- package/.server/server/plugins/engine/views/components/latlongfield.html +1 -1
- package/package.json +1 -1
- package/src/server/plugins/engine/components/DeclarationField.test.ts +30 -4
- package/src/server/plugins/engine/components/DeclarationField.ts +2 -1
- package/src/server/plugins/engine/components/EastingNorthingField.test.ts +29 -2
- package/src/server/plugins/engine/components/EastingNorthingField.ts +33 -28
- package/src/server/plugins/engine/components/LatLongField.test.ts +28 -2
- package/src/server/plugins/engine/components/LatLongField.ts +28 -22
- package/src/server/plugins/engine/components/LocationFieldHelpers.test.ts +405 -9
- package/src/server/plugins/engine/components/LocationFieldHelpers.ts +108 -12
- package/src/server/plugins/engine/components/NationalGridFieldNumberField.ts +1 -1
- package/src/server/plugins/engine/components/OsGridRefField.ts +1 -2
- package/src/server/plugins/engine/components/helpers/components.test.ts +9 -9
- package/src/server/plugins/engine/components/types.ts +1 -0
- package/src/server/plugins/engine/views/components/_location-field-base.html +40 -16
- package/src/server/plugins/engine/views/components/eastingnorthingfield.html +1 -1
- package/src/server/plugins/engine/views/components/latlongfield.html +1 -1
|
@@ -46,6 +46,7 @@ export declare class AutocompleteField extends SelectField {
|
|
|
46
46
|
attributes?: string | Record<string, string>;
|
|
47
47
|
legend?: import("./types.js").Label;
|
|
48
48
|
};
|
|
49
|
+
showFieldsetError?: boolean;
|
|
49
50
|
components?: import("./types.js").ComponentViewModel[];
|
|
50
51
|
upload?: {
|
|
51
52
|
count: number;
|
|
@@ -57,6 +57,7 @@ export declare class DatePartsField extends FormComponent {
|
|
|
57
57
|
classes?: string;
|
|
58
58
|
attributes?: string | Record<string, string>;
|
|
59
59
|
};
|
|
60
|
+
showFieldsetError?: boolean;
|
|
60
61
|
components?: import("~/src/server/plugins/engine/components/types.js").ComponentViewModel[];
|
|
61
62
|
upload?: {
|
|
62
63
|
count: number;
|
|
@@ -67,7 +67,7 @@ export class DeclarationField extends FormComponent {
|
|
|
67
67
|
content,
|
|
68
68
|
declarationConfirmationLabel = defaultDeclarationConfirmationLabel
|
|
69
69
|
} = this;
|
|
70
|
-
const isChecked =
|
|
70
|
+
const isChecked = payload[this.name] === 'true' || payload[this.name] === true;
|
|
71
71
|
return {
|
|
72
72
|
...super.getViewModel(payload, errors),
|
|
73
73
|
hint: hint ? {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DeclarationField.js","names":["joi","FormComponent","isFormValue","messageTemplate","DeclarationField","DEFAULT_DECLARATION_LABEL","constructor","def","props","options","content","checkboxSchema","string","valid","required","formSchema","array","items","strip","label","single","messages","declarationRequired","stateSchema","boolean","cast","declarationConfirmationLabel","getFormValueFromState","state","name","getFormDataFromState","getStateFromValidForm","payload","payloadValue","value","isValue","length","every","v","getContextValueFromFormValue","getFormValue","undefined","getDisplayStringFromFormValue","getViewModel","errors","defaultDeclarationConfirmationLabel","title","hint","isChecked","text","fieldset","legend","checked","Array","isArray","getAllPossibleErrors","baseErrors","type","template","advancedSettingsErrors","isBool"],"sources":["../../../../../src/server/plugins/engine/components/DeclarationField.ts"],"sourcesContent":["import { type DeclarationFieldComponent, type Item } from '@defra/forms-model'\nimport joi, {\n type ArraySchema,\n type BooleanSchema,\n type StringSchema\n} from 'joi'\n\nimport {\n FormComponent,\n isFormValue\n} from '~/src/server/plugins/engine/components/FormComponent.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 type FormValue\n} from '~/src/server/plugins/engine/types.js'\n\nexport class DeclarationField extends FormComponent {\n private readonly DEFAULT_DECLARATION_LABEL = 'I understand and agree'\n\n declare options: DeclarationFieldComponent['options']\n\n declare declarationConfirmationLabel: string\n\n declare formSchema: ArraySchema<StringSchema[]>\n declare stateSchema: BooleanSchema\n declare content: string\n\n constructor(\n def: DeclarationFieldComponent,\n props: ConstructorParameters<typeof FormComponent>[1]\n ) {\n super(def, props)\n\n const { options, content } = def\n\n let checkboxSchema = joi.string().valid('true')\n\n if (options.required !== false) {\n checkboxSchema = checkboxSchema.required()\n }\n\n const formSchema = joi\n .array()\n .items(checkboxSchema, joi.string().valid('unchecked').strip())\n .label(this.label)\n .single()\n .messages({\n 'any.required': messageTemplate.declarationRequired as string,\n 'any.unknown': messageTemplate.declarationRequired as string,\n 'array.includesRequiredUnknowns':\n messageTemplate.declarationRequired as string\n }) as ArraySchema<StringSchema[]>\n\n this.formSchema = formSchema\n this.stateSchema = joi.boolean().cast('string').label(this.label).required()\n\n this.options = options\n this.content = content\n this.declarationConfirmationLabel =\n options.declarationConfirmationLabel ?? this.DEFAULT_DECLARATION_LABEL\n }\n\n getFormValueFromState(state: FormSubmissionState) {\n const { name } = this\n return state[name] === true ? 'true' : 'unchecked'\n }\n\n getFormDataFromState(state: FormSubmissionState): FormPayload {\n const { name } = this\n return { [name]: state[name] === true ? 'true' : 'unchecked' }\n }\n\n getStateFromValidForm(payload: FormPayload): FormState {\n const { name } = this\n const payloadValue = payload[name]\n const value =\n this.isValue(payloadValue) &&\n payloadValue.length > 0 &&\n payloadValue.every((v) => {\n return v === 'true'\n })\n\n return { [name]: value }\n }\n\n getContextValueFromFormValue(value: FormValue | FormPayload): boolean {\n return value === 'true'\n }\n\n getFormValue(value?: FormStateValue | FormState) {\n return this.isValue(value) ? value : undefined\n }\n\n getDisplayStringFromFormValue(value: FormValue | FormPayload): string {\n return value === 'true' ? this.declarationConfirmationLabel : 'Not provided'\n }\n\n getViewModel(payload: FormPayload, errors?: FormSubmissionError[]) {\n const defaultDeclarationConfirmationLabel =\n 'I confirm that I understand and accept this declaration'\n const {\n title,\n hint,\n content,\n declarationConfirmationLabel = defaultDeclarationConfirmationLabel\n } = this\n const isChecked
|
|
1
|
+
{"version":3,"file":"DeclarationField.js","names":["joi","FormComponent","isFormValue","messageTemplate","DeclarationField","DEFAULT_DECLARATION_LABEL","constructor","def","props","options","content","checkboxSchema","string","valid","required","formSchema","array","items","strip","label","single","messages","declarationRequired","stateSchema","boolean","cast","declarationConfirmationLabel","getFormValueFromState","state","name","getFormDataFromState","getStateFromValidForm","payload","payloadValue","value","isValue","length","every","v","getContextValueFromFormValue","getFormValue","undefined","getDisplayStringFromFormValue","getViewModel","errors","defaultDeclarationConfirmationLabel","title","hint","isChecked","text","fieldset","legend","checked","Array","isArray","getAllPossibleErrors","baseErrors","type","template","advancedSettingsErrors","isBool"],"sources":["../../../../../src/server/plugins/engine/components/DeclarationField.ts"],"sourcesContent":["import { type DeclarationFieldComponent, type Item } from '@defra/forms-model'\nimport joi, {\n type ArraySchema,\n type BooleanSchema,\n type StringSchema\n} from 'joi'\n\nimport {\n FormComponent,\n isFormValue\n} from '~/src/server/plugins/engine/components/FormComponent.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 type FormValue\n} from '~/src/server/plugins/engine/types.js'\n\nexport class DeclarationField extends FormComponent {\n private readonly DEFAULT_DECLARATION_LABEL = 'I understand and agree'\n\n declare options: DeclarationFieldComponent['options']\n\n declare declarationConfirmationLabel: string\n\n declare formSchema: ArraySchema<StringSchema[]>\n declare stateSchema: BooleanSchema\n declare content: string\n\n constructor(\n def: DeclarationFieldComponent,\n props: ConstructorParameters<typeof FormComponent>[1]\n ) {\n super(def, props)\n\n const { options, content } = def\n\n let checkboxSchema = joi.string().valid('true')\n\n if (options.required !== false) {\n checkboxSchema = checkboxSchema.required()\n }\n\n const formSchema = joi\n .array()\n .items(checkboxSchema, joi.string().valid('unchecked').strip())\n .label(this.label)\n .single()\n .messages({\n 'any.required': messageTemplate.declarationRequired as string,\n 'any.unknown': messageTemplate.declarationRequired as string,\n 'array.includesRequiredUnknowns':\n messageTemplate.declarationRequired as string\n }) as ArraySchema<StringSchema[]>\n\n this.formSchema = formSchema\n this.stateSchema = joi.boolean().cast('string').label(this.label).required()\n\n this.options = options\n this.content = content\n this.declarationConfirmationLabel =\n options.declarationConfirmationLabel ?? this.DEFAULT_DECLARATION_LABEL\n }\n\n getFormValueFromState(state: FormSubmissionState) {\n const { name } = this\n return state[name] === true ? 'true' : 'unchecked'\n }\n\n getFormDataFromState(state: FormSubmissionState): FormPayload {\n const { name } = this\n return { [name]: state[name] === true ? 'true' : 'unchecked' }\n }\n\n getStateFromValidForm(payload: FormPayload): FormState {\n const { name } = this\n const payloadValue = payload[name]\n const value =\n this.isValue(payloadValue) &&\n payloadValue.length > 0 &&\n payloadValue.every((v) => {\n return v === 'true'\n })\n\n return { [name]: value }\n }\n\n getContextValueFromFormValue(value: FormValue | FormPayload): boolean {\n return value === 'true'\n }\n\n getFormValue(value?: FormStateValue | FormState) {\n return this.isValue(value) ? value : undefined\n }\n\n getDisplayStringFromFormValue(value: FormValue | FormPayload): string {\n return value === 'true' ? this.declarationConfirmationLabel : 'Not provided'\n }\n\n getViewModel(payload: FormPayload, errors?: FormSubmissionError[]) {\n const defaultDeclarationConfirmationLabel =\n 'I confirm that I understand and accept this declaration'\n const {\n title,\n hint,\n content,\n declarationConfirmationLabel = defaultDeclarationConfirmationLabel\n } = this\n const isChecked =\n payload[this.name] === 'true' || payload[this.name] === true\n return {\n ...super.getViewModel(payload, errors),\n hint: hint ? { text: hint } : undefined,\n fieldset: {\n legend: {\n text: title\n }\n },\n content,\n items: [\n {\n text: declarationConfirmationLabel,\n value: 'true',\n checked: isChecked\n }\n ]\n }\n }\n\n isValue(value?: FormStateValue | FormState): value is Item['value'][] {\n if (!Array.isArray(value)) {\n return false\n }\n\n // Skip checks when empty\n if (!value.length) {\n return true\n }\n\n return value.every(isFormValue)\n }\n\n /**\n * For error preview page that shows all possible errors on a component\n */\n getAllPossibleErrors(): ErrorMessageTemplateList {\n return DeclarationField.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.declarationRequired }\n ],\n advancedSettingsErrors: []\n }\n }\n\n static isBool(value?: FormStateValue | FormState): value is boolean {\n return isFormValue(value) && typeof value === 'boolean'\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -55,6 +55,7 @@ export declare class EastingNorthingField extends FormComponent {
|
|
|
55
55
|
classes?: string;
|
|
56
56
|
attributes?: string | Record<string, string>;
|
|
57
57
|
};
|
|
58
|
+
showFieldsetError?: boolean;
|
|
58
59
|
components?: import("~/src/server/plugins/engine/components/types.js").ComponentViewModel[];
|
|
59
60
|
upload?: {
|
|
60
61
|
count: number;
|
|
@@ -101,12 +102,14 @@ export declare class EastingNorthingField extends FormComponent {
|
|
|
101
102
|
classes?: string;
|
|
102
103
|
attributes?: string | Record<string, string>;
|
|
103
104
|
};
|
|
105
|
+
showFieldsetError?: boolean;
|
|
104
106
|
components?: import("~/src/server/plugins/engine/components/types.js").ComponentViewModel[];
|
|
105
107
|
upload?: {
|
|
106
108
|
count: number;
|
|
107
109
|
summaryList: import("~/src/server/plugins/engine/types.js").SummaryList;
|
|
108
110
|
};
|
|
109
111
|
};
|
|
112
|
+
getViewErrors(errors?: FormSubmissionError[]): FormSubmissionError[] | undefined;
|
|
110
113
|
isState(value?: FormStateValue | FormState): value is EastingNorthingState;
|
|
111
114
|
/**
|
|
112
115
|
* For error preview page that shows all possible errors on a component
|
|
@@ -118,4 +121,3 @@ export declare class EastingNorthingField extends FormComponent {
|
|
|
118
121
|
static getAllPossibleErrors(): ErrorMessageTemplateList;
|
|
119
122
|
static isEastingNorthing(value?: FormStateValue | FormState): value is EastingNorthingState;
|
|
120
123
|
}
|
|
121
|
-
export declare function getValidatorEastingNorthing(component: EastingNorthingField): import("joi").CustomValidator;
|
|
@@ -2,7 +2,7 @@ import { ComponentType } from '@defra/forms-model';
|
|
|
2
2
|
import lowerFirst from 'lodash/lowerFirst.js';
|
|
3
3
|
import { ComponentCollection } from "./ComponentCollection.js";
|
|
4
4
|
import { FormComponent, isFormState } from "./FormComponent.js";
|
|
5
|
-
import {
|
|
5
|
+
import { deduplicateErrorsByHref, getLocationFieldViewModel } from "./LocationFieldHelpers.js";
|
|
6
6
|
import { NumberField } from "./NumberField.js";
|
|
7
7
|
import { messageTemplate } from "../pageControllers/validationOptions.js";
|
|
8
8
|
import { convertToLanguageMessages } from "../../../utils/type-utils.js";
|
|
@@ -25,23 +25,27 @@ export class EastingNorthingField extends FormComponent {
|
|
|
25
25
|
const eastingMax = schema?.easting?.max ?? DEFAULT_EASTING_MAX;
|
|
26
26
|
const northingMin = schema?.northing?.min ?? DEFAULT_NORTHING_MIN;
|
|
27
27
|
const northingMax = schema?.northing?.max ?? DEFAULT_NORTHING_MAX;
|
|
28
|
+
const eastingRequired = 'Enter easting';
|
|
29
|
+
const northingRequired = 'Enter northing';
|
|
30
|
+
const eastingDigitsMessage = `{{#label}} for ${lowerFirst(this.label)} must be between 1 and 6 digits`;
|
|
31
|
+
const northingDigitsMessage = `{{#label}} for ${lowerFirst(this.label)} must be between 1 and 7 digits`;
|
|
28
32
|
const customValidationMessages = convertToLanguageMessages({
|
|
29
|
-
'any.required':
|
|
30
|
-
'number.base':
|
|
33
|
+
'any.required': eastingRequired,
|
|
34
|
+
'number.base': eastingRequired,
|
|
31
35
|
'number.min': `{{#label}} for ${lowerFirst(this.label)} must be between {{#limit}} and ${eastingMax}`,
|
|
32
36
|
'number.max': `{{#label}} for ${lowerFirst(this.label)} must be between ${eastingMin} and {{#limit}}`,
|
|
33
|
-
'number.precision':
|
|
34
|
-
'number.integer':
|
|
35
|
-
'number.unsafe':
|
|
37
|
+
'number.precision': eastingDigitsMessage,
|
|
38
|
+
'number.integer': eastingDigitsMessage,
|
|
39
|
+
'number.unsafe': eastingDigitsMessage
|
|
36
40
|
});
|
|
37
41
|
const northingValidationMessages = convertToLanguageMessages({
|
|
38
|
-
'any.required':
|
|
39
|
-
'number.base':
|
|
42
|
+
'any.required': northingRequired,
|
|
43
|
+
'number.base': northingRequired,
|
|
40
44
|
'number.min': `{{#label}} for ${lowerFirst(this.label)} must be between {{#limit}} and ${northingMax}`,
|
|
41
45
|
'number.max': `{{#label}} for ${lowerFirst(this.label)} must be between ${northingMin} and {{#limit}}`,
|
|
42
|
-
'number.precision':
|
|
43
|
-
'number.integer':
|
|
44
|
-
'number.unsafe':
|
|
46
|
+
'number.precision': northingDigitsMessage,
|
|
47
|
+
'number.integer': northingDigitsMessage,
|
|
48
|
+
'number.unsafe': northingDigitsMessage
|
|
45
49
|
});
|
|
46
50
|
this.collection = new ComponentCollection([{
|
|
47
51
|
type: ComponentType.NumberField,
|
|
@@ -77,7 +81,6 @@ export class EastingNorthingField extends FormComponent {
|
|
|
77
81
|
...props,
|
|
78
82
|
parent: this
|
|
79
83
|
}, {
|
|
80
|
-
custom: getValidatorEastingNorthing(this),
|
|
81
84
|
peers: [`${name}__easting`, `${name}__northing`]
|
|
82
85
|
});
|
|
83
86
|
this.options = options;
|
|
@@ -93,8 +96,8 @@ export class EastingNorthingField extends FormComponent {
|
|
|
93
96
|
return '';
|
|
94
97
|
}
|
|
95
98
|
|
|
96
|
-
// CYA page format: <<
|
|
97
|
-
return `${value.
|
|
99
|
+
// CYA page format: <<eastingvalue, northingvalue>>
|
|
100
|
+
return `${value.easting}, ${value.northing}`;
|
|
98
101
|
}
|
|
99
102
|
getDisplayStringFromState(state) {
|
|
100
103
|
const value = this.getFormValueFromState(state);
|
|
@@ -104,9 +107,7 @@ export class EastingNorthingField extends FormComponent {
|
|
|
104
107
|
if (!value) {
|
|
105
108
|
return null;
|
|
106
109
|
}
|
|
107
|
-
|
|
108
|
-
// Output format: Northing: <<entry>>\nEasting: <<entry>>
|
|
109
|
-
return `Northing: ${value.northing}\nEasting: ${value.easting}`;
|
|
110
|
+
return `Easting: ${value.easting}\nNorthing: ${value.northing}`;
|
|
110
111
|
}
|
|
111
112
|
getContextValueFromState(state) {
|
|
112
113
|
const value = this.getFormValueFromState(state);
|
|
@@ -116,6 +117,10 @@ export class EastingNorthingField extends FormComponent {
|
|
|
116
117
|
const viewModel = super.getViewModel(payload, errors);
|
|
117
118
|
return getLocationFieldViewModel(this, viewModel, payload, errors);
|
|
118
119
|
}
|
|
120
|
+
getViewErrors(errors) {
|
|
121
|
+
const allErrors = this.getErrors(errors);
|
|
122
|
+
return deduplicateErrorsByHref(allErrors);
|
|
123
|
+
}
|
|
119
124
|
isState(value) {
|
|
120
125
|
return EastingNorthingField.isEastingNorthing(value);
|
|
121
126
|
}
|
|
@@ -137,23 +142,23 @@ export class EastingNorthingField extends FormComponent {
|
|
|
137
142
|
template: messageTemplate.required
|
|
138
143
|
}, {
|
|
139
144
|
type: 'eastingFormat',
|
|
140
|
-
template: 'Easting for
|
|
145
|
+
template: 'Easting for {{#title}} must be between 1 and 6 digits'
|
|
141
146
|
}, {
|
|
142
147
|
type: 'northingFormat',
|
|
143
|
-
template: 'Northing for
|
|
148
|
+
template: 'Northing for {{#title}} must be between 1 and 7 digits'
|
|
144
149
|
}],
|
|
145
150
|
advancedSettingsErrors: [{
|
|
146
151
|
type: 'eastingMin',
|
|
147
|
-
template: `Easting for
|
|
152
|
+
template: `Easting for {{#title}} must be between ${DEFAULT_EASTING_MIN} and ${DEFAULT_EASTING_MAX}`
|
|
148
153
|
}, {
|
|
149
154
|
type: 'eastingMax',
|
|
150
|
-
template: `Easting for
|
|
155
|
+
template: `Easting for {{#title}} must be between ${DEFAULT_EASTING_MIN} and ${DEFAULT_EASTING_MAX}`
|
|
151
156
|
}, {
|
|
152
157
|
type: 'northingMin',
|
|
153
|
-
template: `Northing for
|
|
158
|
+
template: `Northing for {{#title}} must be between ${DEFAULT_NORTHING_MIN} and ${DEFAULT_NORTHING_MAX}`
|
|
154
159
|
}, {
|
|
155
160
|
type: 'northingMax',
|
|
156
|
-
template: `Northing for
|
|
161
|
+
template: `Northing for {{#title}} must be between ${DEFAULT_NORTHING_MIN} and ${DEFAULT_NORTHING_MAX}`
|
|
157
162
|
}]
|
|
158
163
|
};
|
|
159
164
|
}
|
|
@@ -161,7 +166,4 @@ export class EastingNorthingField extends FormComponent {
|
|
|
161
166
|
return isFormState(value) && NumberField.isNumber(value.easting) && NumberField.isNumber(value.northing);
|
|
162
167
|
}
|
|
163
168
|
}
|
|
164
|
-
export function getValidatorEastingNorthing(component) {
|
|
165
|
-
return createLocationFieldValidator(component);
|
|
166
|
-
}
|
|
167
169
|
//# sourceMappingURL=EastingNorthingField.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EastingNorthingField.js","names":["ComponentType","lowerFirst","ComponentCollection","FormComponent","isFormState","createLocationFieldValidator","getLocationFieldViewModel","NumberField","messageTemplate","convertToLanguageMessages","DEFAULT_EASTING_MIN","DEFAULT_EASTING_MAX","DEFAULT_NORTHING_MIN","DEFAULT_NORTHING_MAX","EastingNorthingField","constructor","def","props","name","options","schema","isRequired","required","eastingMin","easting","min","eastingMax","max","northingMin","northing","northingMax","customValidationMessages","objectMissing","label","northingValidationMessages","collection","type","title","precision","optionalText","classes","parent","custom","getValidatorEastingNorthing","peers","formSchema","stateSchema","getFormValueFromState","state","value","isEastingNorthing","undefined","getDisplayStringFromFormValue","getDisplayStringFromState","getContextValueFromFormValue","getContextValueFromState","getViewModel","payload","errors","viewModel","isState","getAllPossibleErrors","baseErrors","template","advancedSettingsErrors","isNumber","component"],"sources":["../../../../../src/server/plugins/engine/components/EastingNorthingField.ts"],"sourcesContent":["import {\n ComponentType,\n type EastingNorthingFieldComponent\n} 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 createLocationFieldValidator,\n getLocationFieldViewModel\n} from '~/src/server/plugins/engine/components/LocationFieldHelpers.js'\nimport { NumberField } from '~/src/server/plugins/engine/components/NumberField.js'\nimport { type EastingNorthingState } from '~/src/server/plugins/engine/components/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// British National Grid coordinate limits\nconst DEFAULT_EASTING_MIN = 0\nconst DEFAULT_EASTING_MAX = 700000\nconst DEFAULT_NORTHING_MIN = 0\nconst DEFAULT_NORTHING_MAX = 1300000\n\nexport class EastingNorthingField extends FormComponent {\n declare options: EastingNorthingFieldComponent['options']\n declare formSchema: ObjectSchema<FormPayload>\n declare stateSchema: ObjectSchema<FormState>\n declare collection: ComponentCollection\n\n constructor(\n def: EastingNorthingFieldComponent,\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 eastingMin = schema?.easting?.min ?? DEFAULT_EASTING_MIN\n const eastingMax = schema?.easting?.max ?? DEFAULT_EASTING_MAX\n const northingMin = schema?.northing?.min ?? DEFAULT_NORTHING_MIN\n const northingMax = schema?.northing?.max ?? DEFAULT_NORTHING_MAX\n\n const customValidationMessages: LanguageMessages =\n convertToLanguageMessages({\n 'any.required': messageTemplate.objectMissing,\n 'number.base': messageTemplate.objectMissing,\n 'number.min': `{{#label}} for ${lowerFirst(this.label)} must be between {{#limit}} and ${eastingMax}`,\n 'number.max': `{{#label}} for ${lowerFirst(this.label)} must be between ${eastingMin} and {{#limit}}`,\n 'number.precision': `{{#label}} for ${lowerFirst(this.label)} must be between 1 and 6 digits`,\n 'number.integer': `{{#label}} for ${lowerFirst(this.label)} must be between 1 and 6 digits`,\n 'number.unsafe': `{{#label}} for ${lowerFirst(this.label)} must be between 1 and 6 digits`\n })\n\n const northingValidationMessages: LanguageMessages =\n convertToLanguageMessages({\n 'any.required': messageTemplate.objectMissing,\n 'number.base': messageTemplate.objectMissing,\n 'number.min': `{{#label}} for ${lowerFirst(this.label)} must be between {{#limit}} and ${northingMax}`,\n 'number.max': `{{#label}} for ${lowerFirst(this.label)} must be between ${northingMin} and {{#limit}}`,\n 'number.precision': `{{#label}} for ${lowerFirst(this.label)} must be between 1 and 7 digits`,\n 'number.integer': `{{#label}} for ${lowerFirst(this.label)} must be between 1 and 7 digits`,\n 'number.unsafe': `{{#label}} for ${lowerFirst(this.label)} must be between 1 and 7 digits`\n })\n\n this.collection = new ComponentCollection(\n [\n {\n type: ComponentType.NumberField,\n name: `${name}__easting`,\n title: 'Easting',\n schema: {\n min: eastingMin,\n max: eastingMax,\n precision: 0\n },\n options: {\n required: isRequired,\n optionalText: true,\n classes: 'govuk-input--width-10',\n customValidationMessages\n }\n },\n {\n type: ComponentType.NumberField,\n name: `${name}__northing`,\n title: 'Northing',\n schema: {\n min: northingMin,\n max: northingMax,\n precision: 0\n },\n options: {\n required: isRequired,\n optionalText: true,\n classes: 'govuk-input--width-10',\n customValidationMessages: northingValidationMessages\n }\n }\n ],\n { ...props, parent: this },\n {\n custom: getValidatorEastingNorthing(this),\n peers: [`${name}__easting`, `${name}__northing`]\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 EastingNorthingField.isEastingNorthing(value) ? value : undefined\n }\n\n getDisplayStringFromFormValue(\n value: EastingNorthingState | undefined\n ): string {\n if (!value) {\n return ''\n }\n\n // CYA page format: <<northingvalue, eastingvalue>>\n return `${value.northing}, ${value.easting}`\n }\n\n getDisplayStringFromState(state: FormSubmissionState) {\n const value = this.getFormValueFromState(state)\n\n return this.getDisplayStringFromFormValue(value)\n }\n\n getContextValueFromFormValue(\n value: EastingNorthingState | undefined\n ): string | null {\n if (!value) {\n return null\n }\n\n // Output format: Northing: <<entry>>\\nEasting: <<entry>>\n return `Northing: ${value.northing}\\nEasting: ${value.easting}`\n }\n\n getContextValueFromState(state: FormSubmissionState) {\n const value = this.getFormValueFromState(state)\n\n return this.getContextValueFromFormValue(value)\n }\n\n getViewModel(payload: FormPayload, errors?: FormSubmissionError[]) {\n const viewModel = super.getViewModel(payload, errors)\n return getLocationFieldViewModel(this, viewModel, payload, errors)\n }\n\n isState(value?: FormStateValue | FormState) {\n return EastingNorthingField.isEastingNorthing(value)\n }\n\n /**\n * For error preview page that shows all possible errors on a component\n */\n getAllPossibleErrors(): ErrorMessageTemplateList {\n return EastingNorthingField.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: 'eastingFormat',\n template:\n 'Easting for [short description] must be between 1 and 6 digits'\n },\n {\n type: 'northingFormat',\n template:\n 'Northing for [short description] must be between 1 and 7 digits'\n }\n ],\n advancedSettingsErrors: [\n {\n type: 'eastingMin',\n template: `Easting for [short description] must be between ${DEFAULT_EASTING_MIN} and ${DEFAULT_EASTING_MAX}`\n },\n {\n type: 'eastingMax',\n template: `Easting for [short description] must be between ${DEFAULT_EASTING_MIN} and ${DEFAULT_EASTING_MAX}`\n },\n {\n type: 'northingMin',\n template: `Northing for [short description] must be between ${DEFAULT_NORTHING_MIN} and ${DEFAULT_NORTHING_MAX}`\n },\n {\n type: 'northingMax',\n template: `Northing for [short description] must be between ${DEFAULT_NORTHING_MIN} and ${DEFAULT_NORTHING_MAX}`\n }\n ]\n }\n }\n\n static isEastingNorthing(\n value?: FormStateValue | FormState\n ): value is EastingNorthingState {\n return (\n isFormState(value) &&\n NumberField.isNumber(value.easting) &&\n NumberField.isNumber(value.northing)\n )\n }\n}\n\nexport function getValidatorEastingNorthing(component: EastingNorthingField) {\n return createLocationFieldValidator(component)\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"EastingNorthingField.js","names":["ComponentType","lowerFirst","ComponentCollection","FormComponent","isFormState","deduplicateErrorsByHref","getLocationFieldViewModel","NumberField","messageTemplate","convertToLanguageMessages","DEFAULT_EASTING_MIN","DEFAULT_EASTING_MAX","DEFAULT_NORTHING_MIN","DEFAULT_NORTHING_MAX","EastingNorthingField","constructor","def","props","name","options","schema","isRequired","required","eastingMin","easting","min","eastingMax","max","northingMin","northing","northingMax","eastingRequired","northingRequired","eastingDigitsMessage","label","northingDigitsMessage","customValidationMessages","northingValidationMessages","collection","type","title","precision","optionalText","classes","parent","peers","formSchema","stateSchema","getFormValueFromState","state","value","isEastingNorthing","undefined","getDisplayStringFromFormValue","getDisplayStringFromState","getContextValueFromFormValue","getContextValueFromState","getViewModel","payload","errors","viewModel","getViewErrors","allErrors","getErrors","isState","getAllPossibleErrors","baseErrors","template","advancedSettingsErrors","isNumber"],"sources":["../../../../../src/server/plugins/engine/components/EastingNorthingField.ts"],"sourcesContent":["import {\n ComponentType,\n type EastingNorthingFieldComponent\n} 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 { type EastingNorthingState } from '~/src/server/plugins/engine/components/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// British National Grid coordinate limits\nconst DEFAULT_EASTING_MIN = 0\nconst DEFAULT_EASTING_MAX = 700000\nconst DEFAULT_NORTHING_MIN = 0\nconst DEFAULT_NORTHING_MAX = 1300000\n\nexport class EastingNorthingField extends FormComponent {\n declare options: EastingNorthingFieldComponent['options']\n declare formSchema: ObjectSchema<FormPayload>\n declare stateSchema: ObjectSchema<FormState>\n declare collection: ComponentCollection\n\n constructor(\n def: EastingNorthingFieldComponent,\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 eastingMin = schema?.easting?.min ?? DEFAULT_EASTING_MIN\n const eastingMax = schema?.easting?.max ?? DEFAULT_EASTING_MAX\n const northingMin = schema?.northing?.min ?? DEFAULT_NORTHING_MIN\n const northingMax = schema?.northing?.max ?? DEFAULT_NORTHING_MAX\n\n const eastingRequired = 'Enter easting'\n const northingRequired = 'Enter northing'\n\n const eastingDigitsMessage = `{{#label}} for ${lowerFirst(this.label)} must be between 1 and 6 digits`\n const northingDigitsMessage = `{{#label}} for ${lowerFirst(this.label)} must be between 1 and 7 digits`\n\n const customValidationMessages: LanguageMessages =\n convertToLanguageMessages({\n 'any.required': eastingRequired,\n 'number.base': eastingRequired,\n 'number.min': `{{#label}} for ${lowerFirst(this.label)} must be between {{#limit}} and ${eastingMax}`,\n 'number.max': `{{#label}} for ${lowerFirst(this.label)} must be between ${eastingMin} and {{#limit}}`,\n 'number.precision': eastingDigitsMessage,\n 'number.integer': eastingDigitsMessage,\n 'number.unsafe': eastingDigitsMessage\n })\n\n const northingValidationMessages: LanguageMessages =\n convertToLanguageMessages({\n 'any.required': northingRequired,\n 'number.base': northingRequired,\n 'number.min': `{{#label}} for ${lowerFirst(this.label)} must be between {{#limit}} and ${northingMax}`,\n 'number.max': `{{#label}} for ${lowerFirst(this.label)} must be between ${northingMin} and {{#limit}}`,\n 'number.precision': northingDigitsMessage,\n 'number.integer': northingDigitsMessage,\n 'number.unsafe': northingDigitsMessage\n })\n\n this.collection = new ComponentCollection(\n [\n {\n type: ComponentType.NumberField,\n name: `${name}__easting`,\n title: 'Easting',\n schema: {\n min: eastingMin,\n max: eastingMax,\n precision: 0\n },\n options: {\n required: isRequired,\n optionalText: true,\n classes: 'govuk-input--width-10',\n customValidationMessages\n }\n },\n {\n type: ComponentType.NumberField,\n name: `${name}__northing`,\n title: 'Northing',\n schema: {\n min: northingMin,\n max: northingMax,\n precision: 0\n },\n options: {\n required: isRequired,\n optionalText: true,\n classes: 'govuk-input--width-10',\n customValidationMessages: northingValidationMessages\n }\n }\n ],\n { ...props, parent: this },\n {\n peers: [`${name}__easting`, `${name}__northing`]\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 EastingNorthingField.isEastingNorthing(value) ? value : undefined\n }\n\n getDisplayStringFromFormValue(\n value: EastingNorthingState | undefined\n ): string {\n if (!value) {\n return ''\n }\n\n // CYA page format: <<eastingvalue, northingvalue>>\n return `${value.easting}, ${value.northing}`\n }\n\n getDisplayStringFromState(state: FormSubmissionState) {\n const value = this.getFormValueFromState(state)\n\n return this.getDisplayStringFromFormValue(value)\n }\n\n getContextValueFromFormValue(\n value: EastingNorthingState | undefined\n ): string | null {\n if (!value) {\n return null\n }\n\n return `Easting: ${value.easting}\\nNorthing: ${value.northing}`\n }\n\n getContextValueFromState(state: FormSubmissionState) {\n const value = this.getFormValueFromState(state)\n\n return this.getContextValueFromFormValue(value)\n }\n\n getViewModel(payload: FormPayload, errors?: FormSubmissionError[]) {\n const viewModel = super.getViewModel(payload, errors)\n return getLocationFieldViewModel(this, viewModel, payload, errors)\n }\n\n getViewErrors(\n errors?: FormSubmissionError[]\n ): FormSubmissionError[] | undefined {\n const allErrors = this.getErrors(errors)\n return deduplicateErrorsByHref(allErrors)\n }\n\n isState(value?: FormStateValue | FormState) {\n return EastingNorthingField.isEastingNorthing(value)\n }\n\n /**\n * For error preview page that shows all possible errors on a component\n */\n getAllPossibleErrors(): ErrorMessageTemplateList {\n return EastingNorthingField.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: 'eastingFormat',\n template: 'Easting for {{#title}} must be between 1 and 6 digits'\n },\n {\n type: 'northingFormat',\n template: 'Northing for {{#title}} must be between 1 and 7 digits'\n }\n ],\n advancedSettingsErrors: [\n {\n type: 'eastingMin',\n template: `Easting for {{#title}} must be between ${DEFAULT_EASTING_MIN} and ${DEFAULT_EASTING_MAX}`\n },\n {\n type: 'eastingMax',\n template: `Easting for {{#title}} must be between ${DEFAULT_EASTING_MIN} and ${DEFAULT_EASTING_MAX}`\n },\n {\n type: 'northingMin',\n template: `Northing for {{#title}} must be between ${DEFAULT_NORTHING_MIN} and ${DEFAULT_NORTHING_MAX}`\n },\n {\n type: 'northingMax',\n template: `Northing for {{#title}} must be between ${DEFAULT_NORTHING_MIN} and ${DEFAULT_NORTHING_MAX}`\n }\n ]\n }\n }\n\n static isEastingNorthing(\n value?: FormStateValue | FormState\n ): value is EastingNorthingState {\n return (\n isFormState(value) &&\n NumberField.isNumber(value.easting) &&\n NumberField.isNumber(value.northing)\n )\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -71,6 +71,7 @@ export declare class FileUploadField extends FormComponent {
|
|
|
71
71
|
classes?: string;
|
|
72
72
|
attributes?: string | Record<string, string>;
|
|
73
73
|
};
|
|
74
|
+
showFieldsetError?: boolean;
|
|
74
75
|
components?: import("./types.js").ComponentViewModel[];
|
|
75
76
|
};
|
|
76
77
|
isValue(value?: FormStateValue | FormState): value is UploadState;
|
|
@@ -55,6 +55,7 @@ export declare class LatLongField extends FormComponent {
|
|
|
55
55
|
classes?: string;
|
|
56
56
|
attributes?: string | Record<string, string>;
|
|
57
57
|
};
|
|
58
|
+
showFieldsetError?: boolean;
|
|
58
59
|
components?: import("~/src/server/plugins/engine/components/types.js").ComponentViewModel[];
|
|
59
60
|
upload?: {
|
|
60
61
|
count: number;
|
|
@@ -101,12 +102,14 @@ export declare class LatLongField extends FormComponent {
|
|
|
101
102
|
classes?: string;
|
|
102
103
|
attributes?: string | Record<string, string>;
|
|
103
104
|
};
|
|
105
|
+
showFieldsetError?: boolean;
|
|
104
106
|
components?: import("~/src/server/plugins/engine/components/types.js").ComponentViewModel[];
|
|
105
107
|
upload?: {
|
|
106
108
|
count: number;
|
|
107
109
|
summaryList: import("~/src/server/plugins/engine/types.js").SummaryList;
|
|
108
110
|
};
|
|
109
111
|
};
|
|
112
|
+
getViewErrors(errors?: FormSubmissionError[]): FormSubmissionError[] | undefined;
|
|
110
113
|
isState(value?: FormStateValue | FormState): value is LatLongState;
|
|
111
114
|
/**
|
|
112
115
|
* For error preview page that shows all possible errors on a component
|
|
@@ -118,4 +121,3 @@ export declare class LatLongField extends FormComponent {
|
|
|
118
121
|
static getAllPossibleErrors(): ErrorMessageTemplateList;
|
|
119
122
|
static isLatLong(value?: FormStateValue | FormState): value is LatLongState;
|
|
120
123
|
}
|
|
121
|
-
export declare function getValidatorLatLong(component: LatLongField): import("joi").CustomValidator;
|
|
@@ -2,7 +2,7 @@ import { ComponentType } from '@defra/forms-model';
|
|
|
2
2
|
import lowerFirst from 'lodash/lowerFirst.js';
|
|
3
3
|
import { ComponentCollection } from "./ComponentCollection.js";
|
|
4
4
|
import { FormComponent, isFormState } from "./FormComponent.js";
|
|
5
|
-
import {
|
|
5
|
+
import { deduplicateErrorsByHref, getLocationFieldViewModel } from "./LocationFieldHelpers.js";
|
|
6
6
|
import { NumberField } from "./NumberField.js";
|
|
7
7
|
import { messageTemplate } from "../pageControllers/validationOptions.js";
|
|
8
8
|
import { convertToLanguageMessages } from "../../../utils/type-utils.js";
|
|
@@ -26,23 +26,27 @@ export class LatLongField extends FormComponent {
|
|
|
26
26
|
const latitudeMax = schema?.latitude?.max ?? 60.859;
|
|
27
27
|
const longitudeMin = schema?.longitude?.min ?? -13.687;
|
|
28
28
|
const longitudeMax = schema?.longitude?.max ?? 1.767;
|
|
29
|
+
const latitudeRequired = 'Enter latitude';
|
|
30
|
+
const longitudeRequired = 'Enter longitude';
|
|
29
31
|
const customValidationMessages = convertToLanguageMessages({
|
|
30
|
-
'any.required': messageTemplate.objectMissing,
|
|
31
|
-
'number.base': messageTemplate.objectMissing,
|
|
32
32
|
'number.precision': '{{#label}} must have no more than 7 decimal places',
|
|
33
33
|
'number.unsafe': '{{#label}} must be a valid number'
|
|
34
34
|
});
|
|
35
|
+
const latitudeRangeMessage = `Latitude for ${lowerFirst(this.label)} must be between ${latitudeMin} and ${latitudeMax}`;
|
|
36
|
+
const longitudeRangeMessage = `Longitude for ${lowerFirst(this.label)} must be between ${longitudeMin} and ${longitudeMax}`;
|
|
35
37
|
const latitudeMessages = convertToLanguageMessages({
|
|
36
38
|
...customValidationMessages,
|
|
39
|
+
'any.required': latitudeRequired,
|
|
37
40
|
'number.base': `Enter a valid latitude for ${lowerFirst(this.label)} like 51.519450`,
|
|
38
|
-
'number.min':
|
|
39
|
-
'number.max':
|
|
41
|
+
'number.min': latitudeRangeMessage,
|
|
42
|
+
'number.max': latitudeRangeMessage
|
|
40
43
|
});
|
|
41
44
|
const longitudeMessages = convertToLanguageMessages({
|
|
42
45
|
...customValidationMessages,
|
|
46
|
+
'any.required': longitudeRequired,
|
|
43
47
|
'number.base': `Enter a valid longitude for ${lowerFirst(this.label)} like -0.127758`,
|
|
44
|
-
'number.min':
|
|
45
|
-
'number.max':
|
|
48
|
+
'number.min': longitudeRangeMessage,
|
|
49
|
+
'number.max': longitudeRangeMessage
|
|
46
50
|
});
|
|
47
51
|
this.collection = new ComponentCollection([{
|
|
48
52
|
type: ComponentType.NumberField,
|
|
@@ -80,7 +84,6 @@ export class LatLongField extends FormComponent {
|
|
|
80
84
|
...props,
|
|
81
85
|
parent: this
|
|
82
86
|
}, {
|
|
83
|
-
custom: getValidatorLatLong(this),
|
|
84
87
|
peers: [`${name}__latitude`, `${name}__longitude`]
|
|
85
88
|
});
|
|
86
89
|
this.options = options;
|
|
@@ -108,8 +111,8 @@ export class LatLongField extends FormComponent {
|
|
|
108
111
|
return null;
|
|
109
112
|
}
|
|
110
113
|
|
|
111
|
-
// Output format:
|
|
112
|
-
return `
|
|
114
|
+
// Output format: Latitude: <<entry>>\nLongitude: <<entry>>
|
|
115
|
+
return `Latitude: ${value.latitude}\nLongitude: ${value.longitude}`;
|
|
113
116
|
}
|
|
114
117
|
getContextValueFromState(state) {
|
|
115
118
|
const value = this.getFormValueFromState(state);
|
|
@@ -119,6 +122,10 @@ export class LatLongField extends FormComponent {
|
|
|
119
122
|
const viewModel = super.getViewModel(payload, errors);
|
|
120
123
|
return getLocationFieldViewModel(this, viewModel, payload, errors);
|
|
121
124
|
}
|
|
125
|
+
getViewErrors(errors) {
|
|
126
|
+
const allErrors = this.getErrors(errors);
|
|
127
|
+
return deduplicateErrorsByHref(allErrors);
|
|
128
|
+
}
|
|
122
129
|
isState(value) {
|
|
123
130
|
return LatLongField.isLatLong(value);
|
|
124
131
|
}
|
|
@@ -140,23 +147,23 @@ export class LatLongField extends FormComponent {
|
|
|
140
147
|
template: messageTemplate.required
|
|
141
148
|
}, {
|
|
142
149
|
type: 'latitudeFormat',
|
|
143
|
-
template: 'Enter a valid latitude for
|
|
150
|
+
template: 'Enter a valid latitude for {{#title}} like 51.519450'
|
|
144
151
|
}, {
|
|
145
152
|
type: 'longitudeFormat',
|
|
146
|
-
template: 'Enter a valid longitude for
|
|
153
|
+
template: 'Enter a valid longitude for {{#title}} like -0.127758'
|
|
147
154
|
}],
|
|
148
155
|
advancedSettingsErrors: [{
|
|
149
156
|
type: 'latitudeMin',
|
|
150
|
-
template: 'Latitude for
|
|
157
|
+
template: 'Latitude for {{#title}} must be between 49 and 60'
|
|
151
158
|
}, {
|
|
152
159
|
type: 'latitudeMax',
|
|
153
|
-
template: 'Latitude for
|
|
160
|
+
template: 'Latitude for {{#title}} must be between 49 and 60'
|
|
154
161
|
}, {
|
|
155
162
|
type: 'longitudeMin',
|
|
156
|
-
template: 'Longitude for
|
|
163
|
+
template: 'Longitude for {{#title}} must be between -9 and 2'
|
|
157
164
|
}, {
|
|
158
165
|
type: 'longitudeMax',
|
|
159
|
-
template: 'Longitude for
|
|
166
|
+
template: 'Longitude for {{#title}} must be between -9 and 2'
|
|
160
167
|
}]
|
|
161
168
|
};
|
|
162
169
|
}
|
|
@@ -164,7 +171,4 @@ export class LatLongField extends FormComponent {
|
|
|
164
171
|
return isFormState(value) && NumberField.isNumber(value.latitude) && NumberField.isNumber(value.longitude);
|
|
165
172
|
}
|
|
166
173
|
}
|
|
167
|
-
export function getValidatorLatLong(component) {
|
|
168
|
-
return createLocationFieldValidator(component);
|
|
169
|
-
}
|
|
170
174
|
//# sourceMappingURL=LatLongField.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LatLongField.js","names":["ComponentType","lowerFirst","ComponentCollection","FormComponent","isFormState","createLocationFieldValidator","getLocationFieldViewModel","NumberField","messageTemplate","convertToLanguageMessages","DECIMAL_PRECISION","LatLongField","constructor","def","props","name","options","schema","isRequired","required","latitudeMin","latitude","min","latitudeMax","max","longitudeMin","longitude","longitudeMax","customValidationMessages","objectMissing","latitudeMessages","label","longitudeMessages","collection","type","title","precision","optionalText","classes","suffix","parent","custom","getValidatorLatLong","peers","formSchema","stateSchema","getFormValueFromState","state","value","isLatLong","undefined","getDisplayStringFromFormValue","getDisplayStringFromState","getContextValueFromFormValue","getContextValueFromState","getViewModel","payload","errors","viewModel","isState","getAllPossibleErrors","baseErrors","template","advancedSettingsErrors","isNumber","component"],"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 createLocationFieldValidator,\n getLocationFieldViewModel\n} from '~/src/server/plugins/engine/components/LocationFieldHelpers.js'\nimport { NumberField } from '~/src/server/plugins/engine/components/NumberField.js'\nimport { type LatLongState } from '~/src/server/plugins/engine/components/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 customValidationMessages: LanguageMessages =\n convertToLanguageMessages({\n 'any.required': messageTemplate.objectMissing,\n 'number.base': messageTemplate.objectMissing,\n 'number.precision':\n '{{#label}} must have no more than 7 decimal places',\n 'number.unsafe': '{{#label}} must be a valid number'\n })\n\n const latitudeMessages: LanguageMessages = convertToLanguageMessages({\n ...customValidationMessages,\n 'number.base': `Enter a valid latitude for ${lowerFirst(this.label)} like 51.519450`,\n 'number.min': `Latitude for ${lowerFirst(this.label)} must be between ${latitudeMin} and ${latitudeMax}`,\n 'number.max': `Latitude for ${lowerFirst(this.label)} must be between ${latitudeMin} and ${latitudeMax}`\n })\n\n const longitudeMessages: LanguageMessages = convertToLanguageMessages({\n ...customValidationMessages,\n 'number.base': `Enter a valid longitude for ${lowerFirst(this.label)} like -0.127758`,\n 'number.min': `Longitude for ${lowerFirst(this.label)} must be between ${longitudeMin} and ${longitudeMax}`,\n 'number.max': `Longitude for ${lowerFirst(this.label)} must be between ${longitudeMin} and ${longitudeMax}`\n })\n\n this.collection = new ComponentCollection(\n [\n {\n type: ComponentType.NumberField,\n name: `${name}__latitude`,\n title: '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: '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 custom: getValidatorLatLong(this),\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(value: LatLongState | undefined): string {\n if (!value) {\n return ''\n }\n\n // CYA page format: <<latvalue, langvalue>>\n return `${value.latitude}, ${value.longitude}`\n }\n\n getDisplayStringFromState(state: FormSubmissionState) {\n const value = this.getFormValueFromState(state)\n\n return this.getDisplayStringFromFormValue(value)\n }\n\n getContextValueFromFormValue(value: LatLongState | undefined): string | null {\n if (!value) {\n return null\n }\n\n // Output format: Lat: <<entry>>\\nLong: <<entry>>\n return `Lat: ${value.latitude}\\nLong: ${value.longitude}`\n }\n\n getContextValueFromState(state: FormSubmissionState) {\n const value = this.getFormValueFromState(state)\n\n return this.getContextValueFromFormValue(value)\n }\n\n getViewModel(payload: FormPayload, errors?: FormSubmissionError[]) {\n const viewModel = super.getViewModel(payload, errors)\n return getLocationFieldViewModel(this, viewModel, payload, errors)\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:\n 'Enter a valid latitude for [short description] like 51.519450'\n },\n {\n type: 'longitudeFormat',\n template:\n 'Enter a valid longitude for [short description] like -0.127758'\n }\n ],\n advancedSettingsErrors: [\n {\n type: 'latitudeMin',\n template: 'Latitude for [short description] must be between 49 and 60'\n },\n {\n type: 'latitudeMax',\n template: 'Latitude for [short description] must be between 49 and 60'\n },\n {\n type: 'longitudeMin',\n template: 'Longitude for [short description] must be between -9 and 2'\n },\n {\n type: 'longitudeMax',\n template: 'Longitude for [short description] must be between -9 and 2'\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\nexport function getValidatorLatLong(component: LatLongField) {\n return createLocationFieldValidator(component)\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"LatLongField.js","names":["ComponentType","lowerFirst","ComponentCollection","FormComponent","isFormState","deduplicateErrorsByHref","getLocationFieldViewModel","NumberField","messageTemplate","convertToLanguageMessages","DECIMAL_PRECISION","LatLongField","constructor","def","props","name","options","schema","isRequired","required","latitudeMin","latitude","min","latitudeMax","max","longitudeMin","longitude","longitudeMax","latitudeRequired","longitudeRequired","customValidationMessages","latitudeRangeMessage","label","longitudeRangeMessage","latitudeMessages","longitudeMessages","collection","type","title","precision","optionalText","classes","suffix","parent","peers","formSchema","stateSchema","getFormValueFromState","state","value","isLatLong","undefined","getDisplayStringFromFormValue","getDisplayStringFromState","getContextValueFromFormValue","getContextValueFromState","getViewModel","payload","errors","viewModel","getViewErrors","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 { type LatLongState } from '~/src/server/plugins/engine/components/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 latitudeRequired = 'Enter latitude'\n const longitudeRequired = 'Enter longitude'\n\n const customValidationMessages: LanguageMessages =\n convertToLanguageMessages({\n 'number.precision':\n '{{#label}} must have no more than 7 decimal places',\n 'number.unsafe': '{{#label}} must be a valid number'\n })\n\n const latitudeRangeMessage = `Latitude for ${lowerFirst(this.label)} must be between ${latitudeMin} and ${latitudeMax}`\n const longitudeRangeMessage = `Longitude for ${lowerFirst(this.label)} must be between ${longitudeMin} and ${longitudeMax}`\n\n const latitudeMessages: LanguageMessages = convertToLanguageMessages({\n ...customValidationMessages,\n 'any.required': latitudeRequired,\n 'number.base': `Enter a valid latitude for ${lowerFirst(this.label)} like 51.519450`,\n 'number.min': latitudeRangeMessage,\n 'number.max': latitudeRangeMessage\n })\n\n const longitudeMessages: LanguageMessages = convertToLanguageMessages({\n ...customValidationMessages,\n 'any.required': longitudeRequired,\n 'number.base': `Enter a valid longitude for ${lowerFirst(this.label)} like -0.127758`,\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: '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: '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(value: LatLongState | undefined): string {\n if (!value) {\n return ''\n }\n\n // CYA page format: <<latvalue, langvalue>>\n return `${value.latitude}, ${value.longitude}`\n }\n\n getDisplayStringFromState(state: FormSubmissionState) {\n const value = this.getFormValueFromState(state)\n\n return this.getDisplayStringFromFormValue(value)\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(payload: FormPayload, errors?: FormSubmissionError[]) {\n const viewModel = super.getViewModel(payload, errors)\n return getLocationFieldViewModel(this, viewModel, payload, errors)\n }\n\n getViewErrors(\n errors?: FormSubmissionError[]\n ): FormSubmissionError[] | undefined {\n const allErrors = this.getErrors(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: 'Enter a valid latitude for {{#title}} like 51.519450'\n },\n {\n type: 'longitudeFormat',\n template: 'Enter a valid longitude for {{#title}} like -0.127758'\n }\n ],\n advancedSettingsErrors: [\n {\n type: 'latitudeMin',\n template: 'Latitude for {{#title}} must be between 49 and 60'\n },\n {\n type: 'latitudeMax',\n template: 'Latitude for {{#title}} must be between 49 and 60'\n },\n {\n type: 'longitudeMin',\n template: 'Longitude for {{#title}} must be between -9 and 2'\n },\n {\n type: 'longitudeMax',\n template: 'Longitude for {{#title}} must be between -9 and 2'\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":[]}
|
|
@@ -47,6 +47,7 @@ export declare class List extends ComponentBase {
|
|
|
47
47
|
classes?: string;
|
|
48
48
|
attributes?: string | Record<string, string>;
|
|
49
49
|
};
|
|
50
|
+
showFieldsetError?: boolean;
|
|
50
51
|
components?: import("~/src/server/plugins/engine/components/types.js").ComponentViewModel[];
|
|
51
52
|
upload?: {
|
|
52
53
|
count: number;
|
|
@@ -59,6 +59,7 @@ export declare class ListFormComponent extends FormComponent {
|
|
|
59
59
|
classes?: string;
|
|
60
60
|
attributes?: string | Record<string, string>;
|
|
61
61
|
};
|
|
62
|
+
showFieldsetError?: boolean;
|
|
62
63
|
components?: import("~/src/server/plugins/engine/components/types.js").ComponentViewModel[];
|
|
63
64
|
upload?: {
|
|
64
65
|
count: number;
|
|
@@ -72,6 +72,7 @@ export declare abstract class LocationFieldBase extends FormComponent {
|
|
|
72
72
|
classes?: string;
|
|
73
73
|
attributes?: string | Record<string, string>;
|
|
74
74
|
};
|
|
75
|
+
showFieldsetError?: boolean;
|
|
75
76
|
components?: import("./types.js").ComponentViewModel[];
|
|
76
77
|
upload?: {
|
|
77
78
|
count: number;
|
|
@@ -120,6 +121,7 @@ export declare abstract class LocationFieldBase extends FormComponent {
|
|
|
120
121
|
classes?: string;
|
|
121
122
|
attributes?: string | Record<string, string>;
|
|
122
123
|
};
|
|
124
|
+
showFieldsetError?: boolean;
|
|
123
125
|
components?: import("./types.js").ComponentViewModel[];
|
|
124
126
|
upload?: {
|
|
125
127
|
count: number;
|