@defra/forms-engine-plugin 4.23.0 → 5.0.0-alpha.1

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 (347) hide show
  1. package/.public/assets-manifest.json +3 -5
  2. package/.public/javascripts/im-core.min.js +2 -0
  3. package/.public/javascripts/im-core.min.js.map +1 -0
  4. package/.public/javascripts/shared.min.js +1 -1
  5. package/.public/javascripts/shared.min.js.map +1 -1
  6. package/.public/javascripts/vendor/@defra.min.js +1 -1
  7. package/.public/javascripts/vendor/@defra.min.js.map +1 -1
  8. package/.public/stylesheets/application.min.css +1 -1
  9. package/.public/stylesheets/application.min.css.map +1 -1
  10. package/.server/client/javascripts/geospatial-map.js +8 -6
  11. package/.server/client/javascripts/geospatial-map.js.map +1 -1
  12. package/.server/client/javascripts/location-map.js +8 -1
  13. package/.server/client/javascripts/location-map.js.map +1 -1
  14. package/.server/client/javascripts/map.d.ts +6 -0
  15. package/.server/client/javascripts/map.js +10 -0
  16. package/.server/client/javascripts/map.js.map +1 -1
  17. package/.server/client/javascripts/sssi-dataset.d.ts +34 -0
  18. package/.server/client/javascripts/sssi-dataset.js +101 -0
  19. package/.server/client/javascripts/sssi-dataset.js.map +1 -0
  20. package/.server/client/stylesheets/shared.scss +0 -2
  21. package/.server/server/forms/register-as-a-unicorn-breeder.yaml +0 -14
  22. package/.server/server/forms/simple-form.yaml +106 -3
  23. package/.server/server/plugins/engine/components/AutocompleteField.d.ts +11 -11
  24. package/.server/server/plugins/engine/components/AutocompleteField.js +2 -2
  25. package/.server/server/plugins/engine/components/AutocompleteField.js.map +1 -1
  26. package/.server/server/plugins/engine/components/CheckboxesField.d.ts +3 -2
  27. package/.server/server/plugins/engine/components/CheckboxesField.js +4 -9
  28. package/.server/server/plugins/engine/components/CheckboxesField.js.map +1 -1
  29. package/.server/server/plugins/engine/components/ComponentCollection.d.ts +8 -7
  30. package/.server/server/plugins/engine/components/ComponentCollection.js +106 -51
  31. package/.server/server/plugins/engine/components/ComponentCollection.js.map +1 -1
  32. package/.server/server/plugins/engine/components/DatePartsField.d.ts +8 -6
  33. package/.server/server/plugins/engine/components/DatePartsField.js +27 -9
  34. package/.server/server/plugins/engine/components/DatePartsField.js.map +1 -1
  35. package/.server/server/plugins/engine/components/DeclarationField.d.ts +13 -11
  36. package/.server/server/plugins/engine/components/DeclarationField.js +31 -9
  37. package/.server/server/plugins/engine/components/DeclarationField.js.map +1 -1
  38. package/.server/server/plugins/engine/components/EastingNorthingField.d.ts +8 -5
  39. package/.server/server/plugins/engine/components/EastingNorthingField.js +42 -22
  40. package/.server/server/plugins/engine/components/EastingNorthingField.js.map +1 -1
  41. package/.server/server/plugins/engine/components/EmailAddressField.d.ts +11 -14
  42. package/.server/server/plugins/engine/components/EmailAddressField.js +2 -2
  43. package/.server/server/plugins/engine/components/EmailAddressField.js.map +1 -1
  44. package/.server/server/plugins/engine/components/FileUploadField.d.ts +14 -12
  45. package/.server/server/plugins/engine/components/FileUploadField.js +22 -12
  46. package/.server/server/plugins/engine/components/FileUploadField.js.map +1 -1
  47. package/.server/server/plugins/engine/components/FormComponent.d.ts +21 -12
  48. package/.server/server/plugins/engine/components/FormComponent.js +33 -14
  49. package/.server/server/plugins/engine/components/FormComponent.js.map +1 -1
  50. package/.server/server/plugins/engine/components/GeospatialField.d.ts +15 -12
  51. package/.server/server/plugins/engine/components/GeospatialField.js +21 -13
  52. package/.server/server/plugins/engine/components/GeospatialField.js.map +1 -1
  53. package/.server/server/plugins/engine/components/LatLongField.d.ts +8 -5
  54. package/.server/server/plugins/engine/components/LatLongField.js +32 -20
  55. package/.server/server/plugins/engine/components/LatLongField.js.map +1 -1
  56. package/.server/server/plugins/engine/components/ListFormComponent.d.ts +7 -6
  57. package/.server/server/plugins/engine/components/ListFormComponent.js +19 -7
  58. package/.server/server/plugins/engine/components/ListFormComponent.js.map +1 -1
  59. package/.server/server/plugins/engine/components/LocationFieldBase.d.ts +17 -16
  60. package/.server/server/plugins/engine/components/LocationFieldBase.js +2 -2
  61. package/.server/server/plugins/engine/components/LocationFieldBase.js.map +1 -1
  62. package/.server/server/plugins/engine/components/LocationFieldHelpers.d.ts +8 -3
  63. package/.server/server/plugins/engine/components/LocationFieldHelpers.js +14 -3
  64. package/.server/server/plugins/engine/components/LocationFieldHelpers.js.map +1 -1
  65. package/.server/server/plugins/engine/components/Markdown.d.ts +8 -7
  66. package/.server/server/plugins/engine/components/Markdown.js +5 -2
  67. package/.server/server/plugins/engine/components/Markdown.js.map +1 -1
  68. package/.server/server/plugins/engine/components/MonthYearField.d.ts +9 -7
  69. package/.server/server/plugins/engine/components/MonthYearField.js +26 -8
  70. package/.server/server/plugins/engine/components/MonthYearField.js.map +1 -1
  71. package/.server/server/plugins/engine/components/MultilineTextField.d.ts +10 -9
  72. package/.server/server/plugins/engine/components/MultilineTextField.js +2 -2
  73. package/.server/server/plugins/engine/components/MultilineTextField.js.map +1 -1
  74. package/.server/server/plugins/engine/components/NationalGridFieldNumberField.d.ts +2 -1
  75. package/.server/server/plugins/engine/components/NationalGridFieldNumberField.js +14 -6
  76. package/.server/server/plugins/engine/components/NationalGridFieldNumberField.js.map +1 -1
  77. package/.server/server/plugins/engine/components/NumberField.d.ts +10 -9
  78. package/.server/server/plugins/engine/components/NumberField.js +2 -2
  79. package/.server/server/plugins/engine/components/NumberField.js.map +1 -1
  80. package/.server/server/plugins/engine/components/OsGridRefField.d.ts +2 -1
  81. package/.server/server/plugins/engine/components/OsGridRefField.js +14 -6
  82. package/.server/server/plugins/engine/components/OsGridRefField.js.map +1 -1
  83. package/.server/server/plugins/engine/components/PaymentField.d.ts +12 -10
  84. package/.server/server/plugins/engine/components/PaymentField.js +21 -8
  85. package/.server/server/plugins/engine/components/PaymentField.js.map +1 -1
  86. package/.server/server/plugins/engine/components/SelectField.d.ts +11 -11
  87. package/.server/server/plugins/engine/components/SelectField.js +2 -2
  88. package/.server/server/plugins/engine/components/SelectField.js.map +1 -1
  89. package/.server/server/plugins/engine/components/SelectionControlField.d.ts +4 -4
  90. package/.server/server/plugins/engine/components/SelectionControlField.js +2 -2
  91. package/.server/server/plugins/engine/components/SelectionControlField.js.map +1 -1
  92. package/.server/server/plugins/engine/components/TelephoneNumberField.d.ts +10 -9
  93. package/.server/server/plugins/engine/components/TelephoneNumberField.js +2 -2
  94. package/.server/server/plugins/engine/components/TelephoneNumberField.js.map +1 -1
  95. package/.server/server/plugins/engine/components/UkAddressField.d.ts +12 -10
  96. package/.server/server/plugins/engine/components/UkAddressField.js +29 -17
  97. package/.server/server/plugins/engine/components/UkAddressField.js.map +1 -1
  98. package/.server/server/plugins/engine/components/YesNoField.d.ts +3 -0
  99. package/.server/server/plugins/engine/components/YesNoField.js +9 -0
  100. package/.server/server/plugins/engine/components/YesNoField.js.map +1 -1
  101. package/.server/server/plugins/engine/components/helpers/components.d.ts +3 -2
  102. package/.server/server/plugins/engine/components/helpers/components.js +11 -8
  103. package/.server/server/plugins/engine/components/helpers/components.js.map +1 -1
  104. package/.server/server/plugins/engine/components/types.d.ts +8 -1
  105. package/.server/server/plugins/engine/components/types.js.map +1 -1
  106. package/.server/server/plugins/engine/configureEnginePlugin.js +8 -1
  107. package/.server/server/plugins/engine/configureEnginePlugin.js.map +1 -1
  108. package/.server/server/plugins/engine/form-context.d.ts +1 -0
  109. package/.server/server/plugins/engine/form-context.js +4 -2
  110. package/.server/server/plugins/engine/form-context.js.map +1 -1
  111. package/.server/server/plugins/engine/helpers.d.ts +1 -1
  112. package/.server/server/plugins/engine/helpers.js +8 -13
  113. package/.server/server/plugins/engine/helpers.js.map +1 -1
  114. package/.server/server/plugins/engine/i18n/buildValidationMessages.d.ts +39 -0
  115. package/.server/server/plugins/engine/i18n/buildValidationMessages.js +50 -0
  116. package/.server/server/plugins/engine/i18n/buildValidationMessages.js.map +1 -0
  117. package/.server/server/plugins/engine/i18n/createFormTranslator.d.ts +5 -0
  118. package/.server/server/plugins/engine/i18n/createFormTranslator.js +18 -0
  119. package/.server/server/plugins/engine/i18n/createFormTranslator.js.map +1 -0
  120. package/.server/server/plugins/engine/i18n/createTranslator.d.ts +9 -0
  121. package/.server/server/plugins/engine/i18n/createTranslator.js +51 -0
  122. package/.server/server/plugins/engine/i18n/createTranslator.js.map +1 -0
  123. package/.server/server/plugins/engine/i18n/extractBaseTranslations.d.ts +5 -0
  124. package/.server/server/plugins/engine/i18n/extractBaseTranslations.js +57 -0
  125. package/.server/server/plugins/engine/i18n/extractBaseTranslations.js.map +1 -0
  126. package/.server/server/plugins/engine/i18n/index.d.ts +18 -0
  127. package/.server/server/plugins/engine/i18n/index.js +71 -0
  128. package/.server/server/plugins/engine/i18n/index.js.map +1 -0
  129. package/.server/server/plugins/engine/i18n/translations/cy.json +271 -0
  130. package/.server/server/plugins/engine/i18n/translations/en-GB.json +271 -0
  131. package/.server/server/plugins/engine/i18n/types.d.ts +41 -0
  132. package/.server/server/plugins/engine/i18n/types.js +2 -0
  133. package/.server/server/plugins/engine/i18n/types.js.map +1 -0
  134. package/.server/server/plugins/engine/index.js +3 -2
  135. package/.server/server/plugins/engine/index.js.map +1 -1
  136. package/.server/server/plugins/engine/models/FormModel.d.ts +9 -1
  137. package/.server/server/plugins/engine/models/FormModel.js +44 -18
  138. package/.server/server/plugins/engine/models/FormModel.js.map +1 -1
  139. package/.server/server/plugins/engine/models/SummaryViewModel.d.ts +5 -2
  140. package/.server/server/plugins/engine/models/SummaryViewModel.js +44 -18
  141. package/.server/server/plugins/engine/models/SummaryViewModel.js.map +1 -1
  142. package/.server/server/plugins/engine/options.js +2 -1
  143. package/.server/server/plugins/engine/options.js.map +1 -1
  144. package/.server/server/plugins/engine/outputFormatters/adapter/v1.js +4 -0
  145. package/.server/server/plugins/engine/outputFormatters/adapter/v1.js.map +1 -1
  146. package/.server/server/plugins/engine/outputFormatters/human/v1.js +2 -1
  147. package/.server/server/plugins/engine/outputFormatters/human/v1.js.map +1 -1
  148. package/.server/server/plugins/engine/outputFormatters/machine/v1.js +7 -6
  149. package/.server/server/plugins/engine/outputFormatters/machine/v1.js.map +1 -1
  150. package/.server/server/plugins/engine/pageControllers/FileUploadPageController.d.ts +2 -1
  151. package/.server/server/plugins/engine/pageControllers/FileUploadPageController.js +6 -3
  152. package/.server/server/plugins/engine/pageControllers/FileUploadPageController.js.map +1 -1
  153. package/.server/server/plugins/engine/pageControllers/PageController.d.ts +3 -1
  154. package/.server/server/plugins/engine/pageControllers/PageController.js +11 -1
  155. package/.server/server/plugins/engine/pageControllers/PageController.js.map +1 -1
  156. package/.server/server/plugins/engine/pageControllers/QuestionPageController.d.ts +4 -2
  157. package/.server/server/plugins/engine/pageControllers/QuestionPageController.js +52 -21
  158. package/.server/server/plugins/engine/pageControllers/QuestionPageController.js.map +1 -1
  159. package/.server/server/plugins/engine/pageControllers/RepeatPageController.d.ts +3 -2
  160. package/.server/server/plugins/engine/pageControllers/RepeatPageController.js +63 -26
  161. package/.server/server/plugins/engine/pageControllers/RepeatPageController.js.map +1 -1
  162. package/.server/server/plugins/engine/pageControllers/StartPageController.d.ts +3 -1
  163. package/.server/server/plugins/engine/pageControllers/StartPageController.js +2 -2
  164. package/.server/server/plugins/engine/pageControllers/StartPageController.js.map +1 -1
  165. package/.server/server/plugins/engine/pageControllers/StatusPageController.js +12 -2
  166. package/.server/server/plugins/engine/pageControllers/StatusPageController.js.map +1 -1
  167. package/.server/server/plugins/engine/pageControllers/SummaryPageController.d.ts +4 -3
  168. package/.server/server/plugins/engine/pageControllers/SummaryPageController.js +44 -28
  169. package/.server/server/plugins/engine/pageControllers/SummaryPageController.js.map +1 -1
  170. package/.server/server/plugins/engine/pageControllers/__stubs__/translator.d.ts +2 -0
  171. package/.server/server/plugins/engine/pageControllers/__stubs__/translator.js +24 -0
  172. package/.server/server/plugins/engine/pageControllers/__stubs__/translator.js.map +1 -0
  173. package/.server/server/plugins/engine/pageControllers/errors.d.ts +1 -1
  174. package/.server/server/plugins/engine/pageControllers/errors.js +3 -2
  175. package/.server/server/plugins/engine/pageControllers/errors.js.map +1 -1
  176. package/.server/server/plugins/engine/pageControllers/helpers/submission.d.ts +3 -2
  177. package/.server/server/plugins/engine/pageControllers/helpers/submission.js +4 -4
  178. package/.server/server/plugins/engine/pageControllers/helpers/submission.js.map +1 -1
  179. package/.server/server/plugins/engine/pageControllers/validationOptions.d.ts +7 -3
  180. package/.server/server/plugins/engine/pageControllers/validationOptions.js +34 -33
  181. package/.server/server/plugins/engine/pageControllers/validationOptions.js.map +1 -1
  182. package/.server/server/plugins/engine/plugin.js +2 -0
  183. package/.server/server/plugins/engine/plugin.js.map +1 -1
  184. package/.server/server/plugins/engine/routes/index.js +4 -1
  185. package/.server/server/plugins/engine/routes/index.js.map +1 -1
  186. package/.server/server/plugins/engine/routes/questions.js +5 -2
  187. package/.server/server/plugins/engine/routes/questions.js.map +1 -1
  188. package/.server/server/plugins/engine/types/index.d.ts +1 -0
  189. package/.server/server/plugins/engine/types/index.js.map +1 -1
  190. package/.server/server/plugins/engine/types/schema.js +1 -0
  191. package/.server/server/plugins/engine/types/schema.js.map +1 -1
  192. package/.server/server/plugins/engine/types.d.ts +12 -1
  193. package/.server/server/plugins/engine/types.js.map +1 -1
  194. package/.server/server/plugins/engine/views/components/_location-field-base.html +4 -2
  195. package/.server/server/plugins/engine/views/components/fileuploadfield.html +3 -3
  196. package/.server/server/plugins/engine/views/components/geospatialfield.html +4 -1
  197. package/.server/server/plugins/engine/views/components/nationalgridfieldnumberfield.html +1 -1
  198. package/.server/server/plugins/engine/views/components/osgridreffield.html +1 -1
  199. package/.server/server/plugins/engine/views/components/paymentfield.html +8 -8
  200. package/.server/server/plugins/engine/views/components/ukaddressfield.html +4 -4
  201. package/.server/server/plugins/engine/views/confirmation.html +4 -4
  202. package/.server/server/plugins/engine/views/exit.html +4 -4
  203. package/.server/server/plugins/engine/views/file-upload.html +3 -3
  204. package/.server/server/plugins/engine/views/index.html +3 -3
  205. package/.server/server/plugins/engine/views/item-delete.html +1 -1
  206. package/.server/server/plugins/engine/views/partials/form.html +3 -3
  207. package/.server/server/plugins/engine/views/partials/preview-banner.html +4 -4
  208. package/.server/server/plugins/engine/views/partials/warn-missing-notification-email.html +4 -5
  209. package/.server/server/plugins/engine/views/repeat-list-summary.html +4 -4
  210. package/.server/server/plugins/engine/views/summary.html +14 -7
  211. package/.server/server/plugins/map/routes/index.js +1 -1
  212. package/.server/server/plugins/map/routes/index.js.map +1 -1
  213. package/.server/server/plugins/map/types.d.ts +1 -25
  214. package/.server/server/plugins/map/types.js +1 -16
  215. package/.server/server/plugins/map/types.js.map +1 -1
  216. package/.server/server/plugins/nunjucks/enviroment.test.js +10 -0
  217. package/.server/server/plugins/nunjucks/enviroment.test.js.map +1 -1
  218. package/.server/server/plugins/nunjucks/environment.d.ts +8 -0
  219. package/.server/server/plugins/nunjucks/environment.js +13 -0
  220. package/.server/server/plugins/nunjucks/environment.js.map +1 -1
  221. package/.server/server/plugins/nunjucks/filters/answer.js +9 -1
  222. package/.server/server/plugins/nunjucks/filters/answer.js.map +1 -1
  223. package/.server/server/plugins/nunjucks/filters/answer.test.js +13 -2
  224. package/.server/server/plugins/nunjucks/filters/answer.test.js.map +1 -1
  225. package/.server/server/plugins/nunjucks/filters/field.d.ts +1 -1
  226. package/.server/server/plugins/postcode-lookup/models/index.d.ts +24 -19
  227. package/.server/server/plugins/postcode-lookup/models/index.js +83 -76
  228. package/.server/server/plugins/postcode-lookup/models/index.js.map +1 -1
  229. package/.server/server/plugins/postcode-lookup/routes/index.js +7 -13
  230. package/.server/server/plugins/postcode-lookup/routes/index.js.map +1 -1
  231. package/.server/server/plugins/postcode-lookup/types.d.ts +1 -0
  232. package/.server/server/plugins/postcode-lookup/types.js +1 -0
  233. package/.server/server/plugins/postcode-lookup/types.js.map +1 -1
  234. package/.server/server/plugins/postcode-lookup/views/postcode-lookup-details.html +3 -3
  235. package/.server/server/types.d.ts +2 -1
  236. package/.server/server/types.js.map +1 -1
  237. package/.server/server/utils/utils.d.ts +5 -0
  238. package/.server/server/utils/utils.js +16 -0
  239. package/.server/server/utils/utils.js.map +1 -1
  240. package/.server/typings/hapi/index.d.js.map +1 -1
  241. package/package.json +5 -4
  242. package/src/client/javascripts/geospatial-map.js +10 -6
  243. package/src/client/javascripts/location-map.js +11 -0
  244. package/src/client/javascripts/map.js +10 -0
  245. package/src/client/javascripts/sssi-dataset.js +106 -0
  246. package/src/client/stylesheets/shared.scss +0 -2
  247. package/src/server/forms/register-as-a-unicorn-breeder.yaml +0 -14
  248. package/src/server/forms/simple-form.yaml +106 -3
  249. package/src/server/plugins/engine/components/AutocompleteField.ts +3 -6
  250. package/src/server/plugins/engine/components/CheckboxesField.ts +12 -11
  251. package/src/server/plugins/engine/components/ComponentCollection.ts +143 -61
  252. package/src/server/plugins/engine/components/DatePartsField.ts +33 -11
  253. package/src/server/plugins/engine/components/DeclarationField.ts +37 -14
  254. package/src/server/plugins/engine/components/EastingNorthingField.ts +83 -22
  255. package/src/server/plugins/engine/components/EmailAddressField.ts +4 -7
  256. package/src/server/plugins/engine/components/FileUploadField.ts +28 -22
  257. package/src/server/plugins/engine/components/FormComponent.ts +49 -12
  258. package/src/server/plugins/engine/components/GeospatialField.ts +38 -21
  259. package/src/server/plugins/engine/components/LatLongField.ts +52 -21
  260. package/src/server/plugins/engine/components/ListFormComponent.ts +26 -10
  261. package/src/server/plugins/engine/components/LocationFieldBase.ts +5 -8
  262. package/src/server/plugins/engine/components/LocationFieldHelpers.ts +24 -4
  263. package/src/server/plugins/engine/components/Markdown.ts +7 -3
  264. package/src/server/plugins/engine/components/MonthYearField.ts +32 -10
  265. package/src/server/plugins/engine/components/MultilineTextField.ts +5 -8
  266. package/src/server/plugins/engine/components/NationalGridFieldNumberField.ts +25 -11
  267. package/src/server/plugins/engine/components/NumberField.ts +3 -4
  268. package/src/server/plugins/engine/components/OsGridRefField.ts +25 -9
  269. package/src/server/plugins/engine/components/PaymentField.ts +22 -12
  270. package/src/server/plugins/engine/components/SelectField.ts +3 -6
  271. package/src/server/plugins/engine/components/SelectionControlField.ts +7 -8
  272. package/src/server/plugins/engine/components/TelephoneNumberField.ts +4 -7
  273. package/src/server/plugins/engine/components/UkAddressField.ts +33 -18
  274. package/src/server/plugins/engine/components/YesNoField.ts +10 -0
  275. package/src/server/plugins/engine/components/helpers/components.ts +13 -6
  276. package/src/server/plugins/engine/components/types.ts +9 -0
  277. package/src/server/plugins/engine/configureEnginePlugin.ts +12 -1
  278. package/src/server/plugins/engine/form-context.ts +8 -2
  279. package/src/server/plugins/engine/helpers.ts +10 -18
  280. package/src/server/plugins/engine/i18n/buildValidationMessages.ts +69 -0
  281. package/src/server/plugins/engine/i18n/createFormTranslator.ts +33 -0
  282. package/src/server/plugins/engine/i18n/createTranslator.ts +61 -0
  283. package/src/server/plugins/engine/i18n/extractBaseTranslations.ts +61 -0
  284. package/src/server/plugins/engine/i18n/index.ts +80 -0
  285. package/src/server/plugins/engine/i18n/translations/cy.json +271 -0
  286. package/src/server/plugins/engine/i18n/translations/en-GB.json +271 -0
  287. package/src/server/plugins/engine/i18n/types.ts +62 -0
  288. package/src/server/plugins/engine/index.ts +4 -2
  289. package/src/server/plugins/engine/models/FormModel.ts +59 -23
  290. package/src/server/plugins/engine/models/SummaryViewModel.ts +68 -25
  291. package/src/server/plugins/engine/options.js +2 -1
  292. package/src/server/plugins/engine/outputFormatters/adapter/v1.ts +5 -0
  293. package/src/server/plugins/engine/outputFormatters/human/v1.ts +2 -3
  294. package/src/server/plugins/engine/outputFormatters/machine/v1.ts +9 -8
  295. package/src/server/plugins/engine/pageControllers/FileUploadPageController.ts +7 -3
  296. package/src/server/plugins/engine/pageControllers/PageController.ts +12 -1
  297. package/src/server/plugins/engine/pageControllers/QuestionPageController.ts +53 -21
  298. package/src/server/plugins/engine/pageControllers/RepeatPageController.ts +66 -29
  299. package/src/server/plugins/engine/pageControllers/StartPageController.ts +7 -2
  300. package/src/server/plugins/engine/pageControllers/StatusPageController.ts +10 -2
  301. package/src/server/plugins/engine/pageControllers/SummaryPageController.ts +48 -22
  302. package/src/server/plugins/engine/pageControllers/__stubs__/translator.ts +28 -0
  303. package/src/server/plugins/engine/pageControllers/errors.ts +4 -2
  304. package/src/server/plugins/engine/pageControllers/helpers/submission.ts +11 -4
  305. package/src/server/plugins/engine/pageControllers/validationOptions.ts +43 -53
  306. package/src/server/plugins/engine/plugin.ts +2 -0
  307. package/src/server/plugins/engine/routes/index.ts +9 -1
  308. package/src/server/plugins/engine/routes/questions.ts +5 -1
  309. package/src/server/plugins/engine/types/index.ts +5 -0
  310. package/src/server/plugins/engine/types/schema.ts +1 -0
  311. package/src/server/plugins/engine/types.ts +10 -0
  312. package/src/server/plugins/engine/views/components/_location-field-base.html +4 -2
  313. package/src/server/plugins/engine/views/components/fileuploadfield.html +3 -3
  314. package/src/server/plugins/engine/views/components/geospatialfield.html +4 -1
  315. package/src/server/plugins/engine/views/components/nationalgridfieldnumberfield.html +1 -1
  316. package/src/server/plugins/engine/views/components/osgridreffield.html +1 -1
  317. package/src/server/plugins/engine/views/components/paymentfield.html +8 -8
  318. package/src/server/plugins/engine/views/components/ukaddressfield.html +4 -4
  319. package/src/server/plugins/engine/views/confirmation.html +4 -4
  320. package/src/server/plugins/engine/views/exit.html +4 -4
  321. package/src/server/plugins/engine/views/file-upload.html +3 -3
  322. package/src/server/plugins/engine/views/index.html +3 -3
  323. package/src/server/plugins/engine/views/item-delete.html +1 -1
  324. package/src/server/plugins/engine/views/partials/form.html +3 -3
  325. package/src/server/plugins/engine/views/partials/preview-banner.html +4 -4
  326. package/src/server/plugins/engine/views/partials/warn-missing-notification-email.html +4 -5
  327. package/src/server/plugins/engine/views/repeat-list-summary.html +4 -4
  328. package/src/server/plugins/engine/views/summary.html +14 -7
  329. package/src/server/plugins/map/routes/index.js +1 -1
  330. package/src/server/plugins/map/types.js +1 -16
  331. package/src/server/plugins/nunjucks/environment.js +14 -0
  332. package/src/server/plugins/nunjucks/filters/answer.js +12 -1
  333. package/src/server/plugins/postcode-lookup/models/index.js +144 -87
  334. package/src/server/plugins/postcode-lookup/routes/index.js +13 -16
  335. package/src/server/plugins/postcode-lookup/types.js +1 -0
  336. package/src/server/plugins/postcode-lookup/views/postcode-lookup-details.html +3 -3
  337. package/src/server/types.ts +2 -0
  338. package/src/server/utils/utils.js +14 -0
  339. package/src/typings/hapi/index.d.ts +1 -0
  340. package/.public/javascripts/im-search-plugin.min.js +0 -2
  341. package/.public/javascripts/im-search-plugin.min.js.map +0 -1
  342. package/.public/javascripts/vendor/preact.min.js +0 -2
  343. package/.public/javascripts/vendor/preact.min.js.map +0 -1
  344. package/.server/server/plugins/engine/components/constants.d.ts +0 -1
  345. package/.server/server/plugins/engine/components/constants.js +0 -2
  346. package/.server/server/plugins/engine/components/constants.js.map +0 -1
  347. package/src/server/plugins/engine/components/constants.ts +0 -1
@@ -6,7 +6,6 @@ import joi, {
6
6
  } from 'joi'
7
7
 
8
8
  import {
9
- FormComponent,
10
9
  isFormState,
11
10
  isFormValue
12
11
  } from './FormComponent.js'
@@ -16,11 +15,18 @@ import {
16
15
  type Field,
17
16
  type Guidance
18
17
  } from './helpers/components.js'
19
- import { type ComponentViewModel } from './types.js'
18
+ import {
19
+ type ComponentViewModel,
20
+ type RenderContext
21
+ } from './types.js'
20
22
  import { getErrors } from '../helpers.js'
23
+ import { type Translator } from '../i18n/types.js'
21
24
  import { type FormModel } from '../models/index.js'
22
25
  import { type PageControllerClass } from '../pageControllers/helpers/pages.js'
23
- import { validationOptions as opts } from '../pageControllers/validationOptions.js'
26
+ import {
27
+ buildLanguageMessages,
28
+ validationOptions as opts
29
+ } from '../pageControllers/validationOptions.js'
24
30
  import {
25
31
  type FormPayload,
26
32
  type FormState,
@@ -28,7 +34,6 @@ import {
28
34
  type FormSubmissionState,
29
35
  type FormValidationResult
30
36
  } from '../types.js'
31
- import { type FormQuery } from '../../../routes/types.js'
32
37
 
33
38
  export class ComponentCollection {
34
39
  page?: PageControllerClass
@@ -87,49 +92,6 @@ export class ComponentCollection {
87
92
  : stateSchema.keys({ [name]: field.stateSchema })
88
93
  }
89
94
 
90
- // Add parent field title to collection field errors
91
- formSchema = formSchema.error((errors) => {
92
- return errors.flatMap((error) => {
93
- if (!isErrorContext(error.local) || error.local.title) {
94
- return error
95
- }
96
-
97
- // Use field key or first missing child field
98
- let { missing, key = missing?.[0] } = error.local
99
-
100
- // But avoid numeric key used by array payloads
101
- if (typeof key === 'number') {
102
- key = error.path[0]
103
- }
104
-
105
- // Find the parent field
106
- const parent = fields.find(
107
- (item) => item.name === key?.split('__').shift()
108
- )
109
-
110
- // Find the child field
111
- const child = (parent?.collection?.fields ?? fields).find(
112
- (item) => item.name === key
113
- )
114
-
115
- // Update error with child label
116
- if (child && (!error.local.label || error.local.label === 'value')) {
117
- error.local.label = child.title
118
- }
119
-
120
- // Fix error summary links for missing fields
121
- if (missing?.length) {
122
- error.path = missing
123
- error.local.key = missing[0]
124
- }
125
-
126
- // Update error with parent title
127
- error.local.title ??= parent?.label
128
-
129
- return error
130
- })
131
- })
132
-
133
95
  if (schema?.peers) {
134
96
  formSchema = formSchema.and(...schema.peers, {
135
97
  isPresent: isFormValue
@@ -215,8 +177,14 @@ export class ComponentCollection {
215
177
  /**
216
178
  * Get all errors for all fields in this collection
217
179
  */
218
- getErrors(errors?: FormSubmissionError[]): FormSubmissionError[] | undefined {
219
- return this.getFieldErrors((field) => field.getErrors(errors), errors)
180
+ getErrors(
181
+ translator: Translator,
182
+ errors?: FormSubmissionError[]
183
+ ): FormSubmissionError[] | undefined {
184
+ return this.getFieldErrors(
185
+ (field) => field.getErrors(translator, errors),
186
+ errors
187
+ )
220
188
  }
221
189
 
222
190
  /**
@@ -225,25 +193,22 @@ export class ComponentCollection {
225
193
  * Composite fields like UKAddress can choose to return more than one error.
226
194
  */
227
195
  getViewErrors(
196
+ translator: Translator,
228
197
  errors?: FormSubmissionError[]
229
198
  ): FormSubmissionError[] | undefined {
230
- return this.getFieldErrors((field) => field.getViewErrors(errors), errors)
199
+ return this.getFieldErrors(
200
+ (field) => field.getViewErrors(translator, errors),
201
+ errors
202
+ )
231
203
  }
232
204
 
233
- getViewModel(
234
- payload: FormPayload,
235
- errors?: FormSubmissionError[],
236
- query: FormQuery = {}
237
- ) {
205
+ getViewModel(context: RenderContext) {
238
206
  const { components } = this
239
207
 
240
208
  const result: ComponentViewModel[] = components.map((component) => {
241
209
  const { isFormComponent, type } = component
242
210
 
243
- const model =
244
- component instanceof FormComponent
245
- ? component.getViewModel(payload, errors, query)
246
- : component.getViewModel()
211
+ const model = component.getViewModel(context)
247
212
 
248
213
  return { type, isFormComponent, model }
249
214
  })
@@ -251,11 +216,128 @@ export class ComponentCollection {
251
216
  return result
252
217
  }
253
218
 
219
+ overrideParentTitle(
220
+ formSchema: joi.ObjectSchema<FormPayload>,
221
+ translator: Translator | undefined
222
+ ) {
223
+ // Add parent field title to collection field errors
224
+ return formSchema.error((errors) => {
225
+ return errors.flatMap((error) => {
226
+ if (!isErrorContext(error.local) || error.local.title) {
227
+ return error
228
+ }
229
+
230
+ // Use field key or first missing child field
231
+ let { missing, key = missing?.[0] } = error.local
232
+
233
+ // But avoid numeric key used by array payloads
234
+ if (typeof key === 'number') {
235
+ key = error.path[0]
236
+ }
237
+
238
+ // Find the parent field
239
+ const parent = this.fields.find(
240
+ (item) => item.name === key?.split('__').shift()
241
+ )
242
+
243
+ // Find the child field
244
+ const child = (parent?.collection?.fields ?? this.fields).find(
245
+ (item) => item.name === key
246
+ )
247
+
248
+ // Update error with child label
249
+ if (child && (!error.local.label || error.local.label === 'value')) {
250
+ error.local.label = child.title
251
+ }
252
+
253
+ // Fix error summary links for missing fields
254
+ if (missing?.length) {
255
+ error.path = missing
256
+ error.local.key = missing[0]
257
+ }
258
+
259
+ // Update error with parent title
260
+ if (translator && parent) {
261
+ error.local.title ??= translator.tComponent(
262
+ parent as ComponentDef,
263
+ 'title'
264
+ )
265
+ } else {
266
+ error.local.title ??= parent?.label
267
+ }
268
+
269
+ return error
270
+ })
271
+ })
272
+ }
273
+
254
274
  /**
255
275
  * Validate form payload
256
276
  */
257
- validate(value: FormPayload = {}): FormValidationResult<FormPayload> {
258
- const result = this.formSchema.validate(value, opts)
277
+ validate(
278
+ value: FormPayload = {},
279
+ translator?: Translator
280
+ ): FormValidationResult<FormPayload> {
281
+ const messages = translator
282
+ ? buildLanguageMessages(translator.t)
283
+ : undefined
284
+
285
+ // When translating, override Joi labels (and custom schema messages where
286
+ // needed) so #label/#title in message templates resolve in the correct language.
287
+ let schema = this.formSchema
288
+ // Add parent field title to collection field errors
289
+ schema = this.overrideParentTitle(schema, translator)
290
+
291
+ if (translator) {
292
+ const { t } = translator
293
+ const labelOverrides: Record<string, joi.Schema> = {}
294
+
295
+ for (const field of this.fields) {
296
+ if (field.collection) {
297
+ // Composite field: translate each sub-field's label using the key constant
298
+ // (e.g. 'components.addressField.line1' → "Llinell cyfeiriad 1") and apply
299
+ // any field-type-specific message overrides (e.g. objectMissing for dates).
300
+ const messagesOverride =
301
+ field.getValidationMessagesOverride(translator)
302
+ for (const subField of field.collection.fields) {
303
+ const translatedSubLabel = t(subField.title) || subField.label
304
+ let patchedSchema = subField.formSchema.label(translatedSubLabel)
305
+ if (messagesOverride) {
306
+ patchedSchema = patchedSchema.messages(messagesOverride)
307
+ }
308
+ labelOverrides[subField.name] = patchedSchema
309
+ }
310
+ } else {
311
+ const translatedLabel =
312
+ translator.tComponent(
313
+ field as unknown as ComponentDef,
314
+ 'shortDescription'
315
+ ) ||
316
+ translator.tComponent(field as unknown as ComponentDef, 'title')
317
+ const messagesOverride =
318
+ field.getValidationMessagesOverride(translator)
319
+ let patchedSchema = field.formSchema
320
+ if (translatedLabel && translatedLabel !== field.label) {
321
+ patchedSchema = patchedSchema.label(translatedLabel)
322
+ }
323
+ if (messagesOverride) {
324
+ patchedSchema = patchedSchema.messages(messagesOverride)
325
+ }
326
+ if (patchedSchema !== field.formSchema) {
327
+ labelOverrides[field.name] = patchedSchema
328
+ }
329
+ }
330
+ }
331
+
332
+ if (Object.keys(labelOverrides).length) {
333
+ schema = schema.keys(labelOverrides)
334
+ }
335
+ }
336
+
337
+ const result = schema.validate(value, {
338
+ ...opts,
339
+ ...(messages && { messages })
340
+ })
259
341
 
260
342
  const details = result.error?.details
261
343
 
@@ -11,16 +11,18 @@ import {
11
11
  import { NumberField } from './NumberField.js'
12
12
  import {
13
13
  type DateInputItem,
14
- type DatePartsState
14
+ type DatePartsState,
15
+ type RenderContext
15
16
  } from './types.js'
16
17
  import { parseStrictDate } from '../date-helper.js'
18
+ import { buildValidationMessages } from '../i18n/buildValidationMessages.js'
19
+ import { type Translator } from '../i18n/types.js'
17
20
  import { messageTemplate } from '../pageControllers/validationOptions.js'
18
21
  import {
19
22
  type ErrorMessageTemplateList,
20
23
  type FormPayload,
21
24
  type FormState,
22
25
  type FormStateValue,
23
- type FormSubmissionError,
24
26
  type FormSubmissionState
25
27
  } from '../types.js'
26
28
  import { convertToLanguageMessages } from '../../../utils/type-utils.js'
@@ -56,7 +58,7 @@ export class DatePartsField extends FormComponent {
56
58
  {
57
59
  type: ComponentType.NumberField,
58
60
  name: `${name}__day`,
59
- title: 'Day',
61
+ title: 'components.dateField.day',
60
62
  schema: { min: 1, max: 31, precision: 0 },
61
63
  options: {
62
64
  required: isRequired,
@@ -68,7 +70,7 @@ export class DatePartsField extends FormComponent {
68
70
  {
69
71
  type: ComponentType.NumberField,
70
72
  name: `${name}__month`,
71
- title: 'Month',
73
+ title: 'components.dateField.month',
72
74
  schema: { min: 1, max: 12, precision: 0 },
73
75
  options: {
74
76
  required: isRequired,
@@ -80,7 +82,7 @@ export class DatePartsField extends FormComponent {
80
82
  {
81
83
  type: ComponentType.NumberField,
82
84
  name: `${name}__year`,
83
- title: 'Year',
85
+ title: 'components.dateField.year',
84
86
  schema: { min: 1000, max: 3000, precision: 0 },
85
87
  options: {
86
88
  required: isRequired,
@@ -107,7 +109,10 @@ export class DatePartsField extends FormComponent {
107
109
  return this.isState(value) ? value : undefined
108
110
  }
109
111
 
110
- getDisplayStringFromFormValue(formValue: DatePartsState | undefined) {
112
+ getDisplayStringFromFormValue(
113
+ formValue: DatePartsState | undefined,
114
+ _translator: Translator
115
+ ) {
111
116
  if (!formValue) {
112
117
  return ''
113
118
  }
@@ -118,10 +123,13 @@ export class DatePartsField extends FormComponent {
118
123
  )
119
124
  }
120
125
 
121
- getDisplayStringFromState(state: FormSubmissionState) {
126
+ getDisplayStringFromState(
127
+ state: FormSubmissionState,
128
+ translator: Translator
129
+ ) {
122
130
  const value = this.getFormValueFromState(state)
123
131
 
124
- return this.getDisplayStringFromFormValue(value)
132
+ return this.getDisplayStringFromFormValue(value, translator)
125
133
  }
126
134
 
127
135
  getContextValueFromFormValue(value: DatePartsState | undefined) {
@@ -148,10 +156,24 @@ export class DatePartsField extends FormComponent {
148
156
  return this.getContextValueFromFormValue(value)
149
157
  }
150
158
 
151
- getViewModel(payload: FormPayload, errors?: FormSubmissionError[]) {
159
+ getValidationMessagesOverride(translator: Translator) {
160
+ const { t } = translator
161
+ return convertToLanguageMessages({
162
+ 'any.required': buildValidationMessages(t).objectMissing,
163
+ 'number.base': buildValidationMessages(t).objectMissing,
164
+ 'number.precision': buildValidationMessages(t).dateFormat,
165
+ 'number.integer': buildValidationMessages(t).dateFormat,
166
+ 'number.unsafe': buildValidationMessages(t).dateFormat,
167
+ 'number.min': buildValidationMessages(t).dateFormat,
168
+ 'number.max': buildValidationMessages(t).dateFormat
169
+ })
170
+ }
171
+
172
+ getViewModel(context: RenderContext) {
173
+ const { errors } = context
152
174
  const { collection, name } = this
153
175
 
154
- const viewModel = super.getViewModel(payload, errors)
176
+ const viewModel = super.getViewModel(context)
155
177
  let { fieldset, label } = viewModel
156
178
 
157
179
  // Check for component errors only
@@ -159,7 +181,7 @@ export class DatePartsField extends FormComponent {
159
181
 
160
182
  // Use the component collection to generate the subitems
161
183
  const items: DateInputItem[] = collection
162
- .getViewModel(payload, errors)
184
+ .getViewModel(context)
163
185
  .map(({ model }) => {
164
186
  let { label, type, value, classes, errorMessage } = model
165
187
 
@@ -2,12 +2,14 @@ import {
2
2
  ComponentType,
3
3
  hasFormComponents,
4
4
  isFormType,
5
+ type ComponentDef,
5
6
  type DeclarationFieldComponent,
6
7
  type Item
7
8
  } from '@defra/forms-model'
8
9
  import joi, {
9
10
  type ArraySchema,
10
11
  type BooleanSchema,
12
+ type LanguageMessages,
11
13
  type StringSchema
12
14
  } from 'joi'
13
15
 
@@ -15,23 +17,23 @@ import {
15
17
  FormComponent,
16
18
  isFormValue
17
19
  } from './FormComponent.js'
20
+ import { type RenderContext } from './types.js'
21
+ import { buildValidationMessages } from '../i18n/buildValidationMessages.js'
22
+ import { type Translator } from '../i18n/types.js'
18
23
  import { messageTemplate } from '../pageControllers/validationOptions.js'
19
24
  import {
20
25
  type ErrorMessageTemplateList,
21
26
  type FormPayload,
22
27
  type FormState,
23
28
  type FormStateValue,
24
- type FormSubmissionError,
25
29
  type FormSubmissionState,
26
30
  type FormValue
27
31
  } from '../types.js'
28
32
 
29
33
  export class DeclarationField extends FormComponent {
30
- private readonly DEFAULT_DECLARATION_LABEL = 'I understand and agree'
31
-
32
34
  declare options: DeclarationFieldComponent['options']
33
35
 
34
- declare declarationConfirmationLabel: string
36
+ declare declarationConfirmationLabel: string | undefined
35
37
 
36
38
  declare formSchema: ArraySchema<StringSchema[]>
37
39
  declare stateSchema: BooleanSchema
@@ -69,8 +71,9 @@ export class DeclarationField extends FormComponent {
69
71
 
70
72
  this.options = options
71
73
  this.content = content
72
- this.declarationConfirmationLabel =
73
- options.declarationConfirmationLabel ?? this.DEFAULT_DECLARATION_LABEL
74
+ // Store only the form-authored label (if provided). If absent, getViewModel
75
+ // resolves the default via t() at render time so the correct language is used.
76
+ this.declarationConfirmationLabel = options.declarationConfirmationLabel
74
77
  const formComponents = hasFormComponents(props.page?.pageDef)
75
78
  ? props.page.pageDef.components
76
79
  : []
@@ -114,20 +117,40 @@ export class DeclarationField extends FormComponent {
114
117
  return this.isValue(value) ? value : undefined
115
118
  }
116
119
 
117
- getDisplayStringFromFormValue(value: FormValue | FormPayload): string {
118
- return value === 'true' ? this.declarationConfirmationLabel : 'Not provided'
120
+ getValidationMessagesOverride(translator: Translator) {
121
+ const { declarationRequired } = buildValidationMessages(translator.t)
122
+ const msg = declarationRequired as unknown as string
123
+ return {
124
+ 'any.required': msg,
125
+ 'any.unknown': msg,
126
+ 'array.includesRequiredUnknowns': msg
127
+ } as unknown as LanguageMessages
119
128
  }
120
129
 
121
- getViewModel(payload: FormPayload, errors?: FormSubmissionError[]) {
122
- const defaultDeclarationConfirmationLabel =
123
- 'I confirm that I understand and accept this declaration'
130
+ getDisplayStringFromFormValue(
131
+ value: FormValue | FormPayload,
132
+ translator: Translator
133
+ ): string {
134
+ const { t } = translator
135
+ return value === 'true'
136
+ ? (this.declarationConfirmationLabel ??
137
+ t('components.declarationField.defaultLabel'))
138
+ : t('components.declarationField.notProvided')
139
+ }
140
+
141
+ getViewModel(context: RenderContext) {
142
+ const { payload } = context
143
+ const { t, tComponent } = context.translator
144
+
124
145
  const {
125
146
  hint,
126
- content,
127
- declarationConfirmationLabel = defaultDeclarationConfirmationLabel
147
+ declarationConfirmationLabel = t(
148
+ 'components.declarationField.defaultLabel'
149
+ )
128
150
  } = this
151
+ const content = tComponent(this as unknown as ComponentDef, 'content')
129
152
 
130
- const viewModel = super.getViewModel(payload, errors)
153
+ const viewModel = super.getViewModel(context)
131
154
  let { fieldset, label } = viewModel
132
155
 
133
156
  fieldset ??= {
@@ -16,7 +16,12 @@ import {
16
16
  } from './LocationFieldHelpers.js'
17
17
  import { NumberField } from './NumberField.js'
18
18
  import { createLowerFirstExpression } from './helpers/index.js'
19
- import { type EastingNorthingState } from './types.js'
19
+ import {
20
+ type EastingNorthingState,
21
+ type RenderContext
22
+ } from './types.js'
23
+ import { t as tPlugin } from '../i18n/index.js'
24
+ import { type Translator } from '../i18n/types.js'
20
25
  import { messageTemplate } from '../pageControllers/validationOptions.js'
21
26
  import {
22
27
  type ErrorMessageTemplateList,
@@ -55,18 +60,47 @@ export class EastingNorthingField extends FormComponent {
55
60
  const northingMin = schema?.northing?.min ?? DEFAULT_NORTHING_MIN
56
61
  const northingMax = schema?.northing?.max ?? DEFAULT_NORTHING_MAX
57
62
 
58
- const eastingRequired = 'Enter easting'
59
- const northingRequired = 'Enter northing'
63
+ const fieldLabel = lowerFirst(this.label)
60
64
 
61
- const eastingDigitsMessage = `{{#label}} for ${lowerFirst(this.label)} must be between 1 and 6 digits`
62
- const northingDigitsMessage = `{{#label}} for ${lowerFirst(this.label)} must be between 1 and 7 digits`
65
+ const eastingDigitsMessage = tPlugin(
66
+ 'components.eastingNorthingField.eastingDigits',
67
+ 'en-GB',
68
+ { fieldLabel }
69
+ )
70
+ const northingDigitsMessage = tPlugin(
71
+ 'components.eastingNorthingField.northingDigits',
72
+ 'en-GB',
73
+ { fieldLabel }
74
+ )
63
75
 
64
76
  const customValidationMessages: LanguageMessages =
65
77
  convertToLanguageMessages({
66
- 'any.required': eastingRequired,
67
- 'number.base': eastingRequired,
68
- 'number.min': `{{#label}} for ${lowerFirst(this.label)} must be between {{#limit}} and ${eastingMax}`,
69
- 'number.max': `{{#label}} for ${lowerFirst(this.label)} must be between ${eastingMin} and {{#limit}}`,
78
+ 'any.required': tPlugin(
79
+ 'components.eastingNorthingField.eastingRequired',
80
+ 'en-GB'
81
+ ),
82
+ 'number.base': tPlugin(
83
+ 'components.eastingNorthingField.eastingRequired',
84
+ 'en-GB'
85
+ ),
86
+ 'number.min': tPlugin(
87
+ 'components.eastingNorthingField.eastingRange',
88
+ 'en-GB',
89
+ {
90
+ fieldLabel,
91
+ min: eastingMin,
92
+ max: eastingMax
93
+ }
94
+ ),
95
+ 'number.max': tPlugin(
96
+ 'components.eastingNorthingField.eastingRange',
97
+ 'en-GB',
98
+ {
99
+ fieldLabel,
100
+ min: eastingMin,
101
+ max: eastingMax
102
+ }
103
+ ),
70
104
  'number.precision': eastingDigitsMessage,
71
105
  'number.integer': eastingDigitsMessage,
72
106
  'number.unsafe': eastingDigitsMessage
@@ -74,10 +108,32 @@ export class EastingNorthingField extends FormComponent {
74
108
 
75
109
  const northingValidationMessages: LanguageMessages =
76
110
  convertToLanguageMessages({
77
- 'any.required': northingRequired,
78
- 'number.base': northingRequired,
79
- 'number.min': `{{#label}} for ${lowerFirst(this.label)} must be between {{#limit}} and ${northingMax}`,
80
- 'number.max': `{{#label}} for ${lowerFirst(this.label)} must be between ${northingMin} and {{#limit}}`,
111
+ 'any.required': tPlugin(
112
+ 'components.eastingNorthingField.northingRequired',
113
+ 'en-GB'
114
+ ),
115
+ 'number.base': tPlugin(
116
+ 'components.eastingNorthingField.northingRequired',
117
+ 'en-GB'
118
+ ),
119
+ 'number.min': tPlugin(
120
+ 'components.eastingNorthingField.northingRange',
121
+ 'en-GB',
122
+ {
123
+ fieldLabel,
124
+ min: northingMin,
125
+ max: northingMax
126
+ }
127
+ ),
128
+ 'number.max': tPlugin(
129
+ 'components.eastingNorthingField.northingRange',
130
+ 'en-GB',
131
+ {
132
+ fieldLabel,
133
+ min: northingMin,
134
+ max: northingMax
135
+ }
136
+ ),
81
137
  'number.precision': northingDigitsMessage,
82
138
  'number.integer': northingDigitsMessage,
83
139
  'number.unsafe': northingDigitsMessage
@@ -88,7 +144,7 @@ export class EastingNorthingField extends FormComponent {
88
144
  {
89
145
  type: ComponentType.NumberField,
90
146
  name: `${name}__easting`,
91
- title: 'Easting',
147
+ title: 'components.eastingNorthingField.easting',
92
148
  schema: {
93
149
  min: eastingMin,
94
150
  max: eastingMax,
@@ -104,7 +160,7 @@ export class EastingNorthingField extends FormComponent {
104
160
  {
105
161
  type: ComponentType.NumberField,
106
162
  name: `${name}__northing`,
107
- title: 'Northing',
163
+ title: 'components.eastingNorthingField.northing',
108
164
  schema: {
109
165
  min: northingMin,
110
166
  max: northingMax,
@@ -135,7 +191,8 @@ export class EastingNorthingField extends FormComponent {
135
191
  }
136
192
 
137
193
  getDisplayStringFromFormValue(
138
- value: EastingNorthingState | undefined
194
+ value: EastingNorthingState | undefined,
195
+ _translator: Translator
139
196
  ): string {
140
197
  if (!value) {
141
198
  return ''
@@ -145,10 +202,13 @@ export class EastingNorthingField extends FormComponent {
145
202
  return `${value.easting}, ${value.northing}`
146
203
  }
147
204
 
148
- getDisplayStringFromState(state: FormSubmissionState) {
205
+ getDisplayStringFromState(
206
+ state: FormSubmissionState,
207
+ translator: Translator
208
+ ) {
149
209
  const value = this.getFormValueFromState(state)
150
210
 
151
- return this.getDisplayStringFromFormValue(value)
211
+ return this.getDisplayStringFromFormValue(value, translator)
152
212
  }
153
213
 
154
214
  getContextValueFromFormValue(
@@ -167,15 +227,16 @@ export class EastingNorthingField extends FormComponent {
167
227
  return this.getContextValueFromFormValue(value)
168
228
  }
169
229
 
170
- getViewModel(payload: FormPayload, errors?: FormSubmissionError[]) {
171
- const viewModel = super.getViewModel(payload, errors)
172
- return getLocationFieldViewModel(this, viewModel, payload, errors)
230
+ getViewModel(context: RenderContext) {
231
+ const viewModel = super.getViewModel(context)
232
+ return getLocationFieldViewModel(this, viewModel, context)
173
233
  }
174
234
 
175
235
  getViewErrors(
236
+ translator: Translator,
176
237
  errors?: FormSubmissionError[]
177
238
  ): FormSubmissionError[] | undefined {
178
- const allErrors = this.getErrors(errors)
239
+ const allErrors = this.getErrors(translator, errors)
179
240
  return deduplicateErrorsByHref(allErrors)
180
241
  }
181
242
 
@@ -5,12 +5,9 @@ import {
5
5
  import joi, { type CustomHelpers } from 'joi'
6
6
 
7
7
  import { FormComponent } from './FormComponent.js'
8
+ import { type RenderContext } from './types.js'
8
9
  import { messageTemplate } from '../pageControllers/validationOptions.js'
9
- import {
10
- type ErrorMessageTemplateList,
11
- type FormPayload,
12
- type FormSubmissionError
13
- } from '../types.js'
10
+ import { type ErrorMessageTemplateList } from '../types.js'
14
11
 
15
12
  export class EmailAddressField extends FormComponent {
16
13
  declare options: EmailAddressFieldComponent['options']
@@ -54,8 +51,8 @@ export class EmailAddressField extends FormComponent {
54
51
  this.options = options
55
52
  }
56
53
 
57
- getViewModel(payload: FormPayload, errors?: FormSubmissionError[]) {
58
- const viewModel = super.getViewModel(payload, errors)
54
+ getViewModel(context: RenderContext) {
55
+ const viewModel = super.getViewModel(context)
59
56
  const { attributes } = viewModel
60
57
 
61
58
  attributes.autocomplete = 'email'