@defra/forms-engine-plugin 4.0.12 → 4.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/.public/stylesheets/application.min.css +1 -1
  2. package/.public/stylesheets/application.min.css.map +1 -1
  3. package/.server/client/stylesheets/application.scss +0 -1
  4. package/.server/client/stylesheets/shared.scss +0 -1
  5. package/.server/server/forms/register-as-a-unicorn-breeder.yaml +4 -2
  6. package/.server/server/plugins/engine/components/EastingNorthingField.js +13 -12
  7. package/.server/server/plugins/engine/components/EastingNorthingField.js.map +1 -1
  8. package/.server/server/plugins/engine/components/EmailAddressField.d.ts +7 -1
  9. package/.server/server/plugins/engine/components/LatLongField.js +7 -6
  10. package/.server/server/plugins/engine/components/LatLongField.js.map +1 -1
  11. package/.server/server/plugins/engine/components/LocationFieldHelpers.js +3 -9
  12. package/.server/server/plugins/engine/components/LocationFieldHelpers.js.map +1 -1
  13. package/.server/server/plugins/engine/components/NationalGridFieldNumberField.js +5 -5
  14. package/.server/server/plugins/engine/components/NationalGridFieldNumberField.js.map +1 -1
  15. package/.server/server/plugins/engine/components/OsGridRefField.js +8 -4
  16. package/.server/server/plugins/engine/components/OsGridRefField.js.map +1 -1
  17. package/.server/server/plugins/engine/components/types.d.ts +3 -0
  18. package/.server/server/plugins/engine/components/types.js.map +1 -1
  19. package/.server/server/plugins/engine/models/FormModel.d.ts +2 -2
  20. package/.server/server/plugins/engine/models/FormModel.js +1 -1
  21. package/.server/server/plugins/engine/models/FormModel.js.map +1 -1
  22. package/.server/server/plugins/engine/models/types.d.ts +1 -1
  23. package/.server/server/plugins/engine/models/types.js.map +1 -1
  24. package/.server/server/plugins/engine/views/components/_location-field-base.html +22 -14
  25. package/package.json +2 -2
  26. package/src/client/stylesheets/application.scss +0 -1
  27. package/src/client/stylesheets/shared.scss +0 -1
  28. package/src/server/forms/register-as-a-unicorn-breeder.yaml +4 -2
  29. package/src/server/plugins/engine/components/EastingNorthingField.test.ts +9 -3
  30. package/src/server/plugins/engine/components/EastingNorthingField.ts +13 -12
  31. package/src/server/plugins/engine/components/LatLongField.test.ts +9 -3
  32. package/src/server/plugins/engine/components/LatLongField.ts +7 -6
  33. package/src/server/plugins/engine/components/LocationFieldHelpers.test.ts +14 -5
  34. package/src/server/plugins/engine/components/LocationFieldHelpers.ts +3 -9
  35. package/src/server/plugins/engine/components/NationalGridFieldNumberField.test.ts +9 -12
  36. package/src/server/plugins/engine/components/NationalGridFieldNumberField.ts +5 -5
  37. package/src/server/plugins/engine/components/OsGridRefField.test.ts +19 -6
  38. package/src/server/plugins/engine/components/OsGridRefField.ts +8 -4
  39. package/src/server/plugins/engine/components/types.ts +3 -0
  40. package/src/server/plugins/engine/models/FormModel.ts +1 -1
  41. package/src/server/plugins/engine/models/types.ts +1 -1
  42. package/src/server/plugins/engine/views/components/_location-field-base.html +22 -14
  43. package/.server/client/stylesheets/_location-input.scss +0 -60
  44. package/src/client/stylesheets/_location-input.scss +0 -60
@@ -2,7 +2,6 @@
2
2
  @use "shared";
3
3
  @use "code";
4
4
  @use "tag-env";
5
- @use "location-input";
6
5
 
7
6
  // An example of some user-supplied styling
8
7
  // Not great practice but it illustrates the point
@@ -2,7 +2,6 @@
2
2
  @use "pkg:accessible-autocomplete";
3
3
  @use "prose";
4
4
  @use "summary-list";
5
- @use "location-input";
6
5
 
7
6
  // Use default GDS Transport font for autocomplete
8
7
  .autocomplete__hint,
@@ -168,15 +168,17 @@ pages:
168
168
  schema: {}
169
169
  type: EastingNorthingField
170
170
  title: Easting and northing
171
+ shortDescription: Location
171
172
  hint:
172
173
  This is an Easting and Northing component
173
174
  - name: seTThb
174
175
  options: {}
175
176
  schema: {}
176
177
  type: LatLongField
177
- title: Latitute and longitude
178
+ title: Latitude and longitude
179
+ shortDescription: Position
178
180
  hint:
179
- This is an Latitute and Longitude component
181
+ This is an Latitude and Longitude component
180
182
  - name: bhjloS
181
183
  options: {}
182
184
  schema: {}
@@ -1,4 +1,5 @@
1
1
  import { ComponentType } from '@defra/forms-model';
2
+ import lowerFirst from 'lodash/lowerFirst.js';
2
3
  import { ComponentCollection } from "./ComponentCollection.js";
3
4
  import { FormComponent, isFormState } from "./FormComponent.js";
4
5
  import { createLocationFieldValidator, getLocationFieldViewModel } from "./LocationFieldHelpers.js";
@@ -27,20 +28,20 @@ export class EastingNorthingField extends FormComponent {
27
28
  const customValidationMessages = convertToLanguageMessages({
28
29
  'any.required': messageTemplate.objectMissing,
29
30
  'number.base': messageTemplate.objectMissing,
30
- 'number.min': `{{#label}} for ${this.title} must be between {{#limit}} and ${eastingMax}`,
31
- 'number.max': `{{#label}} for ${this.title} must be between ${eastingMin} and {{#limit}}`,
32
- 'number.precision': `{{#label}} for ${this.title} must be between 1 and 6 digits`,
33
- 'number.integer': `{{#label}} for ${this.title} must be between 1 and 6 digits`,
34
- 'number.unsafe': `{{#label}} for ${this.title} must be between 1 and 6 digits`
31
+ 'number.min': `{{#label}} for ${lowerFirst(this.label)} must be between {{#limit}} and ${eastingMax}`,
32
+ 'number.max': `{{#label}} for ${lowerFirst(this.label)} must be between ${eastingMin} and {{#limit}}`,
33
+ 'number.precision': `{{#label}} for ${lowerFirst(this.label)} must be between 1 and 6 digits`,
34
+ 'number.integer': `{{#label}} for ${lowerFirst(this.label)} must be between 1 and 6 digits`,
35
+ 'number.unsafe': `{{#label}} for ${lowerFirst(this.label)} must be between 1 and 6 digits`
35
36
  });
36
37
  const northingValidationMessages = convertToLanguageMessages({
37
38
  'any.required': messageTemplate.objectMissing,
38
39
  'number.base': messageTemplate.objectMissing,
39
- 'number.min': `{{#label}} for ${this.title} must be between {{#limit}} and ${northingMax}`,
40
- 'number.max': `{{#label}} for ${this.title} must be between ${northingMin} and {{#limit}}`,
41
- 'number.precision': `{{#label}} for ${this.title} must be between 1 and 7 digits`,
42
- 'number.integer': `{{#label}} for ${this.title} must be between 1 and 7 digits`,
43
- 'number.unsafe': `{{#label}} for ${this.title} must be between 1 and 7 digits`
40
+ 'number.min': `{{#label}} for ${lowerFirst(this.label)} must be between {{#limit}} and ${northingMax}`,
41
+ 'number.max': `{{#label}} for ${lowerFirst(this.label)} must be between ${northingMin} and {{#limit}}`,
42
+ 'number.precision': `{{#label}} for ${lowerFirst(this.label)} must be between 1 and 7 digits`,
43
+ 'number.integer': `{{#label}} for ${lowerFirst(this.label)} must be between 1 and 7 digits`,
44
+ 'number.unsafe': `{{#label}} for ${lowerFirst(this.label)} must be between 1 and 7 digits`
44
45
  });
45
46
  this.collection = new ComponentCollection([{
46
47
  type: ComponentType.NumberField,
@@ -143,10 +144,10 @@ export class EastingNorthingField extends FormComponent {
143
144
  }],
144
145
  advancedSettingsErrors: [{
145
146
  type: 'eastingMin',
146
- template: `Easting for [short description] must be between 0 and 700000`
147
+ template: `Easting for [short description] must be between ${DEFAULT_EASTING_MIN} and ${DEFAULT_EASTING_MAX}`
147
148
  }, {
148
149
  type: 'eastingMax',
149
- template: `Easting for [short description] must be between 0 and 700000`
150
+ template: `Easting for [short description] must be between ${DEFAULT_EASTING_MIN} and ${DEFAULT_EASTING_MAX}`
150
151
  }, {
151
152
  type: 'northingMin',
152
153
  template: `Northing for [short description] must be between ${DEFAULT_NORTHING_MIN} and ${DEFAULT_NORTHING_MAX}`
@@ -1 +1 @@
1
- {"version":3,"file":"EastingNorthingField.js","names":["ComponentType","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","title","northingValidationMessages","collection","type","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'\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 ${this.title} must be between {{#limit}} and ${eastingMax}`,\n 'number.max': `{{#label}} for ${this.title} must be between ${eastingMin} and {{#limit}}`,\n 'number.precision': `{{#label}} for ${this.title} must be between 1 and 6 digits`,\n 'number.integer': `{{#label}} for ${this.title} must be between 1 and 6 digits`,\n 'number.unsafe': `{{#label}} for ${this.title} 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 ${this.title} must be between {{#limit}} and ${northingMax}`,\n 'number.max': `{{#label}} for ${this.title} must be between ${northingMin} and {{#limit}}`,\n 'number.precision': `{{#label}} for ${this.title} must be between 1 and 7 digits`,\n 'number.integer': `{{#label}} for ${this.title} must be between 1 and 7 digits`,\n 'number.unsafe': `{{#label}} for ${this.title} 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 0 and 700000`\n },\n {\n type: 'eastingMax',\n template: `Easting for [short description] must be between 0 and 700000`\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","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":[]}
@@ -30,7 +30,13 @@ export declare class EmailAddressField extends FormComponent {
30
30
  autocomplete?: string;
31
31
  maxlength?: number;
32
32
  multiple?: string;
33
- accept?: string;
33
+ accept
34
+ /**
35
+ * Static version of getAllPossibleErrors that doesn't require a component instance.
36
+ */
37
+ ? /**
38
+ * Static version of getAllPossibleErrors that doesn't require a component instance.
39
+ */: string;
34
40
  inputmode?: string;
35
41
  };
36
42
  content?: import("./types.js").Content | import("./types.js").Content[] | string;
@@ -1,4 +1,5 @@
1
1
  import { ComponentType } from '@defra/forms-model';
2
+ import lowerFirst from 'lodash/lowerFirst.js';
2
3
  import { ComponentCollection } from "./ComponentCollection.js";
3
4
  import { FormComponent, isFormState } from "./FormComponent.js";
4
5
  import { createLocationFieldValidator, getLocationFieldViewModel } from "./LocationFieldHelpers.js";
@@ -33,15 +34,15 @@ export class LatLongField extends FormComponent {
33
34
  });
34
35
  const latitudeMessages = convertToLanguageMessages({
35
36
  ...customValidationMessages,
36
- 'number.base': `Enter a valid latitude for ${this.title} like 51.519450`,
37
- 'number.min': `Latitude for ${this.title} must be between ${latitudeMin} and ${latitudeMax}`,
38
- 'number.max': `Latitude for ${this.title} must be between ${latitudeMin} and ${latitudeMax}`
37
+ 'number.base': `Enter a valid latitude for ${lowerFirst(this.label)} like 51.519450`,
38
+ 'number.min': `Latitude for ${lowerFirst(this.label)} must be between ${latitudeMin} and ${latitudeMax}`,
39
+ 'number.max': `Latitude for ${lowerFirst(this.label)} must be between ${latitudeMin} and ${latitudeMax}`
39
40
  });
40
41
  const longitudeMessages = convertToLanguageMessages({
41
42
  ...customValidationMessages,
42
- 'number.base': `Enter a valid longitude for ${this.title} like -0.127758`,
43
- 'number.min': `Longitude for ${this.title} must be between ${longitudeMin} and ${longitudeMax}`,
44
- 'number.max': `Longitude for ${this.title} must be between ${longitudeMin} and ${longitudeMax}`
43
+ 'number.base': `Enter a valid longitude for ${lowerFirst(this.label)} like -0.127758`,
44
+ 'number.min': `Longitude for ${lowerFirst(this.label)} must be between ${longitudeMin} and ${longitudeMax}`,
45
+ 'number.max': `Longitude for ${lowerFirst(this.label)} must be between ${longitudeMin} and ${longitudeMax}`
45
46
  });
46
47
  this.collection = new ComponentCollection([{
47
48
  type: ComponentType.NumberField,
@@ -1 +1 @@
1
- {"version":3,"file":"LatLongField.js","names":["ComponentType","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","title","longitudeMessages","collection","type","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'\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 ${this.title} like 51.519450`,\n 'number.min': `Latitude for ${this.title} must be between ${latitudeMin} and ${latitudeMax}`,\n 'number.max': `Latitude for ${this.title} must be between ${latitudeMin} and ${latitudeMax}`\n })\n\n const longitudeMessages: LanguageMessages = convertToLanguageMessages({\n ...customValidationMessages,\n 'number.base': `Enter a valid longitude for ${this.title} like -0.127758`,\n 'number.min': `Longitude for ${this.title} must be between ${longitudeMin} and ${longitudeMax}`,\n 'number.max': `Longitude for ${this.title} 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":"AAAA,SAASA,aAAa,QAAoC,oBAAoB;AAG9E,SAASC,mBAAmB;AAC5B,SACEC,aAAa,EACbC,WAAW;AAEb,SACEC,4BAA4B,EAC5BC,yBAAyB;AAE3B,SAASC,WAAW;AAEpB,SAASC,eAAe;AASxB,SAASC,yBAAyB;;AAElC;AACA;AACA,MAAMC,iBAAiB,GAAG,CAAC,EAAC;;AAE5B,OAAO,MAAMC,YAAY,SAASR,aAAa,CAAC;EAM9CS,WAAWA,CACTC,GAA0B,EAC1BC,KAAqD,EACrD;IACA,KAAK,CAACD,GAAG,EAAEC,KAAK,CAAC;IAEjB,MAAM;MAAEC,IAAI;MAAEC,OAAO;MAAEC;IAAO,CAAC,GAAGJ,GAAG;IAErC,MAAMK,UAAU,GAAGF,OAAO,CAACG,QAAQ,KAAK,KAAK;;IAE7C;IACA,MAAMC,WAAW,GAAGH,MAAM,EAAEI,QAAQ,EAAEC,GAAG,IAAI,KAAK;IAClD,MAAMC,WAAW,GAAGN,MAAM,EAAEI,QAAQ,EAAEG,GAAG,IAAI,MAAM;IACnD,MAAMC,YAAY,GAAGR,MAAM,EAAES,SAAS,EAAEJ,GAAG,IAAI,CAAC,MAAM;IACtD,MAAMK,YAAY,GAAGV,MAAM,EAAES,SAAS,EAAEF,GAAG,IAAI,KAAK;IAEpD,MAAMI,wBAA0C,GAC9CnB,yBAAyB,CAAC;MACxB,cAAc,EAAED,eAAe,CAACqB,aAAa;MAC7C,aAAa,EAAErB,eAAe,CAACqB,aAAa;MAC5C,kBAAkB,EAChB,oDAAoD;MACtD,eAAe,EAAE;IACnB,CAAC,CAAC;IAEJ,MAAMC,gBAAkC,GAAGrB,yBAAyB,CAAC;MACnE,GAAGmB,wBAAwB;MAC3B,aAAa,EAAE,8BAA8B,IAAI,CAACG,KAAK,iBAAiB;MACxE,YAAY,EAAE,gBAAgB,IAAI,CAACA,KAAK,oBAAoBX,WAAW,QAAQG,WAAW,EAAE;MAC5F,YAAY,EAAE,gBAAgB,IAAI,CAACQ,KAAK,oBAAoBX,WAAW,QAAQG,WAAW;IAC5F,CAAC,CAAC;IAEF,MAAMS,iBAAmC,GAAGvB,yBAAyB,CAAC;MACpE,GAAGmB,wBAAwB;MAC3B,aAAa,EAAE,+BAA+B,IAAI,CAACG,KAAK,iBAAiB;MACzE,YAAY,EAAE,iBAAiB,IAAI,CAACA,KAAK,oBAAoBN,YAAY,QAAQE,YAAY,EAAE;MAC/F,YAAY,EAAE,iBAAiB,IAAI,CAACI,KAAK,oBAAoBN,YAAY,QAAQE,YAAY;IAC/F,CAAC,CAAC;IAEF,IAAI,CAACM,UAAU,GAAG,IAAI/B,mBAAmB,CACvC,CACE;MACEgC,IAAI,EAAEjC,aAAa,CAACM,WAAW;MAC/BQ,IAAI,EAAE,GAAGA,IAAI,YAAY;MACzBgB,KAAK,EAAE,UAAU;MACjBd,MAAM,EAAE;QACNK,GAAG,EAAEF,WAAW;QAChBI,GAAG,EAAED,WAAW;QAChBY,SAAS,EAAEzB;MACb,CAAC;MACDM,OAAO,EAAE;QACPG,QAAQ,EAAED,UAAU;QACpBkB,YAAY,EAAE,IAAI;QAClBC,OAAO,EAAE,uBAAuB;QAChCC,MAAM,EAAE,GAAG;QACXV,wBAAwB,EAAEE;MAC5B;IACF,CAAC,EACD;MACEI,IAAI,EAAEjC,aAAa,CAACM,WAAW;MAC/BQ,IAAI,EAAE,GAAGA,IAAI,aAAa;MAC1BgB,KAAK,EAAE,WAAW;MAClBd,MAAM,EAAE;QACNK,GAAG,EAAEG,YAAY;QACjBD,GAAG,EAAEG,YAAY;QACjBQ,SAAS,EAAEzB;MACb,CAAC;MACDM,OAAO,EAAE;QACPG,QAAQ,EAAED,UAAU;QACpBkB,YAAY,EAAE,IAAI;QAClBC,OAAO,EAAE,uBAAuB;QAChCC,MAAM,EAAE,GAAG;QACXV,wBAAwB,EAAEI;MAC5B;IACF,CAAC,CACF,EACD;MAAE,GAAGlB,KAAK;MAAEyB,MAAM,EAAE;IAAK,CAAC,EAC1B;MACEC,MAAM,EAAEC,mBAAmB,CAAC,IAAI,CAAC;MACjCC,KAAK,EAAE,CAAC,GAAG3B,IAAI,YAAY,EAAE,GAAGA,IAAI,aAAa;IACnD,CACF,CAAC;IAED,IAAI,CAACC,OAAO,GAAGA,OAAO;IACtB,IAAI,CAAC2B,UAAU,GAAG,IAAI,CAACV,UAAU,CAACU,UAAU;IAC5C,IAAI,CAACC,WAAW,GAAG,IAAI,CAACX,UAAU,CAACW,WAAW;EAChD;EAEAC,qBAAqBA,CAACC,KAA0B,EAAE;IAChD,MAAMC,KAAK,GAAG,KAAK,CAACF,qBAAqB,CAACC,KAAK,CAAC;IAChD,OAAOnC,YAAY,CAACqC,SAAS,CAACD,KAAK,CAAC,GAAGA,KAAK,GAAGE,SAAS;EAC1D;EAEAC,6BAA6BA,CAACH,KAA+B,EAAU;IACrE,IAAI,CAACA,KAAK,EAAE;MACV,OAAO,EAAE;IACX;;IAEA;IACA,OAAO,GAAGA,KAAK,CAAC1B,QAAQ,KAAK0B,KAAK,CAACrB,SAAS,EAAE;EAChD;EAEAyB,yBAAyBA,CAACL,KAA0B,EAAE;IACpD,MAAMC,KAAK,GAAG,IAAI,CAACF,qBAAqB,CAACC,KAAK,CAAC;IAE/C,OAAO,IAAI,CAACI,6BAA6B,CAACH,KAAK,CAAC;EAClD;EAEAK,4BAA4BA,CAACL,KAA+B,EAAiB;IAC3E,IAAI,CAACA,KAAK,EAAE;MACV,OAAO,IAAI;IACb;;IAEA;IACA,OAAO,QAAQA,KAAK,CAAC1B,QAAQ,WAAW0B,KAAK,CAACrB,SAAS,EAAE;EAC3D;EAEA2B,wBAAwBA,CAACP,KAA0B,EAAE;IACnD,MAAMC,KAAK,GAAG,IAAI,CAACF,qBAAqB,CAACC,KAAK,CAAC;IAE/C,OAAO,IAAI,CAACM,4BAA4B,CAACL,KAAK,CAAC;EACjD;EAEAO,YAAYA,CAACC,OAAoB,EAAEC,MAA8B,EAAE;IACjE,MAAMC,SAAS,GAAG,KAAK,CAACH,YAAY,CAACC,OAAO,EAAEC,MAAM,CAAC;IACrD,OAAOlD,yBAAyB,CAAC,IAAI,EAAEmD,SAAS,EAAEF,OAAO,EAAEC,MAAM,CAAC;EACpE;EAEAE,OAAOA,CAACX,KAAkC,EAAE;IAC1C,OAAOpC,YAAY,CAACqC,SAAS,CAACD,KAAK,CAAC;EACtC;;EAEA;AACF;AACA;EACEY,oBAAoBA,CAAA,EAA6B;IAC/C,OAAOhD,YAAY,CAACgD,oBAAoB,CAAC,CAAC;EAC5C;;EAEA;AACF;AACA;EACE,OAAOA,oBAAoBA,CAAA,EAA6B;IACtD,OAAO;MACLC,UAAU,EAAE,CACV;QAAE1B,IAAI,EAAE,UAAU;QAAE2B,QAAQ,EAAErD,eAAe,CAACW;MAAS,CAAC,EACxD;QACEe,IAAI,EAAE,gBAAgB;QACtB2B,QAAQ,EACN;MACJ,CAAC,EACD;QACE3B,IAAI,EAAE,iBAAiB;QACvB2B,QAAQ,EACN;MACJ,CAAC,CACF;MACDC,sBAAsB,EAAE,CACtB;QACE5B,IAAI,EAAE,aAAa;QACnB2B,QAAQ,EAAE;MACZ,CAAC,EACD;QACE3B,IAAI,EAAE,aAAa;QACnB2B,QAAQ,EAAE;MACZ,CAAC,EACD;QACE3B,IAAI,EAAE,cAAc;QACpB2B,QAAQ,EAAE;MACZ,CAAC,EACD;QACE3B,IAAI,EAAE,cAAc;QACpB2B,QAAQ,EAAE;MACZ,CAAC;IAEL,CAAC;EACH;EAEA,OAAOb,SAASA,CAACD,KAAkC,EAAyB;IAC1E,OACE3C,WAAW,CAAC2C,KAAK,CAAC,IAClBxC,WAAW,CAACwD,QAAQ,CAAChB,KAAK,CAAC1B,QAAQ,CAAC,IACpCd,WAAW,CAACwD,QAAQ,CAAChB,KAAK,CAACrB,SAAS,CAAC;EAEzC;AACF;AAEA,OAAO,SAASe,mBAAmBA,CAACuB,SAAuB,EAAE;EAC3D,OAAO3D,4BAA4B,CAAC2D,SAAS,CAAC;AAChD","ignoreList":[]}
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":[]}
@@ -2,17 +2,13 @@ import { isFormValue } from "./FormComponent.js";
2
2
  import { markdown } from "./markdownParser.js";
3
3
  export function getLocationFieldViewModel(component, viewModel, payload, errors) {
4
4
  const {
5
- collection,
6
- name
5
+ collection
7
6
  } = component;
8
7
  const {
9
8
  fieldset: existingFieldset,
10
9
  label
11
10
  } = viewModel;
12
11
 
13
- // Check for component errors only
14
- const hasError = errors?.some(error => error.name === name);
15
-
16
12
  // Use the component collection to generate the subitems
17
13
  const items = collection.getViewModel(payload, errors).map(({
18
14
  model
@@ -29,9 +25,6 @@ export function getLocationFieldViewModel(component, viewModel, payload, errors)
29
25
  if (label) {
30
26
  label.toString = () => label.text; // Use string labels
31
27
  }
32
- if (hasError || errorMessage) {
33
- classes = `${classes ?? ''} govuk-input--error`.trim();
34
- }
35
28
 
36
29
  // Allow any `toString()`-able value so non-numeric
37
30
  // values are shown alongside their error messages
@@ -46,7 +39,8 @@ export function getLocationFieldViewModel(component, viewModel, payload, errors)
46
39
  value,
47
40
  classes,
48
41
  prefix,
49
- suffix
42
+ suffix,
43
+ errorMessage
50
44
  };
51
45
  });
52
46
  const fieldset = existingFieldset ?? {
@@ -1 +1 @@
1
- {"version":3,"file":"LocationFieldHelpers.js","names":["isFormValue","markdown","getLocationFieldViewModel","component","viewModel","payload","errors","collection","name","fieldset","existingFieldset","label","hasError","some","error","items","getViewModel","map","model","type","value","classes","prefix","suffix","errorMessage","toString","text","trim","undefined","id","legend","result","options","instructionText","parse","async","createLocationFieldValidator","helpers","values","getFormValueFromState","getStateFromValidForm","context","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 LatLongField } from '~/src/server/plugins/engine/components/LatLongField.js'\nimport { markdown } from '~/src/server/plugins/engine/components/markdownParser.js'\nimport {\n type DateInputItem,\n type Label,\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\nexport function getLocationFieldViewModel(\n component: LocationField,\n viewModel: ViewModel & {\n label: Label\n id: string\n name: string\n value: FormValue\n },\n payload: FormPayload,\n errors?: FormSubmissionError[]\n) {\n const { collection, name } = component\n const { fieldset: existingFieldset, label } = viewModel\n\n // Check for component errors only\n const hasError = errors?.some((error) => error.name === name)\n\n // Use the component collection to generate the subitems\n const items: DateInputItem[] = collection\n .getViewModel(payload, errors)\n .map(({ model }): DateInputItem => {\n let { label, type, value, classes, prefix, suffix, errorMessage } = model\n\n if (label) {\n label.toString = () => label.text // Use string labels\n }\n\n if (hasError || errorMessage) {\n classes = `${classes ?? ''} govuk-input--error`.trim()\n }\n\n // Allow any `toString()`-able value so non-numeric\n // values are shown alongside their error messages\n if (!isFormValue(value)) {\n value = undefined\n }\n\n return {\n label,\n id: model.id,\n name: model.name,\n type,\n value,\n classes,\n prefix,\n suffix\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 }\n\n if (component.options.instructionText) {\n return {\n ...result,\n instructionText: markdown.parse(component.options.instructionText, {\n async: false\n })\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":"AAGA,SAASA,WAAW;AAEpB,SAASC,QAAQ;AAgBjB,OAAO,SAASC,yBAAyBA,CACvCC,SAAwB,EACxBC,SAKC,EACDC,OAAoB,EACpBC,MAA8B,EAC9B;EACA,MAAM;IAAEC,UAAU;IAAEC;EAAK,CAAC,GAAGL,SAAS;EACtC,MAAM;IAAEM,QAAQ,EAAEC,gBAAgB;IAAEC;EAAM,CAAC,GAAGP,SAAS;;EAEvD;EACA,MAAMQ,QAAQ,GAAGN,MAAM,EAAEO,IAAI,CAAEC,KAAK,IAAKA,KAAK,CAACN,IAAI,KAAKA,IAAI,CAAC;;EAE7D;EACA,MAAMO,KAAsB,GAAGR,UAAU,CACtCS,YAAY,CAACX,OAAO,EAAEC,MAAM,CAAC,CAC7BW,GAAG,CAAC,CAAC;IAAEC;EAAM,CAAC,KAAoB;IACjC,IAAI;MAAEP,KAAK;MAAEQ,IAAI;MAAEC,KAAK;MAAEC,OAAO;MAAEC,MAAM;MAAEC,MAAM;MAAEC;IAAa,CAAC,GAAGN,KAAK;IAEzE,IAAIP,KAAK,EAAE;MACTA,KAAK,CAACc,QAAQ,GAAG,MAAMd,KAAK,CAACe,IAAI,EAAC;IACpC;IAEA,IAAId,QAAQ,IAAIY,YAAY,EAAE;MAC5BH,OAAO,GAAG,GAAGA,OAAO,IAAI,EAAE,qBAAqB,CAACM,IAAI,CAAC,CAAC;IACxD;;IAEA;IACA;IACA,IAAI,CAAC3B,WAAW,CAACoB,KAAK,CAAC,EAAE;MACvBA,KAAK,GAAGQ,SAAS;IACnB;IAEA,OAAO;MACLjB,KAAK;MACLkB,EAAE,EAAEX,KAAK,CAACW,EAAE;MACZrB,IAAI,EAAEU,KAAK,CAACV,IAAI;MAChBW,IAAI;MACJC,KAAK;MACLC,OAAO;MACPC,MAAM;MACNC;IACF,CAAC;EACH,CAAC,CAAC;EAEJ,MAAMd,QAAQ,GAAGC,gBAAgB,IAAI;IACnCoB,MAAM,EAAE;MACNJ,IAAI,EAAEf,KAAK,CAACe,IAAI;MAChBL,OAAO,EAAE;IACX;EACF,CAAC;EAED,MAAMU,MAAM,GAAG;IACb,GAAG3B,SAAS;IACZK,QAAQ;IACRM;EACF,CAAC;EAED,IAAIZ,SAAS,CAAC6B,OAAO,CAACC,eAAe,EAAE;IACrC,OAAO;MACL,GAAGF,MAAM;MACTE,eAAe,EAAEhC,QAAQ,CAACiC,KAAK,CAAC/B,SAAS,CAAC6B,OAAO,CAACC,eAAe,EAAE;QACjEE,KAAK,EAAE;MACT,CAAC;IACH,CAAC;EACH;EAEA,OAAOJ,MAAM;AACf;;AAEA;AACA;AACA;AACA;AACA,OAAO,SAASK,4BAA4BA,CAC1CjC,SAAwB,EACP;EACjB,OAAO,CAACE,OAAoB,EAAEgC,OAAO,KAAK;IACxC,MAAM;MAAE9B,UAAU;MAAEC,IAAI;MAAEwB;IAAQ,CAAC,GAAG7B,SAAS;IAE/C,MAAMmC,MAAM,GAAGnC,SAAS,CAACoC,qBAAqB,CAC5CpC,SAAS,CAACqC,qBAAqB,CAACnC,OAAO,CACzC,CAAC;IAED,MAAMoC,OAAgB,GAAG;MACvBC,OAAO,EAAEnC,UAAU,CAACoC,IAAI;MACxBC,GAAG,EAAEpC;IACP,CAAC;IAED,IAAI,CAACL,SAAS,CAAC0C,OAAO,CAACP,MAAM,CAAC,EAAE;MAC9B,OAAON,OAAO,CAACc,QAAQ,KAAK,KAAK,GAC7BT,OAAO,CAACvB,KAAK,CAAC,iBAAiB,EAAE2B,OAAO,CAAC,GACzCpC,OAAO;IACb;IAEA,OAAOA,OAAO;EAChB,CAAC;AACH","ignoreList":[]}
1
+ {"version":3,"file":"LocationFieldHelpers.js","names":["isFormValue","markdown","getLocationFieldViewModel","component","viewModel","payload","errors","collection","fieldset","existingFieldset","label","items","getViewModel","map","model","type","value","classes","prefix","suffix","errorMessage","toString","text","undefined","id","name","legend","result","options","instructionText","parse","async","createLocationFieldValidator","helpers","values","getFormValueFromState","getStateFromValidForm","context","missing","keys","key","isState","required","error"],"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 LatLongField } from '~/src/server/plugins/engine/components/LatLongField.js'\nimport { markdown } from '~/src/server/plugins/engine/components/markdownParser.js'\nimport {\n type DateInputItem,\n type Label,\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\nexport function getLocationFieldViewModel(\n component: LocationField,\n viewModel: ViewModel & {\n label: Label\n id: string\n name: string\n value: FormValue\n },\n payload: FormPayload,\n errors?: FormSubmissionError[]\n) {\n const { collection } = component\n const { fieldset: existingFieldset, label } = viewModel\n\n // Use the component collection to generate the subitems\n const items: DateInputItem[] = collection\n .getViewModel(payload, errors)\n .map(({ model }): DateInputItem => {\n let { label, type, value, classes, prefix, suffix, errorMessage } = model\n\n if (label) {\n label.toString = () => label.text // Use string labels\n }\n\n // Allow any `toString()`-able value so non-numeric\n // values are shown alongside their error messages\n if (!isFormValue(value)) {\n value = undefined\n }\n\n return {\n label,\n id: model.id,\n name: model.name,\n type,\n value,\n classes,\n prefix,\n suffix,\n errorMessage\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 }\n\n if (component.options.instructionText) {\n return {\n ...result,\n instructionText: markdown.parse(component.options.instructionText, {\n async: false\n })\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":"AAGA,SAASA,WAAW;AAEpB,SAASC,QAAQ;AAgBjB,OAAO,SAASC,yBAAyBA,CACvCC,SAAwB,EACxBC,SAKC,EACDC,OAAoB,EACpBC,MAA8B,EAC9B;EACA,MAAM;IAAEC;EAAW,CAAC,GAAGJ,SAAS;EAChC,MAAM;IAAEK,QAAQ,EAAEC,gBAAgB;IAAEC;EAAM,CAAC,GAAGN,SAAS;;EAEvD;EACA,MAAMO,KAAsB,GAAGJ,UAAU,CACtCK,YAAY,CAACP,OAAO,EAAEC,MAAM,CAAC,CAC7BO,GAAG,CAAC,CAAC;IAAEC;EAAM,CAAC,KAAoB;IACjC,IAAI;MAAEJ,KAAK;MAAEK,IAAI;MAAEC,KAAK;MAAEC,OAAO;MAAEC,MAAM;MAAEC,MAAM;MAAEC;IAAa,CAAC,GAAGN,KAAK;IAEzE,IAAIJ,KAAK,EAAE;MACTA,KAAK,CAACW,QAAQ,GAAG,MAAMX,KAAK,CAACY,IAAI,EAAC;IACpC;;IAEA;IACA;IACA,IAAI,CAACtB,WAAW,CAACgB,KAAK,CAAC,EAAE;MACvBA,KAAK,GAAGO,SAAS;IACnB;IAEA,OAAO;MACLb,KAAK;MACLc,EAAE,EAAEV,KAAK,CAACU,EAAE;MACZC,IAAI,EAAEX,KAAK,CAACW,IAAI;MAChBV,IAAI;MACJC,KAAK;MACLC,OAAO;MACPC,MAAM;MACNC,MAAM;MACNC;IACF,CAAC;EACH,CAAC,CAAC;EAEJ,MAAMZ,QAAQ,GAAGC,gBAAgB,IAAI;IACnCiB,MAAM,EAAE;MACNJ,IAAI,EAAEZ,KAAK,CAACY,IAAI;MAChBL,OAAO,EAAE;IACX;EACF,CAAC;EAED,MAAMU,MAAM,GAAG;IACb,GAAGvB,SAAS;IACZI,QAAQ;IACRG;EACF,CAAC;EAED,IAAIR,SAAS,CAACyB,OAAO,CAACC,eAAe,EAAE;IACrC,OAAO;MACL,GAAGF,MAAM;MACTE,eAAe,EAAE5B,QAAQ,CAAC6B,KAAK,CAAC3B,SAAS,CAACyB,OAAO,CAACC,eAAe,EAAE;QACjEE,KAAK,EAAE;MACT,CAAC;IACH,CAAC;EACH;EAEA,OAAOJ,MAAM;AACf;;AAEA;AACA;AACA;AACA;AACA,OAAO,SAASK,4BAA4BA,CAC1C7B,SAAwB,EACP;EACjB,OAAO,CAACE,OAAoB,EAAE4B,OAAO,KAAK;IACxC,MAAM;MAAE1B,UAAU;MAAEkB,IAAI;MAAEG;IAAQ,CAAC,GAAGzB,SAAS;IAE/C,MAAM+B,MAAM,GAAG/B,SAAS,CAACgC,qBAAqB,CAC5ChC,SAAS,CAACiC,qBAAqB,CAAC/B,OAAO,CACzC,CAAC;IAED,MAAMgC,OAAgB,GAAG;MACvBC,OAAO,EAAE/B,UAAU,CAACgC,IAAI;MACxBC,GAAG,EAAEf;IACP,CAAC;IAED,IAAI,CAACtB,SAAS,CAACsC,OAAO,CAACP,MAAM,CAAC,EAAE;MAC9B,OAAON,OAAO,CAACc,QAAQ,KAAK,KAAK,GAC7BT,OAAO,CAACU,KAAK,CAAC,iBAAiB,EAAEN,OAAO,CAAC,GACzChC,OAAO;IACb;IAEA,OAAOA,OAAO;EAChB,CAAC;AACH","ignoreList":[]}
@@ -1,14 +1,14 @@
1
+ import lowerFirst from 'lodash/lowerFirst.js';
1
2
  import { LocationFieldBase } from "./LocationFieldBase.js";
2
3
  export class NationalGridFieldNumberField extends LocationFieldBase {
3
4
  getValidationConfig() {
4
- // Regex for OS grid references and parcel IDs
5
+ // Regex for OS national grid field references (NGFR)
5
6
  // Validates specific valid OS grid letter combinations with:
6
- // - 2 letters & 8 digits in 2 blocks of 4 (parcel ID) e.g., ST 6789 6789
7
- // - 2 letters & 10 digits in 2 blocks of 5 (OS grid reference) e.g., SO 12345 12345
8
- const pattern = /^((([sS]|[nN])[a-hA-Hj-zJ-Z])|(([tT]|[oO])[abfglmqrvwABFGLMQRVW])|([hH][l-zL-Z])|([jJ][lmqrvwLMQRVW]))\s?(([0-9]{4})\s?([0-9]{4})|([0-9]{5})\s?([0-9]{5}))$/;
7
+ // - 2 letters & 8 digits in 2 blocks of 4 e.g. ST 6789 6789
8
+ const pattern = /^((([sS]|[nN])[a-hA-Hj-zJ-Z])|(([tT]|[oO])[abfglmqrvwABFGLMQRVW])|([hH][l-zL-Z])|([jJ][lmqrvwLMQRVW]))\s?([0-9]{4})\s?([0-9]{4})$/;
9
9
  return {
10
10
  pattern,
11
- patternErrorMessage: `Enter a valid National Grid field number for ${this.title} like NG 1234 5678`
11
+ patternErrorMessage: `Enter a valid National Grid field number for ${lowerFirst(this.label)} like NG 1234 5678`
12
12
  };
13
13
  }
14
14
  getErrorTemplates() {
@@ -1 +1 @@
1
- {"version":3,"file":"NationalGridFieldNumberField.js","names":["LocationFieldBase","NationalGridFieldNumberField","getValidationConfig","pattern","patternErrorMessage","title","getErrorTemplates","type","template","getAllPossibleErrors","instance","Object","create","prototype"],"sources":["../../../../../src/server/plugins/engine/components/NationalGridFieldNumberField.ts"],"sourcesContent":["import { type NationalGridFieldNumberFieldComponent } from '@defra/forms-model'\n\nimport { LocationFieldBase } from '~/src/server/plugins/engine/components/LocationFieldBase.js'\n\nexport class NationalGridFieldNumberField extends LocationFieldBase {\n declare options: NationalGridFieldNumberFieldComponent['options']\n\n protected getValidationConfig() {\n // Regex for OS grid references and parcel IDs\n // Validates specific valid OS grid letter combinations with:\n // - 2 letters & 8 digits in 2 blocks of 4 (parcel ID) e.g., ST 6789 6789\n // - 2 letters & 10 digits in 2 blocks of 5 (OS grid reference) e.g., SO 12345 12345\n const pattern =\n /^((([sS]|[nN])[a-hA-Hj-zJ-Z])|(([tT]|[oO])[abfglmqrvwABFGLMQRVW])|([hH][l-zL-Z])|([jJ][lmqrvwLMQRVW]))\\s?(([0-9]{4})\\s?([0-9]{4})|([0-9]{5})\\s?([0-9]{5}))$/\n\n return {\n pattern,\n patternErrorMessage: `Enter a valid National Grid field number for ${this.title} like NG 1234 5678`\n }\n }\n\n protected getErrorTemplates() {\n return [\n {\n type: 'pattern',\n template:\n 'Enter a valid National Grid field number for [short description] like NG 1234 5678'\n }\n ]\n }\n\n /**\n * Static version of getAllPossibleErrors that doesn't require a component instance.\n */\n static getAllPossibleErrors() {\n const instance = Object.create(\n NationalGridFieldNumberField.prototype\n ) as NationalGridFieldNumberField\n return instance.getAllPossibleErrors()\n }\n}\n"],"mappings":"AAEA,SAASA,iBAAiB;AAE1B,OAAO,MAAMC,4BAA4B,SAASD,iBAAiB,CAAC;EAGxDE,mBAAmBA,CAAA,EAAG;IAC9B;IACA;IACA;IACA;IACA,MAAMC,OAAO,GACX,6JAA6J;IAE/J,OAAO;MACLA,OAAO;MACPC,mBAAmB,EAAE,gDAAgD,IAAI,CAACC,KAAK;IACjF,CAAC;EACH;EAEUC,iBAAiBA,CAAA,EAAG;IAC5B,OAAO,CACL;MACEC,IAAI,EAAE,SAAS;MACfC,QAAQ,EACN;IACJ,CAAC,CACF;EACH;;EAEA;AACF;AACA;EACE,OAAOC,oBAAoBA,CAAA,EAAG;IAC5B,MAAMC,QAAQ,GAAGC,MAAM,CAACC,MAAM,CAC5BX,4BAA4B,CAACY,SAC/B,CAAiC;IACjC,OAAOH,QAAQ,CAACD,oBAAoB,CAAC,CAAC;EACxC;AACF","ignoreList":[]}
1
+ {"version":3,"file":"NationalGridFieldNumberField.js","names":["lowerFirst","LocationFieldBase","NationalGridFieldNumberField","getValidationConfig","pattern","patternErrorMessage","label","getErrorTemplates","type","template","getAllPossibleErrors","instance","Object","create","prototype"],"sources":["../../../../../src/server/plugins/engine/components/NationalGridFieldNumberField.ts"],"sourcesContent":["import { type NationalGridFieldNumberFieldComponent } from '@defra/forms-model'\nimport lowerFirst from 'lodash/lowerFirst.js'\n\nimport { LocationFieldBase } from '~/src/server/plugins/engine/components/LocationFieldBase.js'\n\nexport class NationalGridFieldNumberField extends LocationFieldBase {\n declare options: NationalGridFieldNumberFieldComponent['options']\n\n protected getValidationConfig() {\n // Regex for OS national grid field references (NGFR)\n // Validates specific valid OS grid letter combinations with:\n // - 2 letters & 8 digits in 2 blocks of 4 e.g. ST 6789 6789\n const pattern =\n /^((([sS]|[nN])[a-hA-Hj-zJ-Z])|(([tT]|[oO])[abfglmqrvwABFGLMQRVW])|([hH][l-zL-Z])|([jJ][lmqrvwLMQRVW]))\\s?([0-9]{4})\\s?([0-9]{4})$/\n\n return {\n pattern,\n patternErrorMessage: `Enter a valid National Grid field number for ${lowerFirst(this.label)} like NG 1234 5678`\n }\n }\n\n protected getErrorTemplates() {\n return [\n {\n type: 'pattern',\n template:\n 'Enter a valid National Grid field number for [short description] like NG 1234 5678'\n }\n ]\n }\n\n /**\n * Static version of getAllPossibleErrors that doesn't require a component instance.\n */\n static getAllPossibleErrors() {\n const instance = Object.create(\n NationalGridFieldNumberField.prototype\n ) as NationalGridFieldNumberField\n return instance.getAllPossibleErrors()\n }\n}\n"],"mappings":"AACA,OAAOA,UAAU,MAAM,sBAAsB;AAE7C,SAASC,iBAAiB;AAE1B,OAAO,MAAMC,4BAA4B,SAASD,iBAAiB,CAAC;EAGxDE,mBAAmBA,CAAA,EAAG;IAC9B;IACA;IACA;IACA,MAAMC,OAAO,GACX,mIAAmI;IAErI,OAAO;MACLA,OAAO;MACPC,mBAAmB,EAAE,gDAAgDL,UAAU,CAAC,IAAI,CAACM,KAAK,CAAC;IAC7F,CAAC;EACH;EAEUC,iBAAiBA,CAAA,EAAG;IAC5B,OAAO,CACL;MACEC,IAAI,EAAE,SAAS;MACfC,QAAQ,EACN;IACJ,CAAC,CACF;EACH;;EAEA;AACF;AACA;EACE,OAAOC,oBAAoBA,CAAA,EAAG;IAC5B,MAAMC,QAAQ,GAAGC,MAAM,CAACC,MAAM,CAC5BX,4BAA4B,CAACY,SAC/B,CAAiC;IACjC,OAAOH,QAAQ,CAACD,oBAAoB,CAAC,CAAC;EACxC;AACF","ignoreList":[]}
@@ -1,13 +1,17 @@
1
+ import lowerFirst from 'lodash/lowerFirst.js';
1
2
  import { LocationFieldBase } from "./LocationFieldBase.js";
2
3
  export class OsGridRefField extends LocationFieldBase {
3
4
  getValidationConfig() {
4
- // Regex for OS grid references and parcel IDs
5
+ // Regex for OS national grid references (NGR)
5
6
  // Validates specific valid OS grid letter combinations with:
6
- // - 2 letters & 6 digits (e.g., SD865005 or SD 865 005)
7
- const pattern = /^((([sS]|[nN])[a-hA-Hj-zJ-Z])|(([tT]|[oO])[abfglmqrvwABFGLMQRVW])|([hH][l-zL-Z])|([jJ][lmqrvwLMQRVW]))\s?(([0-9]{3})\s?([0-9]{3}))$/;
7
+ // - 2 letters & 6 digits in 2 blocks of 3 e.g. ST 678 678
8
+ // - 2 letters & 8 digits in 2 blocks of 4 e.g. ST 6789 6789
9
+ // - 2 letters & 10 digits in 2 blocks of 5 e.g. SO 12345 12345
10
+ // Optional spaces between each block
11
+ const pattern = /^((([sS]|[nN])[a-hA-Hj-zJ-Z])|(([tT]|[oO])[abfglmqrvwABFGLMQRVW])|([hH][l-zL-Z])|([jJ][lmqrvwLMQRVW]))\s?(([0-9]{3})\s?([0-9]{3})|([0-9]{4})\s?([0-9]{4})|([0-9]{5})\s?([0-9]{5}))$/;
8
12
  return {
9
13
  pattern,
10
- patternErrorMessage: `Enter a valid OS grid reference for ${this.title} like TQ123456`
14
+ patternErrorMessage: `Enter a valid OS grid reference for ${lowerFirst(this.label)} like TQ123456`
11
15
  };
12
16
  }
13
17
  getErrorTemplates() {
@@ -1 +1 @@
1
- {"version":3,"file":"OsGridRefField.js","names":["LocationFieldBase","OsGridRefField","getValidationConfig","pattern","patternErrorMessage","title","getErrorTemplates","type","template","getAllPossibleErrors","instance","Object","create","prototype"],"sources":["../../../../../src/server/plugins/engine/components/OsGridRefField.ts"],"sourcesContent":["import { type OsGridRefFieldComponent } from '@defra/forms-model'\n\nimport { LocationFieldBase } from '~/src/server/plugins/engine/components/LocationFieldBase.js'\n\nexport class OsGridRefField extends LocationFieldBase {\n declare options: OsGridRefFieldComponent['options']\n\n protected getValidationConfig() {\n // Regex for OS grid references and parcel IDs\n // Validates specific valid OS grid letter combinations with:\n // - 2 letters & 6 digits (e.g., SD865005 or SD 865 005)\n const pattern =\n /^((([sS]|[nN])[a-hA-Hj-zJ-Z])|(([tT]|[oO])[abfglmqrvwABFGLMQRVW])|([hH][l-zL-Z])|([jJ][lmqrvwLMQRVW]))\\s?(([0-9]{3})\\s?([0-9]{3}))$/\n\n return {\n pattern,\n patternErrorMessage: `Enter a valid OS grid reference for ${this.title} like TQ123456`\n }\n }\n\n protected getErrorTemplates() {\n return [\n {\n type: 'pattern',\n template:\n 'Enter a valid OS grid reference for [short description] like TQ123456'\n }\n ]\n }\n\n /**\n * Static version of getAllPossibleErrors that doesn't require a component instance.\n */\n static getAllPossibleErrors() {\n const instance = Object.create(OsGridRefField.prototype) as OsGridRefField\n return instance.getAllPossibleErrors()\n }\n}\n"],"mappings":"AAEA,SAASA,iBAAiB;AAE1B,OAAO,MAAMC,cAAc,SAASD,iBAAiB,CAAC;EAG1CE,mBAAmBA,CAAA,EAAG;IAC9B;IACA;IACA;IACA,MAAMC,OAAO,GACX,qIAAqI;IAEvI,OAAO;MACLA,OAAO;MACPC,mBAAmB,EAAE,uCAAuC,IAAI,CAACC,KAAK;IACxE,CAAC;EACH;EAEUC,iBAAiBA,CAAA,EAAG;IAC5B,OAAO,CACL;MACEC,IAAI,EAAE,SAAS;MACfC,QAAQ,EACN;IACJ,CAAC,CACF;EACH;;EAEA;AACF;AACA;EACE,OAAOC,oBAAoBA,CAAA,EAAG;IAC5B,MAAMC,QAAQ,GAAGC,MAAM,CAACC,MAAM,CAACX,cAAc,CAACY,SAAS,CAAmB;IAC1E,OAAOH,QAAQ,CAACD,oBAAoB,CAAC,CAAC;EACxC;AACF","ignoreList":[]}
1
+ {"version":3,"file":"OsGridRefField.js","names":["lowerFirst","LocationFieldBase","OsGridRefField","getValidationConfig","pattern","patternErrorMessage","label","getErrorTemplates","type","template","getAllPossibleErrors","instance","Object","create","prototype"],"sources":["../../../../../src/server/plugins/engine/components/OsGridRefField.ts"],"sourcesContent":["import { type OsGridRefFieldComponent } from '@defra/forms-model'\nimport lowerFirst from 'lodash/lowerFirst.js'\n\nimport { LocationFieldBase } from '~/src/server/plugins/engine/components/LocationFieldBase.js'\n\nexport class OsGridRefField extends LocationFieldBase {\n declare options: OsGridRefFieldComponent['options']\n\n protected getValidationConfig() {\n // Regex for OS national grid references (NGR)\n // Validates specific valid OS grid letter combinations with:\n // - 2 letters & 6 digits in 2 blocks of 3 e.g. ST 678 678\n // - 2 letters & 8 digits in 2 blocks of 4 e.g. ST 6789 6789\n // - 2 letters & 10 digits in 2 blocks of 5 e.g. SO 12345 12345\n // Optional spaces between each block\n const pattern =\n /^((([sS]|[nN])[a-hA-Hj-zJ-Z])|(([tT]|[oO])[abfglmqrvwABFGLMQRVW])|([hH][l-zL-Z])|([jJ][lmqrvwLMQRVW]))\\s?(([0-9]{3})\\s?([0-9]{3})|([0-9]{4})\\s?([0-9]{4})|([0-9]{5})\\s?([0-9]{5}))$/\n\n return {\n pattern,\n patternErrorMessage: `Enter a valid OS grid reference for ${lowerFirst(this.label)} like TQ123456`\n }\n }\n\n protected getErrorTemplates() {\n return [\n {\n type: 'pattern',\n template:\n 'Enter a valid OS grid reference for [short description] like TQ123456'\n }\n ]\n }\n\n /**\n * Static version of getAllPossibleErrors that doesn't require a component instance.\n */\n static getAllPossibleErrors() {\n const instance = Object.create(OsGridRefField.prototype) as OsGridRefField\n return instance.getAllPossibleErrors()\n }\n}\n"],"mappings":"AACA,OAAOA,UAAU,MAAM,sBAAsB;AAE7C,SAASC,iBAAiB;AAE1B,OAAO,MAAMC,cAAc,SAASD,iBAAiB,CAAC;EAG1CE,mBAAmBA,CAAA,EAAG;IAC9B;IACA;IACA;IACA;IACA;IACA;IACA,MAAMC,OAAO,GACX,qLAAqL;IAEvL,OAAO;MACLA,OAAO;MACPC,mBAAmB,EAAE,uCAAuCL,UAAU,CAAC,IAAI,CAACM,KAAK,CAAC;IACpF,CAAC;EACH;EAEUC,iBAAiBA,CAAA,EAAG;IAC5B,OAAO,CACL;MACEC,IAAI,EAAE,SAAS;MACfC,QAAQ,EACN;IACJ,CAAC,CACF;EACH;;EAEA;AACF;AACA;EACE,OAAOC,oBAAoBA,CAAA,EAAG;IAC5B,MAAMC,QAAQ,GAAGC,MAAM,CAACC,MAAM,CAACX,cAAc,CAACY,SAAS,CAAmB;IAC1E,OAAOH,QAAQ,CAACD,oBAAoB,CAAC,CAAC;EACxC;AACF","ignoreList":[]}
@@ -47,6 +47,9 @@ export interface DateInputItem {
47
47
  classes?: string;
48
48
  prefix?: ComponentText;
49
49
  suffix?: ComponentText;
50
+ errorMessage?: {
51
+ text: string;
52
+ };
50
53
  condition?: undefined;
51
54
  }
52
55
  export interface ViewModel extends Record<string, unknown> {
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","names":[],"sources":["../../../../../src/server/plugins/engine/components/types.ts"],"sourcesContent":["import { type ComponentType, type Item } from '@defra/forms-model'\n\nimport {\n type FormSubmissionError,\n type FormValue,\n type SummaryList\n} from '~/src/server/plugins/engine/types.js'\n\nexport type ComponentText = {\n classes?: string\n attributes?: string | Record<string, string>\n} & (\n | {\n text: string\n html?: string\n }\n | {\n text?: string\n html: string\n }\n)\n\nexport interface Label {\n text: string\n classes?: string\n html?: string\n isPageHeading?: boolean\n}\n\nexport interface Content {\n title?: string\n text: string\n condition?: string\n}\n\nexport interface BackLink {\n text: string\n href: string\n}\n\nexport type ListItemLabel = Omit<Label, 'text' | 'isPageHeading'>\n\nexport interface ListItem {\n text?: string\n value?: Item['value']\n hint?: {\n id?: string\n text: string\n }\n checked?: boolean\n selected?: boolean\n label?: ListItemLabel\n condition?: string\n}\n\nexport interface DateInputItem {\n label?: Label\n type?: string\n id?: string\n name?: string\n value?: Item['value']\n classes?: string\n // Prefix/suffix are used by location fields (e.g., LatLong, EastingNorthing) for units like \"°\"\n // but not by date fields. This interface is reused by both component types.\n prefix?: ComponentText\n suffix?: ComponentText\n condition?: undefined\n}\n\nexport interface ViewModel extends Record<string, unknown> {\n label?: Label\n type?: string\n id?: string\n name?: string\n value?: FormValue\n hint?: {\n id?: string\n text: string\n }\n prefix?: ComponentText\n suffix?: ComponentText\n classes?: string\n condition?: string\n errors?: FormSubmissionError[]\n errorMessage?: {\n text: string\n }\n summaryHtml?: string\n html?: string\n attributes: {\n autocomplete?: string\n maxlength?: number\n multiple?: string\n accept?: string\n inputmode?: string\n }\n content?: Content | Content[] | string\n maxlength?: number\n maxwords?: number\n rows?: number\n items?: ListItem[] | DateInputItem[]\n fieldset?: {\n attributes?: string | Record<string, string>\n legend?: Label\n }\n formGroup?: {\n classes?: string\n attributes?: string | Record<string, string>\n }\n components?: ComponentViewModel[]\n upload?: {\n count: number\n summaryList: SummaryList\n }\n}\n\nexport interface ComponentViewModel {\n type: ComponentType\n isFormComponent: boolean\n model: ViewModel\n}\n\nexport interface DatePartsState extends Record<string, number> {\n day: number\n month: number\n year: number\n}\n\nexport interface MonthYearState extends Record<string, number> {\n month: number\n year: number\n}\n\nexport interface EastingNorthingState extends Record<string, number> {\n easting: number\n northing: number\n}\n\nexport interface LatLongState extends Record<string, number> {\n latitude: number\n longitude: number\n}\n"],"mappings":"","ignoreList":[]}
1
+ {"version":3,"file":"types.js","names":[],"sources":["../../../../../src/server/plugins/engine/components/types.ts"],"sourcesContent":["import { type ComponentType, type Item } from '@defra/forms-model'\n\nimport {\n type FormSubmissionError,\n type FormValue,\n type SummaryList\n} from '~/src/server/plugins/engine/types.js'\n\nexport type ComponentText = {\n classes?: string\n attributes?: string | Record<string, string>\n} & (\n | {\n text: string\n html?: string\n }\n | {\n text?: string\n html: string\n }\n)\n\nexport interface Label {\n text: string\n classes?: string\n html?: string\n isPageHeading?: boolean\n}\n\nexport interface Content {\n title?: string\n text: string\n condition?: string\n}\n\nexport interface BackLink {\n text: string\n href: string\n}\n\nexport type ListItemLabel = Omit<Label, 'text' | 'isPageHeading'>\n\nexport interface ListItem {\n text?: string\n value?: Item['value']\n hint?: {\n id?: string\n text: string\n }\n checked?: boolean\n selected?: boolean\n label?: ListItemLabel\n condition?: string\n}\n\nexport interface DateInputItem {\n label?: Label\n type?: string\n id?: string\n name?: string\n value?: Item['value']\n classes?: string\n // Prefix/suffix are used by location fields (e.g., LatLong, EastingNorthing) for units like \"°\"\n // but not by date fields. This interface is reused by both component types.\n prefix?: ComponentText\n suffix?: ComponentText\n errorMessage?: {\n text: string\n }\n condition?: undefined\n}\n\nexport interface ViewModel extends Record<string, unknown> {\n label?: Label\n type?: string\n id?: string\n name?: string\n value?: FormValue\n hint?: {\n id?: string\n text: string\n }\n prefix?: ComponentText\n suffix?: ComponentText\n classes?: string\n condition?: string\n errors?: FormSubmissionError[]\n errorMessage?: {\n text: string\n }\n summaryHtml?: string\n html?: string\n attributes: {\n autocomplete?: string\n maxlength?: number\n multiple?: string\n accept?: string\n inputmode?: string\n }\n content?: Content | Content[] | string\n maxlength?: number\n maxwords?: number\n rows?: number\n items?: ListItem[] | DateInputItem[]\n fieldset?: {\n attributes?: string | Record<string, string>\n legend?: Label\n }\n formGroup?: {\n classes?: string\n attributes?: string | Record<string, string>\n }\n components?: ComponentViewModel[]\n upload?: {\n count: number\n summaryList: SummaryList\n }\n}\n\nexport interface ComponentViewModel {\n type: ComponentType\n isFormComponent: boolean\n model: ViewModel\n}\n\nexport interface DatePartsState extends Record<string, number> {\n day: number\n month: number\n year: number\n}\n\nexport interface MonthYearState extends Record<string, number> {\n month: number\n year: number\n}\n\nexport interface EastingNorthingState extends Record<string, number> {\n easting: number\n northing: number\n}\n\nexport interface LatLongState extends Record<string, number> {\n latitude: number\n longitude: number\n}\n"],"mappings":"","ignoreList":[]}
@@ -1,5 +1,5 @@
1
1
  import { SchemaVersion, type ComponentDef, type ConditionWrapper, type ConditionWrapperV2, type ConditionsModelData, type Engine, type FormDefinition, type List, type Page } from '@defra/forms-model';
2
- import { Parser, type Value } from 'expr-eval';
2
+ import { Parser, type Value } from 'expr-eval-fork';
3
3
  import joi from 'joi';
4
4
  import { type Component } from '~/src/server/plugins/engine/components/helpers/components.js';
5
5
  import { type ExecutableCondition } from '~/src/server/plugins/engine/models/types.js';
@@ -47,7 +47,7 @@ export declare class FormModel {
47
47
  */
48
48
  makeCondition(condition: ConditionWrapper): ExecutableCondition;
49
49
  toConditionContext(evaluationState: FormState, conditions: Partial<Record<string, ExecutableCondition>>): Extract<Value, Record<string, Value>>;
50
- toConditionExpression(value: ConditionsModelData, parser: Parser): import("expr-eval").Expression;
50
+ toConditionExpression(value: ConditionsModelData, parser: Parser): import("expr-eval-fork").Expression;
51
51
  getList(nameOrId: string): List | undefined;
52
52
  /**
53
53
  * Form context for the current page
@@ -1,6 +1,6 @@
1
1
  import { ComponentType, ConditionsModel, ControllerPath, ControllerType, SchemaVersion, convertConditionWrapperFromV2, formDefinitionSchema, formDefinitionV2Schema, generateConditionAlias, hasComponents, hasRepeater, isConditionWrapperV2, yesNoListId, yesNoListName } from '@defra/forms-model';
2
2
  import { add, format } from 'date-fns';
3
- import { Parser } from 'expr-eval';
3
+ import { Parser } from 'expr-eval-fork';
4
4
  import joi from 'joi';
5
5
  import { createLogger } from "../../../common/helpers/logging/logger.js";
6
6
  import "../components/YesNoField.js";