@defra/forms-engine-plugin 5.0.0-alpha.2 → 5.0.0-alpha.20

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 (339) hide show
  1. package/.public/javascripts/application.min.js +1 -1
  2. package/.public/javascripts/application.min.js.LICENSE.txt +7 -0
  3. package/.public/javascripts/application.min.js.map +1 -1
  4. package/.public/javascripts/shared.min.js +1 -1
  5. package/.public/javascripts/shared.min.js.LICENSE.txt +7 -0
  6. package/.public/javascripts/shared.min.js.map +1 -1
  7. package/.public/stylesheets/application.min.css.map +1 -1
  8. package/.server/client/javascripts/file-upload.js +6 -3
  9. package/.server/client/javascripts/file-upload.js.map +1 -1
  10. package/.server/client/javascripts/geospatial-map.d.ts +153 -5
  11. package/.server/client/javascripts/geospatial-map.js +157 -77
  12. package/.server/client/javascripts/geospatial-map.js.map +1 -1
  13. package/.server/client/javascripts/govuk.js +2 -1
  14. package/.server/client/javascripts/govuk.js.map +1 -1
  15. package/.server/client/javascripts/location-map.d.ts +44 -0
  16. package/.server/client/javascripts/location-map.js +54 -5
  17. package/.server/client/javascripts/location-map.js.map +1 -1
  18. package/.server/client/javascripts/map-constants.d.ts +3 -0
  19. package/.server/client/javascripts/map-constants.js +4 -0
  20. package/.server/client/javascripts/map-constants.js.map +1 -0
  21. package/.server/client/javascripts/map.d.ts +10 -0
  22. package/.server/client/javascripts/map.js +42 -0
  23. package/.server/client/javascripts/map.js.map +1 -1
  24. package/.server/client/javascripts/maps.d.ts +5 -0
  25. package/.server/client/javascripts/maps.js +6 -0
  26. package/.server/client/javascripts/maps.js.map +1 -0
  27. package/.server/client/javascripts/shared.d.ts +1 -4
  28. package/.server/client/javascripts/shared.js +1 -4
  29. package/.server/client/javascripts/shared.js.map +1 -1
  30. package/.server/client/javascripts/sssi-dataset.d.ts +18 -20
  31. package/.server/client/javascripts/sssi-dataset.js +37 -39
  32. package/.server/client/javascripts/sssi-dataset.js.map +1 -1
  33. package/.server/client/stylesheets/maps.scss +4 -0
  34. package/.server/client/stylesheets/shared.scss +1 -5
  35. package/.server/server/constants.d.ts +2 -0
  36. package/.server/server/constants.js +2 -0
  37. package/.server/server/constants.js.map +1 -1
  38. package/.server/server/plugins/engine/__stubs__/definitions.d.ts +29 -0
  39. package/.server/server/plugins/engine/__stubs__/definitions.js +125 -0
  40. package/.server/server/plugins/engine/__stubs__/definitions.js.map +1 -0
  41. package/.server/server/plugins/engine/components/AutocompleteField.d.ts +9 -3
  42. package/.server/server/plugins/engine/components/AutocompleteField.js +12 -0
  43. package/.server/server/plugins/engine/components/AutocompleteField.js.map +1 -1
  44. package/.server/server/plugins/engine/components/CheckboxesField.d.ts +21 -0
  45. package/.server/server/plugins/engine/components/CheckboxesField.js +30 -5
  46. package/.server/server/plugins/engine/components/CheckboxesField.js.map +1 -1
  47. package/.server/server/plugins/engine/components/ComponentBase.d.ts +1 -0
  48. package/.server/server/plugins/engine/components/ComponentBase.js +2 -0
  49. package/.server/server/plugins/engine/components/ComponentBase.js.map +1 -1
  50. package/.server/server/plugins/engine/components/ComponentCollection.js +11 -6
  51. package/.server/server/plugins/engine/components/ComponentCollection.js.map +1 -1
  52. package/.server/server/plugins/engine/components/DatePartsField.d.ts +6 -3
  53. package/.server/server/plugins/engine/components/DatePartsField.js +12 -7
  54. package/.server/server/plugins/engine/components/DatePartsField.js.map +1 -1
  55. package/.server/server/plugins/engine/components/DeclarationField.d.ts +5 -2
  56. package/.server/server/plugins/engine/components/DeclarationField.js +6 -4
  57. package/.server/server/plugins/engine/components/DeclarationField.js.map +1 -1
  58. package/.server/server/plugins/engine/components/Details.d.ts +1 -0
  59. package/.server/server/plugins/engine/components/EastingNorthingField.d.ts +33 -2
  60. package/.server/server/plugins/engine/components/EastingNorthingField.js +110 -54
  61. package/.server/server/plugins/engine/components/EastingNorthingField.js.map +1 -1
  62. package/.server/server/plugins/engine/components/EmailAddressField.d.ts +4 -1
  63. package/.server/server/plugins/engine/components/EmailAddressField.js +2 -1
  64. package/.server/server/plugins/engine/components/EmailAddressField.js.map +1 -1
  65. package/.server/server/plugins/engine/components/FileUploadField.d.ts +21 -0
  66. package/.server/server/plugins/engine/components/FileUploadField.js +35 -3
  67. package/.server/server/plugins/engine/components/FileUploadField.js.map +1 -1
  68. package/.server/server/plugins/engine/components/FormComponent.d.ts +5 -1
  69. package/.server/server/plugins/engine/components/FormComponent.js +5 -2
  70. package/.server/server/plugins/engine/components/FormComponent.js.map +1 -1
  71. package/.server/server/plugins/engine/components/GeospatialField.d.ts +23 -0
  72. package/.server/server/plugins/engine/components/GeospatialField.js +33 -9
  73. package/.server/server/plugins/engine/components/GeospatialField.js.map +1 -1
  74. package/.server/server/plugins/engine/components/Html.d.ts +1 -0
  75. package/.server/server/plugins/engine/components/InsetText.d.ts +1 -0
  76. package/.server/server/plugins/engine/components/LatLongField.d.ts +32 -2
  77. package/.server/server/plugins/engine/components/LatLongField.js +85 -48
  78. package/.server/server/plugins/engine/components/LatLongField.js.map +1 -1
  79. package/.server/server/plugins/engine/components/List.d.ts +1 -0
  80. package/.server/server/plugins/engine/components/ListFormComponent.d.ts +1 -0
  81. package/.server/server/plugins/engine/components/LocationFieldBase.d.ts +8 -2
  82. package/.server/server/plugins/engine/components/LocationFieldBase.js +25 -6
  83. package/.server/server/plugins/engine/components/LocationFieldBase.js.map +1 -1
  84. package/.server/server/plugins/engine/components/LocationFieldHelpers.d.ts +12 -3
  85. package/.server/server/plugins/engine/components/LocationFieldHelpers.js +21 -13
  86. package/.server/server/plugins/engine/components/LocationFieldHelpers.js.map +1 -1
  87. package/.server/server/plugins/engine/components/Markdown.d.ts +1 -0
  88. package/.server/server/plugins/engine/components/Markdown.js +1 -1
  89. package/.server/server/plugins/engine/components/Markdown.js.map +1 -1
  90. package/.server/server/plugins/engine/components/MonthYearField.d.ts +5 -2
  91. package/.server/server/plugins/engine/components/MonthYearField.js +13 -9
  92. package/.server/server/plugins/engine/components/MonthYearField.js.map +1 -1
  93. package/.server/server/plugins/engine/components/MultilineTextField.d.ts +1 -0
  94. package/.server/server/plugins/engine/components/NationalGridFieldNumberField.d.ts +2 -1
  95. package/.server/server/plugins/engine/components/NationalGridFieldNumberField.js +4 -3
  96. package/.server/server/plugins/engine/components/NationalGridFieldNumberField.js.map +1 -1
  97. package/.server/server/plugins/engine/components/NotificationBanner.d.ts +1 -0
  98. package/.server/server/plugins/engine/components/NumberField.d.ts +5 -0
  99. package/.server/server/plugins/engine/components/NumberField.js +16 -0
  100. package/.server/server/plugins/engine/components/NumberField.js.map +1 -1
  101. package/.server/server/plugins/engine/components/OsGridRefField.d.ts +103 -1
  102. package/.server/server/plugins/engine/components/OsGridRefField.js +13 -3
  103. package/.server/server/plugins/engine/components/OsGridRefField.js.map +1 -1
  104. package/.server/server/plugins/engine/components/PaymentField.d.ts +3 -0
  105. package/.server/server/plugins/engine/components/PaymentField.js +17 -6
  106. package/.server/server/plugins/engine/components/PaymentField.js.map +1 -1
  107. package/.server/server/plugins/engine/components/SelectField.d.ts +1 -0
  108. package/.server/server/plugins/engine/components/SelectionControlField.d.ts +1 -0
  109. package/.server/server/plugins/engine/components/TelephoneNumberField.d.ts +1 -0
  110. package/.server/server/plugins/engine/components/UkAddressField.d.ts +1 -0
  111. package/.server/server/plugins/engine/components/UkAddressField.js +23 -8
  112. package/.server/server/plugins/engine/components/UkAddressField.js.map +1 -1
  113. package/.server/server/plugins/engine/components/YesNoField.d.ts +5 -2
  114. package/.server/server/plugins/engine/components/YesNoField.js +17 -8
  115. package/.server/server/plugins/engine/components/YesNoField.js.map +1 -1
  116. package/.server/server/plugins/engine/components/helpers/components.js +3 -3
  117. package/.server/server/plugins/engine/components/helpers/components.js.map +1 -1
  118. package/.server/server/plugins/engine/components/helpers/geospatial.d.ts +8 -1
  119. package/.server/server/plugins/engine/components/helpers/geospatial.js +56 -15
  120. package/.server/server/plugins/engine/components/helpers/geospatial.js.map +1 -1
  121. package/.server/server/plugins/engine/components/helpers/index.d.ts +7 -0
  122. package/.server/server/plugins/engine/components/helpers/index.js +13 -1
  123. package/.server/server/plugins/engine/components/helpers/index.js.map +1 -1
  124. package/.server/server/plugins/engine/components/types.d.ts +1 -0
  125. package/.server/server/plugins/engine/components/types.js.map +1 -1
  126. package/.server/server/plugins/engine/errors.d.ts +49 -0
  127. package/.server/server/plugins/engine/errors.js +75 -0
  128. package/.server/server/plugins/engine/errors.js.map +1 -0
  129. package/.server/server/plugins/engine/form-availability.d.ts +3 -2
  130. package/.server/server/plugins/engine/form-availability.js +3 -2
  131. package/.server/server/plugins/engine/form-availability.js.map +1 -1
  132. package/.server/server/plugins/engine/form-context.js +2 -2
  133. package/.server/server/plugins/engine/form-context.js.map +1 -1
  134. package/.server/server/plugins/engine/helpers.d.ts +22 -2
  135. package/.server/server/plugins/engine/helpers.js +44 -5
  136. package/.server/server/plugins/engine/helpers.js.map +1 -1
  137. package/.server/server/plugins/engine/i18n/buildValidationMessages.d.ts +4 -1
  138. package/.server/server/plugins/engine/i18n/buildValidationMessages.js +31 -7
  139. package/.server/server/plugins/engine/i18n/buildValidationMessages.js.map +1 -1
  140. package/.server/server/plugins/engine/i18n/createFormTranslator.d.ts +4 -4
  141. package/.server/server/plugins/engine/i18n/createFormTranslator.js +33 -4
  142. package/.server/server/plugins/engine/i18n/createFormTranslator.js.map +1 -1
  143. package/.server/server/plugins/engine/i18n/extractBaseTranslations.d.ts +1 -1
  144. package/.server/server/plugins/engine/i18n/extractBaseTranslations.js +9 -0
  145. package/.server/server/plugins/engine/i18n/extractBaseTranslations.js.map +1 -1
  146. package/.server/server/plugins/engine/i18n/form.d.ts +13 -0
  147. package/.server/server/plugins/engine/i18n/form.js +35 -0
  148. package/.server/server/plugins/engine/i18n/form.js.map +1 -0
  149. package/.server/server/plugins/engine/i18n/languages.d.ts +10 -0
  150. package/.server/server/plugins/engine/i18n/languages.js +19 -0
  151. package/.server/server/plugins/engine/i18n/languages.js.map +1 -0
  152. package/.server/server/plugins/engine/i18n/translations/cy.json +192 -9
  153. package/.server/server/plugins/engine/i18n/translations/en-GB.json +125 -7
  154. package/.server/server/plugins/engine/i18n/types.d.ts +3 -0
  155. package/.server/server/plugins/engine/i18n/types.js.map +1 -1
  156. package/.server/server/plugins/engine/index.d.ts +4 -0
  157. package/.server/server/plugins/engine/index.js +4 -0
  158. package/.server/server/plugins/engine/index.js.map +1 -1
  159. package/.server/server/plugins/engine/models/FormModel.d.ts +0 -4
  160. package/.server/server/plugins/engine/models/FormModel.js +19 -17
  161. package/.server/server/plugins/engine/models/FormModel.js.map +1 -1
  162. package/.server/server/plugins/engine/models/SummaryViewModel.js +9 -4
  163. package/.server/server/plugins/engine/models/SummaryViewModel.js.map +1 -1
  164. package/.server/server/plugins/engine/models/unavailable-view-model.d.ts +11 -2
  165. package/.server/server/plugins/engine/models/unavailable-view-model.js +23 -4
  166. package/.server/server/plugins/engine/models/unavailable-view-model.js.map +1 -1
  167. package/.server/server/plugins/engine/outputFormatters/adapter/v1.js +3 -5
  168. package/.server/server/plugins/engine/outputFormatters/adapter/v1.js.map +1 -1
  169. package/.server/server/plugins/engine/outputFormatters/human/v1.js +2 -1
  170. package/.server/server/plugins/engine/outputFormatters/human/v1.js.map +1 -1
  171. package/.server/server/plugins/engine/outputFormatters/machine/v2.d.ts +2 -0
  172. package/.server/server/plugins/engine/outputFormatters/machine/v2.js +2 -0
  173. package/.server/server/plugins/engine/outputFormatters/machine/v2.js.map +1 -1
  174. package/.server/server/plugins/engine/pageControllers/FileUploadPageController.d.ts +7 -1
  175. package/.server/server/plugins/engine/pageControllers/FileUploadPageController.js +56 -10
  176. package/.server/server/plugins/engine/pageControllers/FileUploadPageController.js.map +1 -1
  177. package/.server/server/plugins/engine/pageControllers/QuestionPageController.d.ts +1 -1
  178. package/.server/server/plugins/engine/pageControllers/QuestionPageController.js +7 -3
  179. package/.server/server/plugins/engine/pageControllers/QuestionPageController.js.map +1 -1
  180. package/.server/server/plugins/engine/pageControllers/RepeatPageController.js +3 -4
  181. package/.server/server/plugins/engine/pageControllers/RepeatPageController.js.map +1 -1
  182. package/.server/server/plugins/engine/pageControllers/SummaryPageController.js +10 -4
  183. package/.server/server/plugins/engine/pageControllers/SummaryPageController.js.map +1 -1
  184. package/.server/server/plugins/engine/pageControllers/helpers/pages.js +2 -1
  185. package/.server/server/plugins/engine/pageControllers/helpers/pages.js.map +1 -1
  186. package/.server/server/plugins/engine/pageControllers/helpers/submission.d.ts +1 -1
  187. package/.server/server/plugins/engine/pageControllers/helpers/submission.js +3 -3
  188. package/.server/server/plugins/engine/pageControllers/helpers/submission.js.map +1 -1
  189. package/.server/server/plugins/engine/pageControllers/validationOptions.d.ts +1 -1
  190. package/.server/server/plugins/engine/pageControllers/validationOptions.js +24 -3
  191. package/.server/server/plugins/engine/pageControllers/validationOptions.js.map +1 -1
  192. package/.server/server/plugins/engine/types/schema.js +1 -0
  193. package/.server/server/plugins/engine/types/schema.js.map +1 -1
  194. package/.server/server/plugins/engine/types.d.ts +5 -0
  195. package/.server/server/plugins/engine/types.js.map +1 -1
  196. package/.server/server/plugins/engine/unavailable-response.js +5 -2
  197. package/.server/server/plugins/engine/unavailable-response.js.map +1 -1
  198. package/.server/server/plugins/engine/views/components/_location-field-base.html +4 -2
  199. package/.server/server/plugins/engine/views/components/fileuploadfield.html +1 -1
  200. package/.server/server/plugins/engine/views/components/geospatialfield.html +1 -0
  201. package/.server/server/plugins/engine/views/components/multilinetextfield.html +12 -1
  202. package/.server/server/plugins/engine/views/components/osgridreffield.html +4 -1
  203. package/.server/server/plugins/engine/views/components/paymentfield.html +1 -1
  204. package/.server/server/plugins/engine/views/components/ukaddressfield.html +1 -1
  205. package/.server/server/plugins/engine/views/file-upload.html +1 -1
  206. package/.server/server/plugins/engine/views/partials/preview-banner.html +3 -1
  207. package/.server/server/plugins/engine/views/unavailable.html +14 -11
  208. package/.server/server/plugins/nunjucks/filters/applyUrlParam.d.ts +9 -0
  209. package/.server/server/plugins/nunjucks/filters/applyUrlParam.js +17 -0
  210. package/.server/server/plugins/nunjucks/filters/applyUrlParam.js.map +1 -0
  211. package/.server/server/plugins/nunjucks/filters/applyUrlParam.test.js +17 -0
  212. package/.server/server/plugins/nunjucks/filters/applyUrlParam.test.js.map +1 -0
  213. package/.server/server/plugins/nunjucks/filters/field.d.ts +1 -1
  214. package/.server/server/plugins/nunjucks/filters/index.d.ts +1 -0
  215. package/.server/server/plugins/nunjucks/filters/index.js +1 -0
  216. package/.server/server/plugins/nunjucks/filters/index.js.map +1 -1
  217. package/.server/server/plugins/payment/helper.d.ts +11 -1
  218. package/.server/server/plugins/payment/helper.js +18 -2
  219. package/.server/server/plugins/payment/helper.js.map +1 -1
  220. package/.server/server/plugins/payment/helper.test.js +2 -1
  221. package/.server/server/plugins/payment/helper.test.js.map +1 -1
  222. package/.server/server/plugins/payment/service.d.ts +2 -1
  223. package/.server/server/plugins/payment/service.js +5 -2
  224. package/.server/server/plugins/payment/service.js.map +1 -1
  225. package/.server/server/plugins/payment/service.test.js +7 -3
  226. package/.server/server/plugins/payment/service.test.js.map +1 -1
  227. package/.server/server/plugins/payment/types.d.ts +4 -0
  228. package/.server/server/plugins/payment/types.js +1 -0
  229. package/.server/server/plugins/payment/types.js.map +1 -1
  230. package/.server/server/plugins/postcode-lookup/models/index.d.ts +249 -3
  231. package/.server/server/plugins/postcode-lookup/models/index.js +87 -33
  232. package/.server/server/plugins/postcode-lookup/models/index.js.map +1 -1
  233. package/.server/server/plugins/postcode-lookup/routes/index.d.ts +15 -1
  234. package/.server/server/plugins/postcode-lookup/routes/index.js +47 -15
  235. package/.server/server/plugins/postcode-lookup/routes/index.js.map +1 -1
  236. package/.server/server/plugins/postcode-lookup/routes/index.test.js +84 -0
  237. package/.server/server/plugins/postcode-lookup/routes/index.test.js.map +1 -0
  238. package/.server/server/plugins/postcode-lookup/types.d.ts +12 -0
  239. package/.server/server/plugins/postcode-lookup/types.js +6 -1
  240. package/.server/server/plugins/postcode-lookup/types.js.map +1 -1
  241. package/.server/server/plugins/postcode-lookup/views/postcode-lookup-details.html +3 -3
  242. package/.server/server/utils/type-utils.d.ts +1 -2
  243. package/.server/server/utils/type-utils.js +0 -3
  244. package/.server/server/utils/type-utils.js.map +1 -1
  245. package/.server/server/utils/utils.d.ts +6 -0
  246. package/.server/server/utils/utils.js +18 -1
  247. package/.server/server/utils/utils.js.map +1 -1
  248. package/.server/server/utils/utils.test.js +21 -1
  249. package/.server/server/utils/utils.test.js.map +1 -1
  250. package/package.json +20 -5
  251. package/src/client/javascripts/file-upload.js +11 -3
  252. package/src/client/javascripts/geospatial-map.js +176 -81
  253. package/src/client/javascripts/govuk.js +2 -0
  254. package/src/client/javascripts/location-map.js +60 -4
  255. package/src/client/javascripts/map-constants.js +3 -0
  256. package/src/client/javascripts/map.js +47 -0
  257. package/src/client/javascripts/maps.js +5 -0
  258. package/src/client/javascripts/shared.js +1 -4
  259. package/src/client/javascripts/sssi-dataset.js +39 -41
  260. package/src/client/stylesheets/maps.scss +4 -0
  261. package/src/client/stylesheets/shared.scss +1 -5
  262. package/src/server/constants.js +2 -0
  263. package/src/server/plugins/engine/__stubs__/definitions.ts +155 -0
  264. package/src/server/plugins/engine/components/AutocompleteField.ts +13 -0
  265. package/src/server/plugins/engine/components/CheckboxesField.ts +38 -5
  266. package/src/server/plugins/engine/components/ComponentBase.ts +2 -0
  267. package/src/server/plugins/engine/components/ComponentCollection.ts +16 -11
  268. package/src/server/plugins/engine/components/DatePartsField.ts +20 -9
  269. package/src/server/plugins/engine/components/DeclarationField.ts +7 -6
  270. package/src/server/plugins/engine/components/EastingNorthingField.ts +185 -89
  271. package/src/server/plugins/engine/components/EmailAddressField.ts +2 -1
  272. package/src/server/plugins/engine/components/FileUploadField.ts +44 -3
  273. package/src/server/plugins/engine/components/FormComponent.ts +6 -5
  274. package/src/server/plugins/engine/components/GeospatialField.ts +47 -9
  275. package/src/server/plugins/engine/components/LatLongField.ts +128 -58
  276. package/src/server/plugins/engine/components/LocationFieldBase.ts +30 -7
  277. package/src/server/plugins/engine/components/LocationFieldHelpers.ts +28 -14
  278. package/src/server/plugins/engine/components/Markdown.ts +2 -3
  279. package/src/server/plugins/engine/components/MonthYearField.ts +20 -15
  280. package/src/server/plugins/engine/components/NationalGridFieldNumberField.ts +9 -3
  281. package/src/server/plugins/engine/components/NumberField.ts +21 -1
  282. package/src/server/plugins/engine/components/OsGridRefField.ts +22 -3
  283. package/src/server/plugins/engine/components/PaymentField.ts +15 -5
  284. package/src/server/plugins/engine/components/UkAddressField.ts +30 -7
  285. package/src/server/plugins/engine/components/YesNoField.ts +17 -9
  286. package/src/server/plugins/engine/components/helpers/components.ts +3 -3
  287. package/src/server/plugins/engine/components/helpers/geospatial.ts +84 -21
  288. package/src/server/plugins/engine/components/helpers/index.ts +19 -0
  289. package/src/server/plugins/engine/components/types.ts +1 -0
  290. package/src/server/plugins/engine/errors.ts +78 -0
  291. package/src/server/plugins/engine/form-availability.ts +8 -2
  292. package/src/server/plugins/engine/form-context.ts +4 -2
  293. package/src/server/plugins/engine/helpers.ts +52 -5
  294. package/src/server/plugins/engine/i18n/buildValidationMessages.ts +16 -8
  295. package/src/server/plugins/engine/i18n/createFormTranslator.ts +62 -11
  296. package/src/server/plugins/engine/i18n/extractBaseTranslations.ts +7 -1
  297. package/src/server/plugins/engine/i18n/form.ts +54 -0
  298. package/src/server/plugins/engine/i18n/languages.ts +19 -0
  299. package/src/server/plugins/engine/i18n/translations/cy.json +192 -9
  300. package/src/server/plugins/engine/i18n/translations/en-GB.json +125 -7
  301. package/src/server/plugins/engine/i18n/types.ts +3 -0
  302. package/src/server/plugins/engine/index.ts +7 -0
  303. package/src/server/plugins/engine/models/FormModel.ts +21 -17
  304. package/src/server/plugins/engine/models/SummaryViewModel.ts +6 -5
  305. package/src/server/plugins/engine/models/unavailable-view-model.ts +26 -5
  306. package/src/server/plugins/engine/outputFormatters/adapter/v1.ts +3 -6
  307. package/src/server/plugins/engine/outputFormatters/human/v1.ts +2 -1
  308. package/src/server/plugins/engine/outputFormatters/machine/v2.ts +3 -0
  309. package/src/server/plugins/engine/pageControllers/FileUploadPageController.ts +60 -9
  310. package/src/server/plugins/engine/pageControllers/QuestionPageController.ts +10 -5
  311. package/src/server/plugins/engine/pageControllers/RepeatPageController.ts +2 -2
  312. package/src/server/plugins/engine/pageControllers/SummaryPageController.ts +15 -4
  313. package/src/server/plugins/engine/pageControllers/helpers/pages.ts +2 -1
  314. package/src/server/plugins/engine/pageControllers/helpers/submission.ts +6 -3
  315. package/src/server/plugins/engine/pageControllers/validationOptions.ts +29 -4
  316. package/src/server/plugins/engine/types/schema.ts +1 -0
  317. package/src/server/plugins/engine/types.ts +5 -0
  318. package/src/server/plugins/engine/unavailable-response.ts +6 -2
  319. package/src/server/plugins/engine/views/components/_location-field-base.html +4 -2
  320. package/src/server/plugins/engine/views/components/fileuploadfield.html +1 -1
  321. package/src/server/plugins/engine/views/components/geospatialfield.html +1 -0
  322. package/src/server/plugins/engine/views/components/multilinetextfield.html +12 -1
  323. package/src/server/plugins/engine/views/components/osgridreffield.html +4 -1
  324. package/src/server/plugins/engine/views/components/paymentfield.html +1 -1
  325. package/src/server/plugins/engine/views/components/ukaddressfield.html +1 -1
  326. package/src/server/plugins/engine/views/file-upload.html +1 -1
  327. package/src/server/plugins/engine/views/partials/preview-banner.html +3 -1
  328. package/src/server/plugins/engine/views/unavailable.html +14 -11
  329. package/src/server/plugins/nunjucks/filters/applyUrlParam.js +17 -0
  330. package/src/server/plugins/nunjucks/filters/index.js +1 -0
  331. package/src/server/plugins/payment/helper.js +22 -2
  332. package/src/server/plugins/payment/service.js +6 -2
  333. package/src/server/plugins/payment/types.js +1 -0
  334. package/src/server/plugins/postcode-lookup/models/index.js +75 -43
  335. package/src/server/plugins/postcode-lookup/routes/index.js +73 -16
  336. package/src/server/plugins/postcode-lookup/types.js +6 -1
  337. package/src/server/plugins/postcode-lookup/views/postcode-lookup-details.html +3 -3
  338. package/src/server/utils/type-utils.ts +1 -11
  339. package/src/server/utils/utils.js +19 -1
@@ -1 +1 @@
1
- {"version":3,"file":"FileUploadField.js","names":["Boom","joi","FormComponent","isUploadState","InvalidComponentStateError","messageTemplate","FileStatus","UploadStatus","render","resolveLanguage","uploadIdSchema","string","uuid","required","fileSchema","object","fileId","filename","contentLength","number","tempFileSchema","append","fileStatus","valid","complete","rejected","pending","errorMessage","optional","formFileSchema","metadataSchema","keys","retrievalKey","email","tempStatusSchema","uploadStatus","ready","metadata","form","file","array","items","single","numberOfRejectedFiles","formStatusSchema","itemSchema","uploadId","tempItemSchema","status","formItemSchema","FileUploadField","constructor","def","props","options","schema","formSchema","label","length","max","min","stateSchema","default","allow","getFormValueFromState","state","name","getFormValue","value","isValue","undefined","getDisplayStringFromFormValue","files","translator","t","count","getDisplayStringFromState","getContextValueFromFormValue","map","getContextValueFromState","getViewModel","context","errors","isForceAccess","page","viewModel","attributes","id","filtered","filter","rows","item","index","tag","classes","text","valueHtml","view","params","trim","keyHtml","path","href","getHref","push","visuallyHiddenText","key","html","actions","accept","allowsMultiple","summaryList","multiple","upload","getAllPossibleErrors","onSubmit","request","language","model","createTranslator","notificationEmail","Error","app","services","formSubmissionService","values","initiatedRetrievalKey","persistFiles","error","isBoom","output","statusCode","baseErrors","type","template","selectRequired","advancedSettingsErrors"],"sources":["../../../../../src/server/plugins/engine/components/FileUploadField.ts"],"sourcesContent":["import {\n type FileUploadFieldComponent,\n type FormMetadata\n} from '@defra/forms-model'\nimport Boom from '@hapi/boom'\nimport joi, { type ArraySchema } from 'joi'\n\nimport {\n FormComponent,\n isUploadState\n} from '~/src/server/plugins/engine/components/FormComponent.js'\nimport { type RenderContext } from '~/src/server/plugins/engine/components/types.js'\nimport { type Translator } from '~/src/server/plugins/engine/i18n/types.js'\nimport { InvalidComponentStateError } from '~/src/server/plugins/engine/pageControllers/errors.js'\nimport { messageTemplate } from '~/src/server/plugins/engine/pageControllers/validationOptions.js'\nimport {\n FileStatus,\n UploadStatus,\n type ErrorMessageTemplateList,\n type FileState,\n type FileUpload,\n type FileUploadMetadata,\n type FormContext,\n type FormState,\n type FormStateValue,\n type FormSubmissionState,\n type SummaryList,\n type SummaryListAction,\n type SummaryListRow,\n type UploadState,\n type UploadStatusFileResponse,\n type UploadStatusResponse\n} from '~/src/server/plugins/engine/types.js'\nimport { render } from '~/src/server/plugins/nunjucks/index.js'\nimport { type FormRequestPayload } from '~/src/server/routes/types.js'\nimport { resolveLanguage } from '~/src/server/utils/utils.js'\n\nexport const uploadIdSchema = joi.string().uuid().required()\n\nexport const fileSchema = joi\n .object<FileUpload>({\n fileId: joi.string().uuid().required(),\n filename: joi.string().required(),\n contentLength: joi.number().required()\n })\n .required()\n\nexport const tempFileSchema = fileSchema.append({\n fileStatus: joi\n .string()\n .valid(FileStatus.complete, FileStatus.rejected, FileStatus.pending)\n .required(),\n errorMessage: joi.string().optional()\n})\n\nexport const formFileSchema = fileSchema.append({\n fileStatus: joi.string().valid(FileStatus.complete).required()\n})\n\nexport const metadataSchema = joi\n .object<FileUploadMetadata>()\n .keys({\n retrievalKey: joi.string().email().required()\n })\n .required()\n\nexport const tempStatusSchema = joi\n .object<UploadStatusFileResponse>({\n uploadStatus: joi\n .string()\n .valid(UploadStatus.ready, UploadStatus.pending)\n .required(),\n metadata: metadataSchema,\n form: joi\n .object()\n .required()\n .keys({\n file: joi.array().items(tempFileSchema).single().required()\n }),\n numberOfRejectedFiles: joi.number().optional()\n })\n .required()\n\nexport const formStatusSchema = joi\n .object<UploadStatusResponse>({\n uploadStatus: joi.string().valid(UploadStatus.ready).required(),\n metadata: metadataSchema,\n form: joi.object().required().keys({\n file: formFileSchema\n }),\n numberOfRejectedFiles: joi.number().required()\n })\n .required()\n\nexport const itemSchema = joi.object<FileState>({\n uploadId: uploadIdSchema\n})\n\nexport const tempItemSchema = itemSchema.append({\n status: tempStatusSchema\n})\n\nexport const formItemSchema = itemSchema.append({\n status: formStatusSchema\n})\n\nexport class FileUploadField extends FormComponent {\n declare options: FileUploadFieldComponent['options']\n declare schema: FileUploadFieldComponent['schema']\n declare formSchema: ArraySchema<FileState>\n declare stateSchema: ArraySchema<FileState>\n\n constructor(\n def: FileUploadFieldComponent,\n props: ConstructorParameters<typeof FormComponent>[1]\n ) {\n super(def, props)\n\n const { options, schema } = def\n\n let formSchema = joi\n .array<FileState>()\n .label(this.label)\n .single()\n .required()\n\n if (options.required === false) {\n formSchema = formSchema.optional()\n }\n\n if (typeof schema.length !== 'number') {\n if (typeof schema.max === 'number') {\n formSchema = formSchema.max(schema.max)\n }\n\n if (typeof schema.min === 'number') {\n formSchema = formSchema.min(schema.min)\n } else if (options.required !== false) {\n formSchema = formSchema.min(1)\n }\n } else {\n formSchema = formSchema.length(schema.length)\n }\n\n this.formSchema = formSchema.items(formItemSchema)\n this.stateSchema = formSchema\n .items(formItemSchema)\n .default(null)\n .allow(null)\n\n this.options = options\n this.schema = schema\n }\n\n getFormValueFromState(state: FormSubmissionState) {\n const { name } = this\n return this.getFormValue(state[name])\n }\n\n getFormValue(value?: FormStateValue | FormState) {\n return this.isValue(value) ? value : undefined\n }\n\n getDisplayStringFromFormValue(\n files: FileState[] | undefined,\n translator: Translator\n ): string {\n if (!files?.length) {\n return ''\n }\n\n return translator.t('components.fileUploadField.filesCount', {\n count: files.length\n })\n }\n\n getDisplayStringFromState(\n state: FormSubmissionState,\n translator: Translator\n ) {\n const files = this.getFormValueFromState(state)\n\n return this.getDisplayStringFromFormValue(files, translator)\n }\n\n getContextValueFromFormValue(\n files: UploadState | undefined\n ): string[] | null {\n return files?.map(({ status }) => status.form.file.fileId) ?? null\n }\n\n getContextValueFromState(state: FormSubmissionState) {\n const files = this.getFormValueFromState(state)\n return this.getContextValueFromFormValue(files)\n }\n\n getViewModel(context: RenderContext) {\n const { errors, isForceAccess = false } = context\n const { t } = context.translator\n const { options, page, schema } = this\n\n const viewModel = super.getViewModel(context)\n const { attributes, id, value } = viewModel\n\n const files = this.getFormValue(value) ?? []\n const filtered = files.filter(\n (file) => file.status.form.file.fileStatus === FileStatus.complete\n )\n const count = filtered.length\n\n const rows: SummaryListRow[] = filtered.map((item, index) => {\n const { status } = item\n const { form } = status\n const { file } = form\n\n const tag = {\n classes: 'govuk-tag--green',\n text: t('components.fileUploadField.uploaded')\n }\n\n const valueHtml = render\n .view('components/fileuploadfield-value.html', {\n context: { params: { tag } }\n })\n .trim()\n\n const keyHtml = render\n .view('components/fileuploadfield-key.html', {\n context: {\n params: {\n name: file.filename,\n errorMessage: errors && file.errorMessage\n }\n }\n })\n .trim()\n\n const items: SummaryListAction[] = []\n\n // Remove summary list actions from previews\n if (!isForceAccess) {\n const path = `/${file.fileId}/confirm-delete`\n const href = page?.getHref(`${page.path}${path}`) ?? '#'\n\n items.push({\n href,\n text: 'Remove',\n classes: 'govuk-link--no-visited-state',\n attributes: { id: `${id}__${index}` },\n visuallyHiddenText: file.filename\n })\n }\n\n return {\n key: {\n html: keyHtml\n },\n value: {\n html: valueHtml\n },\n actions: {\n items\n }\n } satisfies SummaryListRow\n })\n\n // Set up the `accept` attribute\n if ('accept' in options && options.accept) {\n attributes.accept = options.accept\n }\n\n // Allow multiple file selection when schema permits more than 1 file\n const allowsMultiple = schema.max !== 1 && schema.length !== 1\n\n const summaryList: SummaryList = {\n classes: 'govuk-summary-list--long-key',\n rows\n }\n\n return {\n ...viewModel,\n\n // File input can't have a initial value\n value: '',\n\n // Override the component name we send to CDP\n name: 'file',\n\n // Enable multi-file selection in the file picker\n ...(allowsMultiple && { multiple: true }),\n\n upload: {\n count,\n summaryList\n }\n }\n }\n\n isValue(value?: FormStateValue | FormState): value is UploadState {\n return isUploadState(value)\n }\n\n /**\n * For error preview page that shows all possible errors on a component\n */\n getAllPossibleErrors(): ErrorMessageTemplateList {\n return FileUploadField.getAllPossibleErrors()\n }\n\n async onSubmit(\n request: FormRequestPayload,\n metadata: FormMetadata,\n context: FormContext\n ) {\n const language = resolveLanguage(request)\n const { t } = this.model.createTranslator(language)\n\n const notificationEmail = metadata.notificationEmail\n\n if (!notificationEmail) {\n // this should not happen because notificationEmail is checked further up\n // the chain in SummaryPageController before submitForm is called.\n throw new Error('Unexpected missing notificationEmail in metadata')\n }\n\n if (!request.app.model?.services.formSubmissionService) {\n throw new Error('No form submission service available in app model')\n }\n\n const { formSubmissionService } = request.app.model.services\n const values = this.getFormValueFromState(context.state) ?? []\n\n const files = values.map((value) => ({\n fileId: value.status.form.file.fileId,\n initiatedRetrievalKey: value.status.metadata.retrievalKey\n }))\n\n if (!files.length) {\n return\n }\n\n try {\n await formSubmissionService.persistFiles(files, notificationEmail)\n } catch (error) {\n if (\n Boom.isBoom(error) &&\n (error.output.statusCode === 403 || // Forbidden - retrieval key invalid\n error.output.statusCode === 404 || // Not Found - file not found\n error.output.statusCode === 410) // Gone - file expired (took to long to submit, etc)\n ) {\n // Failed to persist files. We can't recover from this, the only real way we can recover the submissions is\n // by resetting the problematic components and letting the user re-try.\n // Scenarios: file missing from S3, invalid retrieval key (timing problem), etc.\n throw new InvalidComponentStateError(\n this,\n t('components.fileUploadField.uploadFailed')\n )\n }\n\n throw error\n }\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: 'selectRequired', template: messageTemplate.selectRequired },\n {\n type: 'filesMimes',\n template: 'The selected file must be a {{#limit}}'\n },\n {\n type: 'filesSize',\n template: 'The selected file must be smaller than 100MB'\n },\n { type: 'filesEmpty', template: 'The selected file is empty' },\n { type: 'filesVirus', template: 'The selected file contains a virus' },\n {\n type: 'filesPartial',\n template: 'The selected file has not fully uploaded'\n },\n {\n type: 'filesError',\n template: 'The selected file could not be uploaded – try again'\n }\n ],\n advancedSettingsErrors: [\n {\n type: 'filesMin',\n template: 'You must upload {{#limit}} files or more'\n },\n {\n type: 'filesMax',\n template: 'You can only upload {{#limit}} files or less'\n },\n {\n type: 'filesExact',\n template: 'You must upload exactly {{#limit}} files'\n }\n ]\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"FileUploadField.js","names":["Boom","joi","EN_GB","FormComponent","isUploadState","t","tPlugin","InvalidComponentStateError","messageTemplate","FileStatus","UploadStatus","render","resolveLanguage","uploadIdSchema","string","uuid","required","fileSchema","object","fileId","filename","contentLength","number","tempFileSchema","append","fileStatus","valid","complete","rejected","pending","errorMessage","optional","errorCode","errorParams","any","formFileSchema","metadataSchema","keys","retrievalKey","email","tempStatusSchema","uploadStatus","ready","metadata","form","file","array","items","single","numberOfRejectedFiles","formStatusSchema","itemSchema","uploadId","tempItemSchema","status","formItemSchema","FileUploadField","constructor","def","props","options","schema","formSchema","label","limits","length","max","min","messages","buildErrorMessages","stateSchema","default","allow","getFormValueFromState","state","name","getFormValue","value","isValue","undefined","getDisplayStringFromFormValue","files","translator","count","getDisplayStringFromState","getContextValueFromFormValue","map","getContextValueFromState","getViewModel","context","errors","isForceAccess","page","viewModel","attributes","id","filtered","filter","rows","item","index","tag","classes","text","valueHtml","view","params","trim","keyHtml","path","href","getHref","push","visuallyHiddenText","key","html","actions","accept","allowsMultiple","summaryList","multiple","upload","getValidationMessagesOverride","language","getAllPossibleErrors","onSubmit","request","model","createTranslator","notificationEmail","Error","app","services","formSubmissionService","values","initiatedRetrievalKey","persistFiles","error","isBoom","output","statusCode","baseErrors","type","template","selectRequired","advancedSettingsErrors"],"sources":["../../../../../src/server/plugins/engine/components/FileUploadField.ts"],"sourcesContent":["import {\n type FileUploadFieldComponent,\n type FormMetadata\n} from '@defra/forms-model'\nimport Boom from '@hapi/boom'\nimport joi, { type ArraySchema } from 'joi'\n\nimport { EN_GB } from '~/src/server/constants.js'\nimport {\n FormComponent,\n isUploadState\n} from '~/src/server/plugins/engine/components/FormComponent.js'\nimport { type RenderContext } from '~/src/server/plugins/engine/components/types.js'\nimport { t as tPlugin } from '~/src/server/plugins/engine/i18n/index.js'\nimport { type Translator } from '~/src/server/plugins/engine/i18n/types.js'\nimport { InvalidComponentStateError } from '~/src/server/plugins/engine/pageControllers/errors.js'\nimport { messageTemplate } from '~/src/server/plugins/engine/pageControllers/validationOptions.js'\nimport {\n FileStatus,\n UploadStatus,\n type ErrorMessageTemplateList,\n type FileState,\n type FileUpload,\n type FileUploadMetadata,\n type FormContext,\n type FormState,\n type FormStateValue,\n type FormSubmissionState,\n type SummaryList,\n type SummaryListAction,\n type SummaryListRow,\n type UploadState,\n type UploadStatusFileResponse,\n type UploadStatusResponse\n} from '~/src/server/plugins/engine/types.js'\nimport { render } from '~/src/server/plugins/nunjucks/index.js'\nimport { type FormRequestPayload } from '~/src/server/routes/types.js'\nimport { resolveLanguage } from '~/src/server/utils/utils.js'\n\nexport const uploadIdSchema = joi.string().uuid().required()\n\nexport const fileSchema = joi\n .object<FileUpload>({\n fileId: joi.string().uuid().required(),\n filename: joi.string().required(),\n contentLength: joi.number().required()\n })\n .required()\n\nexport const tempFileSchema = fileSchema.append({\n fileStatus: joi\n .string()\n .valid(FileStatus.complete, FileStatus.rejected, FileStatus.pending)\n .required(),\n errorMessage: joi.string().optional(),\n errorCode: joi.string().optional(),\n errorParams: joi.any().optional()\n})\n\nexport const formFileSchema = fileSchema.append({\n fileStatus: joi.string().valid(FileStatus.complete).required()\n})\n\nexport const metadataSchema = joi\n .object<FileUploadMetadata>()\n .keys({\n retrievalKey: joi.string().email().required()\n })\n .required()\n\nexport const tempStatusSchema = joi\n .object<UploadStatusFileResponse>({\n uploadStatus: joi\n .string()\n .valid(UploadStatus.ready, UploadStatus.pending)\n .required(),\n metadata: metadataSchema,\n form: joi\n .object()\n .required()\n .keys({\n file: joi.array().items(tempFileSchema).single().required()\n }),\n numberOfRejectedFiles: joi.number().optional()\n })\n .required()\n\nexport const formStatusSchema = joi\n .object<UploadStatusResponse>({\n uploadStatus: joi.string().valid(UploadStatus.ready).required(),\n metadata: metadataSchema,\n form: joi.object().required().keys({\n file: formFileSchema\n }),\n numberOfRejectedFiles: joi.number().required()\n })\n .required()\n\nexport const itemSchema = joi.object<FileState>({\n uploadId: uploadIdSchema\n})\n\nexport const tempItemSchema = itemSchema.append({\n status: tempStatusSchema\n})\n\nexport const formItemSchema = itemSchema.append({\n status: formStatusSchema\n})\n\nexport class FileUploadField extends FormComponent {\n declare options: FileUploadFieldComponent['options']\n declare schema: FileUploadFieldComponent['schema']\n declare formSchema: ArraySchema<FileState>\n declare stateSchema: ArraySchema<FileState>\n declare limits: { min?: number; max?: number; length?: number }\n\n constructor(\n def: FileUploadFieldComponent,\n props: ConstructorParameters<typeof FormComponent>[1]\n ) {\n super(def, props)\n\n const { options, schema } = def\n\n let formSchema = joi\n .array<FileState>()\n .label(this.label)\n .single()\n .required()\n\n if (options.required === false) {\n formSchema = formSchema.optional()\n }\n\n const limits: { min?: number; max?: number; length?: number } = {}\n\n if (typeof schema.length !== 'number') {\n if (typeof schema.max === 'number') {\n formSchema = formSchema.max(schema.max)\n limits.max = schema.max\n }\n\n if (typeof schema.min === 'number') {\n formSchema = formSchema.min(schema.min)\n limits.min = schema.min\n } else if (options.required !== false) {\n formSchema = formSchema.min(1)\n limits.min = 1\n }\n } else {\n formSchema = formSchema.length(schema.length)\n limits.length = schema.length\n }\n\n this.limits = limits\n\n formSchema = formSchema.messages(\n FileUploadField.buildErrorMessages(EN_GB, limits)\n )\n\n this.formSchema = formSchema.items(formItemSchema)\n this.stateSchema = formSchema\n .items(formItemSchema)\n .default(null)\n .allow(null)\n\n this.options = options\n this.schema = schema\n }\n\n getFormValueFromState(state: FormSubmissionState) {\n const { name } = this\n return this.getFormValue(state[name])\n }\n\n getFormValue(value?: FormStateValue | FormState) {\n return this.isValue(value) ? value : undefined\n }\n\n getDisplayStringFromFormValue(\n files: FileState[] | undefined,\n translator: Translator\n ): string {\n if (!files?.length) {\n return ''\n }\n\n return translator.t('pages.summary.fileUpload', {\n count: files.length\n })\n }\n\n getDisplayStringFromState(\n state: FormSubmissionState,\n translator: Translator\n ) {\n const files = this.getFormValueFromState(state)\n\n return this.getDisplayStringFromFormValue(files, translator)\n }\n\n getContextValueFromFormValue(\n files: UploadState | undefined\n ): string[] | null {\n return files?.map(({ status }) => status.form.file.fileId) ?? null\n }\n\n getContextValueFromState(state: FormSubmissionState) {\n const files = this.getFormValueFromState(state)\n return this.getContextValueFromFormValue(files)\n }\n\n getViewModel(context: RenderContext) {\n const { errors, isForceAccess = false } = context\n const { t } = context.translator\n const { options, page, schema } = this\n\n const viewModel = super.getViewModel(context)\n const { attributes, id, value } = viewModel\n\n const files = this.getFormValue(value) ?? []\n const filtered = files.filter(\n (file) => file.status.form.file.fileStatus === FileStatus.complete\n )\n const count = filtered.length\n\n const rows: SummaryListRow[] = filtered.map((item, index) => {\n const { status } = item\n const { form } = status\n const { file } = form\n\n const tag = {\n classes: 'govuk-tag--green',\n text: t('components.fileUploadField.uploaded')\n }\n\n const valueHtml = render\n .view('components/fileuploadfield-value.html', {\n context: { params: { tag } }\n })\n .trim()\n\n const keyHtml = render\n .view('components/fileuploadfield-key.html', {\n context: {\n params: {\n name: file.filename,\n errorMessage: errors && file.errorMessage\n }\n }\n })\n .trim()\n\n const items: SummaryListAction[] = []\n\n // Remove summary list actions from previews\n if (!isForceAccess) {\n const path = `/${file.fileId}/confirm-delete`\n const href = page?.getHref(`${page.path}${path}`) ?? '#'\n\n items.push({\n href,\n text: t('pages.fileUpload.remove'),\n classes: 'govuk-link--no-visited-state',\n attributes: { id: `${id}__${index}` },\n visuallyHiddenText: file.filename\n })\n }\n\n return {\n key: {\n html: keyHtml\n },\n value: {\n html: valueHtml\n },\n actions: {\n items\n }\n } satisfies SummaryListRow\n })\n\n // Set up the `accept` attribute\n if ('accept' in options && options.accept) {\n attributes.accept = options.accept\n }\n\n // Allow multiple file selection when schema permits more than 1 file\n const allowsMultiple = schema.max !== 1 && schema.length !== 1\n\n const summaryList: SummaryList = {\n classes: 'govuk-summary-list--long-key',\n rows\n }\n\n return {\n ...viewModel,\n\n // File input can't have a initial value\n value: '',\n\n // Override the component name we send to CDP\n name: 'file',\n\n // Enable multi-file selection in the file picker\n ...(allowsMultiple && { multiple: true }),\n\n upload: {\n count,\n summaryList\n }\n }\n }\n\n isValue(value?: FormStateValue | FormState): value is UploadState {\n return isUploadState(value)\n }\n\n getValidationMessagesOverride(translator: Translator) {\n const { language } = translator\n return {\n [this.name]: FileUploadField.buildErrorMessages(language, this.limits)\n }\n }\n\n /**\n * For error preview page that shows all possible errors on a component\n */\n getAllPossibleErrors(): ErrorMessageTemplateList {\n return FileUploadField.getAllPossibleErrors()\n }\n\n async onSubmit(\n request: FormRequestPayload,\n metadata: FormMetadata,\n context: FormContext\n ) {\n const language = resolveLanguage(request)\n const { t } = this.model.createTranslator(language)\n\n const notificationEmail = metadata.notificationEmail\n\n if (!notificationEmail) {\n // this should not happen because notificationEmail is checked further up\n // the chain in SummaryPageController before submitForm is called.\n throw new Error('Unexpected missing notificationEmail in metadata')\n }\n\n if (!request.app.model?.services.formSubmissionService) {\n throw new Error('No form submission service available in app model')\n }\n\n const { formSubmissionService } = request.app.model.services\n const values = this.getFormValueFromState(context.state) ?? []\n\n const files = values.map((value) => ({\n fileId: value.status.form.file.fileId,\n initiatedRetrievalKey: value.status.metadata.retrievalKey\n }))\n\n if (!files.length) {\n return\n }\n\n try {\n await formSubmissionService.persistFiles(files, notificationEmail)\n } catch (error) {\n if (\n Boom.isBoom(error) &&\n (error.output.statusCode === 403 || // Forbidden - retrieval key invalid\n error.output.statusCode === 404 || // Not Found - file not found\n error.output.statusCode === 410) // Gone - file expired (took to long to submit, etc)\n ) {\n // Failed to persist files. We can't recover from this, the only real way we can recover the submissions is\n // by resetting the problematic components and letting the user re-try.\n // Scenarios: file missing from S3, invalid retrieval key (timing problem), etc.\n throw new InvalidComponentStateError(\n this,\n t('components.fileUploadField.uploadFailed')\n )\n }\n\n throw error\n }\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: 'selectRequired', template: messageTemplate.selectRequired },\n {\n type: 'filesMimes',\n template: 'The selected file must be a {{#limit}}'\n },\n {\n type: 'filesSize',\n template: 'The selected file must be smaller than 100MB'\n },\n { type: 'filesEmpty', template: 'The selected file is empty' },\n { type: 'filesVirus', template: 'The selected file contains a virus' },\n {\n type: 'filesPartial',\n template: 'The selected file has not fully uploaded'\n },\n {\n type: 'filesError',\n template: 'The selected file could not be uploaded – try again'\n }\n ],\n advancedSettingsErrors: [\n {\n type: 'filesMin',\n template: 'You must upload {{#limit}} files or more'\n },\n {\n type: 'filesMax',\n template: 'You can only upload {{#limit}} files or less'\n },\n {\n type: 'filesExact',\n template: 'You must upload exactly {{#limit}} files'\n }\n ]\n }\n }\n\n static buildErrorMessages(\n language: string,\n limits: { min?: number; max?: number; length?: number } = {}\n ) {\n return {\n 'array.min': tPlugin('validation.filesMin', language, {\n count: limits.min ?? 1\n }),\n 'array.max': tPlugin('validation.filesMax', language, {\n count: limits.max ?? 1\n }),\n 'array.length': tPlugin('validation.filesLength', language, {\n count: limits.length ?? 1\n })\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -27,8 +27,11 @@ export declare class FormComponent extends ComponentBase {
27
27
  * Override in composite fields to return translated Joi message overrides for
28
28
  * their sub-fields, applied at validation time so schema-level English messages
29
29
  * are replaced with the correct language. Return null to skip message patching.
30
+ * The return object may contain message overrides at component-level, or sub-field-level.
31
+ * This would allow different error message overrides per field within a collection e.g.
32
+ * for EastingNothingField
30
33
  */
31
- getValidationMessagesOverride(_translator: Translator): LanguageMessages | null;
34
+ getValidationMessagesOverride(_translator: Translator): Record<string, LanguageMessages> | null;
32
35
  getViewModel({ payload, errors, translator, isForceAccess: _isForceAccess }: RenderContext): {
33
36
  label: {
34
37
  text: string;
@@ -76,6 +79,7 @@ export declare class FormComponent extends ComponentBase {
76
79
  upload?: {
77
80
  count: number;
78
81
  summaryList: import("../../../../server/plugins/engine/types.js").SummaryList;
82
+ uploadingLabel?: string;
79
83
  };
80
84
  };
81
85
  getDisplayStringFromFormValue(value: FormValue | FormPayload, _translator: Translator): string;
@@ -105,6 +105,9 @@ export class FormComponent extends ComponentBase {
105
105
  * Override in composite fields to return translated Joi message overrides for
106
106
  * their sub-fields, applied at validation time so schema-level English messages
107
107
  * are replaced with the correct language. Return null to skip message patching.
108
+ * The return object may contain message overrides at component-level, or sub-field-level.
109
+ * This would allow different error message overrides per field within a collection e.g.
110
+ * for EastingNothingField
108
111
  */
109
112
  getValidationMessagesOverride(_translator) {
110
113
  return null;
@@ -128,12 +131,12 @@ export class FormComponent extends ComponentBase {
128
131
  } = translator;
129
132
  const isRequired = !('required' in options) || options.required !== false;
130
133
  const hideOptional = 'optionalText' in options && options.optionalText;
131
- const resolvedTitle = tComponent(this, 'title') || title;
134
+ const resolvedTitle = tComponent(this.def, 'title') || title;
132
135
  const optionalTag = !isRequired && !hideOptional ? ` ${t('common.optional')}` : '';
133
136
  const label = `${resolvedTitle}${optionalTag}`;
134
137
  if (hint) {
135
138
  viewModel.hint = {
136
- text: tComponent(this, 'hint') || hint
139
+ text: tComponent(this.def, 'hint') || hint
137
140
  };
138
141
  }
139
142
 
@@ -1 +1 @@
1
- {"version":3,"file":"FormComponent.js","names":["ComponentBase","FormComponent","type","hint","label","summaryLabel","isFormComponent","isAppendageStateSingleObject","constructor","def","props","getLabel","getSummaryLabel","errorDescription","shortDescription","title","keys","collection","name","fields","map","getFormDataFromState","state","getFormValue","getFormValueFromState","value","isValue","undefined","getStateFromValidForm","payload","getErrors","_translator","errors","list","filter","error","path","includes","length","getFirstError","translator","getViewErrors","firstError","getValidationMessagesOverride","getViewModel","isForceAccess","_isForceAccess","options","viewModel","t","tComponent","isRequired","required","hideOptional","optionalText","resolvedTitle","optionalTag","text","componentErrors","componentError","errorMessage","id","getDisplayStringFromFormValue","toString","getDisplayStringFromState","getContextValueFromFormValue","isState","values","Object","isFormValue","Array","isArray","getContextValueFromState","isFormState","getAllPossibleErrors","baseErrors","advancedSettingsErrors","onSubmit","_request","_metadata","_context","Promise","resolve","isRepeatState","every","isRepeatValue","itemId","isUploadState","isUploadValue","isGeospatialState","isGeospatialValue","uploadId"],"sources":["../../../../../src/server/plugins/engine/components/FormComponent.ts"],"sourcesContent":["import {\n type ComponentDef,\n type FormComponentsDef,\n type FormMetadata,\n type Item\n} from '@defra/forms-model'\nimport { type LanguageMessages } from 'joi'\n\nimport { ComponentBase } from '~/src/server/plugins/engine/components/ComponentBase.js'\nimport { type RenderContext } from '~/src/server/plugins/engine/components/types.js'\nimport { type Translator } from '~/src/server/plugins/engine/i18n/types.js'\nimport {\n type FormContext,\n type FormRequestPayload\n} from '~/src/server/plugins/engine/types/index.js'\nimport {\n type ErrorMessageTemplateList,\n type Feature,\n type FileState,\n type FormPayload,\n type FormState,\n type FormStateValue,\n type FormSubmissionError,\n type FormSubmissionState,\n type FormValue,\n type GeospatialState,\n type RepeatItemState,\n type RepeatListState,\n type UploadState\n} from '~/src/server/plugins/engine/types.js'\n\nexport class FormComponent extends ComponentBase {\n type: FormComponentsDef['type']\n hint: FormComponentsDef['hint']\n label: string\n summaryLabel: string\n\n isFormComponent = true\n isAppendageStateSingleObject = false\n\n constructor(\n def: FormComponentsDef,\n props: ConstructorParameters<typeof ComponentBase>[1]\n ) {\n super(def, props)\n\n const { hint, type } = def\n\n this.type = type\n this.hint = hint\n\n this.label = this.getLabel(def)\n this.summaryLabel = this.getSummaryLabel(def)\n }\n\n getLabel(def: FormComponentsDef) {\n if ('errorDescription' in def && def.errorDescription) {\n return def.errorDescription\n }\n\n return this.getSummaryLabel(def)\n }\n\n getSummaryLabel(def: FormComponentsDef) {\n if ('shortDescription' in def && def.shortDescription) {\n return def.shortDescription\n }\n\n return def.title\n }\n\n get keys() {\n const { collection, name } = this\n\n if (collection) {\n const { fields } = collection\n return [name, ...fields.map(({ name }) => name)]\n }\n\n return [name]\n }\n\n getFormDataFromState(state: FormSubmissionState): FormPayload {\n const { collection, name } = this\n\n if (collection) {\n return collection.getFormDataFromState(state)\n }\n\n return {\n [name]: this.getFormValue(state[name])\n }\n }\n\n getFormValueFromState(state: FormSubmissionState): FormValue | FormPayload {\n const { collection, name } = this\n\n if (collection) {\n return collection.getFormValueFromState(state)\n }\n\n return this.getFormValue(state[name])\n }\n\n getFormValue(value?: FormStateValue | FormState) {\n return this.isValue(value) ? value : undefined\n }\n\n getStateFromValidForm(payload: FormPayload): FormState {\n const { collection, name } = this\n\n if (collection) {\n return collection.getStateFromValidForm(payload)\n }\n\n return {\n [name]: this.getFormValue(payload[name]) ?? null\n }\n }\n\n getErrors(\n _translator: Translator,\n errors?: FormSubmissionError[]\n ): FormSubmissionError[] | undefined {\n const { name } = this\n\n // Filter component and child errors only\n const list = errors?.filter(\n (error) =>\n error.name === name ||\n error.path.includes(name) ||\n this.keys.includes(error.name)\n )\n\n if (!list?.length) {\n return\n }\n\n return list\n }\n\n getFirstError(\n translator: Translator,\n errors?: FormSubmissionError[]\n ): FormSubmissionError | undefined {\n return this.getErrors(translator, errors)?.[0]\n }\n\n getViewErrors(\n translator: Translator,\n errors?: FormSubmissionError[]\n ): FormSubmissionError[] | undefined {\n const firstError = this.getFirstError(translator, errors)\n return firstError && [firstError]\n }\n\n /**\n * Override in composite fields to return translated Joi message overrides for\n * their sub-fields, applied at validation time so schema-level English messages\n * are replaced with the correct language. Return null to skip message patching.\n */\n getValidationMessagesOverride(\n _translator: Translator\n ): LanguageMessages | null {\n return null\n }\n\n getViewModel({\n payload,\n errors,\n translator,\n isForceAccess: _isForceAccess = false\n }: RenderContext) {\n const { hint, name, options = {}, title, viewModel } = this\n\n const { t, tComponent } = translator\n\n const isRequired = !('required' in options) || options.required !== false\n const hideOptional = 'optionalText' in options && options.optionalText\n\n const resolvedTitle =\n tComponent(this as unknown as ComponentDef, 'title') || title\n const optionalTag =\n !isRequired && !hideOptional ? ` ${t('common.optional')}` : ''\n const label = `${resolvedTitle}${optionalTag}`\n\n if (hint) {\n viewModel.hint = {\n text: tComponent(this as unknown as ComponentDef, 'hint') || hint\n }\n }\n\n // Filter component errors only\n const componentErrors = this.getErrors(translator, errors)\n const componentError = this.getFirstError(translator, componentErrors)\n\n if (componentErrors) {\n viewModel.errors = componentErrors\n }\n\n if (componentError) {\n viewModel.errorMessage = {\n text: componentError.text\n }\n }\n\n return {\n ...viewModel,\n label: {\n text: label\n },\n id: name,\n name,\n value: payload[name]\n }\n }\n\n getDisplayStringFromFormValue(\n value: FormValue | FormPayload,\n _translator: Translator\n ): string {\n // Map selected values to text\n // eslint-disable-next-line @typescript-eslint/no-base-to-string\n return this.isValue(value) ? value.toString() : ''\n }\n\n getDisplayStringFromState(\n state: FormSubmissionState,\n translator: Translator\n ): string {\n const value = this.getFormValueFromState(state)\n return this.getDisplayStringFromFormValue(value, translator)\n }\n\n getContextValueFromFormValue(\n value: FormValue | FormPayload\n ): Item['value'] | Item['value'][] | null {\n // Filter object field values\n if (this.isState(value)) {\n const values = Object.values(value).filter(isFormValue)\n return values.length ? values : null\n }\n\n // Filter array field values\n if (this.isValue(value) && Array.isArray(value)) {\n return value.filter(isFormValue)\n }\n\n return this.isValue(value) ? value : null\n }\n\n getContextValueFromState(\n state: FormSubmissionState\n ): Item['value'] | Item['value'][] | null {\n const value = this.getFormValueFromState(state)\n\n return this.getContextValueFromFormValue(value)\n }\n\n isValue(\n value?: FormStateValue | FormState\n ): value is NonNullable<FormStateValue> {\n return isFormValue(value)\n }\n\n isState(value?: FormStateValue | FormState): value is FormState {\n return isFormState(value)\n }\n\n /**\n * For error preview page that shows all possible errors on a component\n */\n getAllPossibleErrors(): ErrorMessageTemplateList {\n return FormComponent.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 advancedSettingsErrors: []\n }\n }\n\n onSubmit(\n _request: FormRequestPayload,\n _metadata: FormMetadata,\n _context: FormContext\n ): Promise<void> {\n return Promise.resolve()\n }\n}\n\n/**\n * Check for form value\n */\nexport function isFormValue(\n value?: unknown\n): value is string | number | boolean {\n return (\n (typeof value === 'string' && value.length > 0) ||\n typeof value === 'number' ||\n typeof value === 'boolean'\n )\n}\n\n/**\n * Check for form state with nested values\n */\nexport function isFormState(value?: unknown): value is FormState {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) {\n return false\n }\n\n // Skip empty objects\n return !!Object.values(value).length\n}\n\n/**\n * Check for repeat list state\n */\nexport function isRepeatState(value?: unknown): value is RepeatListState {\n if (!Array.isArray(value)) {\n return false\n }\n\n // Skip checks when empty\n if (!value.length) {\n return true\n }\n\n return value.every(isRepeatValue)\n}\n\n/**\n * Check for repeat list value\n */\nexport function isRepeatValue(value?: unknown): value is RepeatItemState {\n return isFormState(value) && typeof value.itemId === 'string'\n}\n\n/**\n * Check for upload state\n */\nexport function isUploadState(value?: unknown): value is UploadState {\n if (!Array.isArray(value)) {\n return false\n }\n\n // Skip checks when empty\n if (!value.length) {\n return true\n }\n\n return value.every(isUploadValue)\n}\n\n/**\n * Check for geospatial state\n */\nexport function isGeospatialState(value?: unknown): value is GeospatialState {\n if (!Array.isArray(value)) {\n return false\n }\n\n // Skip checks when empty\n if (!value.length) {\n return true\n }\n\n return value.every(isGeospatialValue)\n}\n\n/**\n * Check for upload state value\n */\nexport function isUploadValue(value?: unknown): value is FileState {\n return isFormState(value) && typeof value.uploadId === 'string'\n}\n\n/**\n * Check for geospatial state value\n */\nexport function isGeospatialValue(value?: unknown): value is Feature {\n return (\n isFormState(value) &&\n typeof value.type === 'string' &&\n value.type === 'Feature'\n )\n}\n"],"mappings":"AAQA,SAASA,aAAa;AAuBtB,OAAO,MAAMC,aAAa,SAASD,aAAa,CAAC;EAC/CE,IAAI;EACJC,IAAI;EACJC,KAAK;EACLC,YAAY;EAEZC,eAAe,GAAG,IAAI;EACtBC,4BAA4B,GAAG,KAAK;EAEpCC,WAAWA,CACTC,GAAsB,EACtBC,KAAqD,EACrD;IACA,KAAK,CAACD,GAAG,EAAEC,KAAK,CAAC;IAEjB,MAAM;MAAEP,IAAI;MAAED;IAAK,CAAC,GAAGO,GAAG;IAE1B,IAAI,CAACP,IAAI,GAAGA,IAAI;IAChB,IAAI,CAACC,IAAI,GAAGA,IAAI;IAEhB,IAAI,CAACC,KAAK,GAAG,IAAI,CAACO,QAAQ,CAACF,GAAG,CAAC;IAC/B,IAAI,CAACJ,YAAY,GAAG,IAAI,CAACO,eAAe,CAACH,GAAG,CAAC;EAC/C;EAEAE,QAAQA,CAACF,GAAsB,EAAE;IAC/B,IAAI,kBAAkB,IAAIA,GAAG,IAAIA,GAAG,CAACI,gBAAgB,EAAE;MACrD,OAAOJ,GAAG,CAACI,gBAAgB;IAC7B;IAEA,OAAO,IAAI,CAACD,eAAe,CAACH,GAAG,CAAC;EAClC;EAEAG,eAAeA,CAACH,GAAsB,EAAE;IACtC,IAAI,kBAAkB,IAAIA,GAAG,IAAIA,GAAG,CAACK,gBAAgB,EAAE;MACrD,OAAOL,GAAG,CAACK,gBAAgB;IAC7B;IAEA,OAAOL,GAAG,CAACM,KAAK;EAClB;EAEA,IAAIC,IAAIA,CAAA,EAAG;IACT,MAAM;MAAEC,UAAU;MAAEC;IAAK,CAAC,GAAG,IAAI;IAEjC,IAAID,UAAU,EAAE;MACd,MAAM;QAAEE;MAAO,CAAC,GAAGF,UAAU;MAC7B,OAAO,CAACC,IAAI,EAAE,GAAGC,MAAM,CAACC,GAAG,CAAC,CAAC;QAAEF;MAAK,CAAC,KAAKA,IAAI,CAAC,CAAC;IAClD;IAEA,OAAO,CAACA,IAAI,CAAC;EACf;EAEAG,oBAAoBA,CAACC,KAA0B,EAAe;IAC5D,MAAM;MAAEL,UAAU;MAAEC;IAAK,CAAC,GAAG,IAAI;IAEjC,IAAID,UAAU,EAAE;MACd,OAAOA,UAAU,CAACI,oBAAoB,CAACC,KAAK,CAAC;IAC/C;IAEA,OAAO;MACL,CAACJ,IAAI,GAAG,IAAI,CAACK,YAAY,CAACD,KAAK,CAACJ,IAAI,CAAC;IACvC,CAAC;EACH;EAEAM,qBAAqBA,CAACF,KAA0B,EAA2B;IACzE,MAAM;MAAEL,UAAU;MAAEC;IAAK,CAAC,GAAG,IAAI;IAEjC,IAAID,UAAU,EAAE;MACd,OAAOA,UAAU,CAACO,qBAAqB,CAACF,KAAK,CAAC;IAChD;IAEA,OAAO,IAAI,CAACC,YAAY,CAACD,KAAK,CAACJ,IAAI,CAAC,CAAC;EACvC;EAEAK,YAAYA,CAACE,KAAkC,EAAE;IAC/C,OAAO,IAAI,CAACC,OAAO,CAACD,KAAK,CAAC,GAAGA,KAAK,GAAGE,SAAS;EAChD;EAEAC,qBAAqBA,CAACC,OAAoB,EAAa;IACrD,MAAM;MAAEZ,UAAU;MAAEC;IAAK,CAAC,GAAG,IAAI;IAEjC,IAAID,UAAU,EAAE;MACd,OAAOA,UAAU,CAACW,qBAAqB,CAACC,OAAO,CAAC;IAClD;IAEA,OAAO;MACL,CAACX,IAAI,GAAG,IAAI,CAACK,YAAY,CAACM,OAAO,CAACX,IAAI,CAAC,CAAC,IAAI;IAC9C,CAAC;EACH;EAEAY,SAASA,CACPC,WAAuB,EACvBC,MAA8B,EACK;IACnC,MAAM;MAAEd;IAAK,CAAC,GAAG,IAAI;;IAErB;IACA,MAAMe,IAAI,GAAGD,MAAM,EAAEE,MAAM,CACxBC,KAAK,IACJA,KAAK,CAACjB,IAAI,KAAKA,IAAI,IACnBiB,KAAK,CAACC,IAAI,CAACC,QAAQ,CAACnB,IAAI,CAAC,IACzB,IAAI,CAACF,IAAI,CAACqB,QAAQ,CAACF,KAAK,CAACjB,IAAI,CACjC,CAAC;IAED,IAAI,CAACe,IAAI,EAAEK,MAAM,EAAE;MACjB;IACF;IAEA,OAAOL,IAAI;EACb;EAEAM,aAAaA,CACXC,UAAsB,EACtBR,MAA8B,EACG;IACjC,OAAO,IAAI,CAACF,SAAS,CAACU,UAAU,EAAER,MAAM,CAAC,GAAG,CAAC,CAAC;EAChD;EAEAS,aAAaA,CACXD,UAAsB,EACtBR,MAA8B,EACK;IACnC,MAAMU,UAAU,GAAG,IAAI,CAACH,aAAa,CAACC,UAAU,EAAER,MAAM,CAAC;IACzD,OAAOU,UAAU,IAAI,CAACA,UAAU,CAAC;EACnC;;EAEA;AACF;AACA;AACA;AACA;EACEC,6BAA6BA,CAC3BZ,WAAuB,EACE;IACzB,OAAO,IAAI;EACb;EAEAa,YAAYA,CAAC;IACXf,OAAO;IACPG,MAAM;IACNQ,UAAU;IACVK,aAAa,EAAEC,cAAc,GAAG;EACnB,CAAC,EAAE;IAChB,MAAM;MAAE3C,IAAI;MAAEe,IAAI;MAAE6B,OAAO,GAAG,CAAC,CAAC;MAAEhC,KAAK;MAAEiC;IAAU,CAAC,GAAG,IAAI;IAE3D,MAAM;MAAEC,CAAC;MAAEC;IAAW,CAAC,GAAGV,UAAU;IAEpC,MAAMW,UAAU,GAAG,EAAE,UAAU,IAAIJ,OAAO,CAAC,IAAIA,OAAO,CAACK,QAAQ,KAAK,KAAK;IACzE,MAAMC,YAAY,GAAG,cAAc,IAAIN,OAAO,IAAIA,OAAO,CAACO,YAAY;IAEtE,MAAMC,aAAa,GACjBL,UAAU,CAAC,IAAI,EAA6B,OAAO,CAAC,IAAInC,KAAK;IAC/D,MAAMyC,WAAW,GACf,CAACL,UAAU,IAAI,CAACE,YAAY,GAAG,IAAIJ,CAAC,CAAC,iBAAiB,CAAC,EAAE,GAAG,EAAE;IAChE,MAAM7C,KAAK,GAAG,GAAGmD,aAAa,GAAGC,WAAW,EAAE;IAE9C,IAAIrD,IAAI,EAAE;MACR6C,SAAS,CAAC7C,IAAI,GAAG;QACfsD,IAAI,EAAEP,UAAU,CAAC,IAAI,EAA6B,MAAM,CAAC,IAAI/C;MAC/D,CAAC;IACH;;IAEA;IACA,MAAMuD,eAAe,GAAG,IAAI,CAAC5B,SAAS,CAACU,UAAU,EAAER,MAAM,CAAC;IAC1D,MAAM2B,cAAc,GAAG,IAAI,CAACpB,aAAa,CAACC,UAAU,EAAEkB,eAAe,CAAC;IAEtE,IAAIA,eAAe,EAAE;MACnBV,SAAS,CAAChB,MAAM,GAAG0B,eAAe;IACpC;IAEA,IAAIC,cAAc,EAAE;MAClBX,SAAS,CAACY,YAAY,GAAG;QACvBH,IAAI,EAAEE,cAAc,CAACF;MACvB,CAAC;IACH;IAEA,OAAO;MACL,GAAGT,SAAS;MACZ5C,KAAK,EAAE;QACLqD,IAAI,EAAErD;MACR,CAAC;MACDyD,EAAE,EAAE3C,IAAI;MACRA,IAAI;MACJO,KAAK,EAAEI,OAAO,CAACX,IAAI;IACrB,CAAC;EACH;EAEA4C,6BAA6BA,CAC3BrC,KAA8B,EAC9BM,WAAuB,EACf;IACR;IACA;IACA,OAAO,IAAI,CAACL,OAAO,CAACD,KAAK,CAAC,GAAGA,KAAK,CAACsC,QAAQ,CAAC,CAAC,GAAG,EAAE;EACpD;EAEAC,yBAAyBA,CACvB1C,KAA0B,EAC1BkB,UAAsB,EACd;IACR,MAAMf,KAAK,GAAG,IAAI,CAACD,qBAAqB,CAACF,KAAK,CAAC;IAC/C,OAAO,IAAI,CAACwC,6BAA6B,CAACrC,KAAK,EAAEe,UAAU,CAAC;EAC9D;EAEAyB,4BAA4BA,CAC1BxC,KAA8B,EACU;IACxC;IACA,IAAI,IAAI,CAACyC,OAAO,CAACzC,KAAK,CAAC,EAAE;MACvB,MAAM0C,MAAM,GAAGC,MAAM,CAACD,MAAM,CAAC1C,KAAK,CAAC,CAACS,MAAM,CAACmC,WAAW,CAAC;MACvD,OAAOF,MAAM,CAAC7B,MAAM,GAAG6B,MAAM,GAAG,IAAI;IACtC;;IAEA;IACA,IAAI,IAAI,CAACzC,OAAO,CAACD,KAAK,CAAC,IAAI6C,KAAK,CAACC,OAAO,CAAC9C,KAAK,CAAC,EAAE;MAC/C,OAAOA,KAAK,CAACS,MAAM,CAACmC,WAAW,CAAC;IAClC;IAEA,OAAO,IAAI,CAAC3C,OAAO,CAACD,KAAK,CAAC,GAAGA,KAAK,GAAG,IAAI;EAC3C;EAEA+C,wBAAwBA,CACtBlD,KAA0B,EACc;IACxC,MAAMG,KAAK,GAAG,IAAI,CAACD,qBAAqB,CAACF,KAAK,CAAC;IAE/C,OAAO,IAAI,CAAC2C,4BAA4B,CAACxC,KAAK,CAAC;EACjD;EAEAC,OAAOA,CACLD,KAAkC,EACI;IACtC,OAAO4C,WAAW,CAAC5C,KAAK,CAAC;EAC3B;EAEAyC,OAAOA,CAACzC,KAAkC,EAAsB;IAC9D,OAAOgD,WAAW,CAAChD,KAAK,CAAC;EAC3B;;EAEA;AACF;AACA;EACEiD,oBAAoBA,CAAA,EAA6B;IAC/C,OAAOzE,aAAa,CAACyE,oBAAoB,CAAC,CAAC;EAC7C;;EAEA;AACF;AACA;EACE,OAAOA,oBAAoBA,CAAA,EAA6B;IACtD,OAAO;MACLC,UAAU,EAAE,EAAE;MACdC,sBAAsB,EAAE;IAC1B,CAAC;EACH;EAEAC,QAAQA,CACNC,QAA4B,EAC5BC,SAAuB,EACvBC,QAAqB,EACN;IACf,OAAOC,OAAO,CAACC,OAAO,CAAC,CAAC;EAC1B;AACF;;AAEA;AACA;AACA;AACA,OAAO,SAASb,WAAWA,CACzB5C,KAAe,EACqB;EACpC,OACG,OAAOA,KAAK,KAAK,QAAQ,IAAIA,KAAK,CAACa,MAAM,GAAG,CAAC,IAC9C,OAAOb,KAAK,KAAK,QAAQ,IACzB,OAAOA,KAAK,KAAK,SAAS;AAE9B;;AAEA;AACA;AACA;AACA,OAAO,SAASgD,WAAWA,CAAChD,KAAe,EAAsB;EAC/D,IAAIA,KAAK,KAAK,IAAI,IAAI,OAAOA,KAAK,KAAK,QAAQ,IAAI6C,KAAK,CAACC,OAAO,CAAC9C,KAAK,CAAC,EAAE;IACvE,OAAO,KAAK;EACd;;EAEA;EACA,OAAO,CAAC,CAAC2C,MAAM,CAACD,MAAM,CAAC1C,KAAK,CAAC,CAACa,MAAM;AACtC;;AAEA;AACA;AACA;AACA,OAAO,SAAS6C,aAAaA,CAAC1D,KAAe,EAA4B;EACvE,IAAI,CAAC6C,KAAK,CAACC,OAAO,CAAC9C,KAAK,CAAC,EAAE;IACzB,OAAO,KAAK;EACd;;EAEA;EACA,IAAI,CAACA,KAAK,CAACa,MAAM,EAAE;IACjB,OAAO,IAAI;EACb;EAEA,OAAOb,KAAK,CAAC2D,KAAK,CAACC,aAAa,CAAC;AACnC;;AAEA;AACA;AACA;AACA,OAAO,SAASA,aAAaA,CAAC5D,KAAe,EAA4B;EACvE,OAAOgD,WAAW,CAAChD,KAAK,CAAC,IAAI,OAAOA,KAAK,CAAC6D,MAAM,KAAK,QAAQ;AAC/D;;AAEA;AACA;AACA;AACA,OAAO,SAASC,aAAaA,CAAC9D,KAAe,EAAwB;EACnE,IAAI,CAAC6C,KAAK,CAACC,OAAO,CAAC9C,KAAK,CAAC,EAAE;IACzB,OAAO,KAAK;EACd;;EAEA;EACA,IAAI,CAACA,KAAK,CAACa,MAAM,EAAE;IACjB,OAAO,IAAI;EACb;EAEA,OAAOb,KAAK,CAAC2D,KAAK,CAACI,aAAa,CAAC;AACnC;;AAEA;AACA;AACA;AACA,OAAO,SAASC,iBAAiBA,CAAChE,KAAe,EAA4B;EAC3E,IAAI,CAAC6C,KAAK,CAACC,OAAO,CAAC9C,KAAK,CAAC,EAAE;IACzB,OAAO,KAAK;EACd;;EAEA;EACA,IAAI,CAACA,KAAK,CAACa,MAAM,EAAE;IACjB,OAAO,IAAI;EACb;EAEA,OAAOb,KAAK,CAAC2D,KAAK,CAACM,iBAAiB,CAAC;AACvC;;AAEA;AACA;AACA;AACA,OAAO,SAASF,aAAaA,CAAC/D,KAAe,EAAsB;EACjE,OAAOgD,WAAW,CAAChD,KAAK,CAAC,IAAI,OAAOA,KAAK,CAACkE,QAAQ,KAAK,QAAQ;AACjE;;AAEA;AACA;AACA;AACA,OAAO,SAASD,iBAAiBA,CAACjE,KAAe,EAAoB;EACnE,OACEgD,WAAW,CAAChD,KAAK,CAAC,IAClB,OAAOA,KAAK,CAACvB,IAAI,KAAK,QAAQ,IAC9BuB,KAAK,CAACvB,IAAI,KAAK,SAAS;AAE5B","ignoreList":[]}
1
+ {"version":3,"file":"FormComponent.js","names":["ComponentBase","FormComponent","type","hint","label","summaryLabel","isFormComponent","isAppendageStateSingleObject","constructor","def","props","getLabel","getSummaryLabel","errorDescription","shortDescription","title","keys","collection","name","fields","map","getFormDataFromState","state","getFormValue","getFormValueFromState","value","isValue","undefined","getStateFromValidForm","payload","getErrors","_translator","errors","list","filter","error","path","includes","length","getFirstError","translator","getViewErrors","firstError","getValidationMessagesOverride","getViewModel","isForceAccess","_isForceAccess","options","viewModel","t","tComponent","isRequired","required","hideOptional","optionalText","resolvedTitle","optionalTag","text","componentErrors","componentError","errorMessage","id","getDisplayStringFromFormValue","toString","getDisplayStringFromState","getContextValueFromFormValue","isState","values","Object","isFormValue","Array","isArray","getContextValueFromState","isFormState","getAllPossibleErrors","baseErrors","advancedSettingsErrors","onSubmit","_request","_metadata","_context","Promise","resolve","isRepeatState","every","isRepeatValue","itemId","isUploadState","isUploadValue","isGeospatialState","isGeospatialValue","uploadId"],"sources":["../../../../../src/server/plugins/engine/components/FormComponent.ts"],"sourcesContent":["import {\n type FormComponentsDef,\n type FormMetadata,\n type Item\n} from '@defra/forms-model'\nimport { type LanguageMessages } from 'joi'\n\nimport { ComponentBase } from '~/src/server/plugins/engine/components/ComponentBase.js'\nimport { type RenderContext } from '~/src/server/plugins/engine/components/types.js'\nimport { type Translator } from '~/src/server/plugins/engine/i18n/types.js'\nimport {\n type FormContext,\n type FormRequestPayload\n} from '~/src/server/plugins/engine/types/index.js'\nimport {\n type ErrorMessageTemplateList,\n type Feature,\n type FileState,\n type FormPayload,\n type FormState,\n type FormStateValue,\n type FormSubmissionError,\n type FormSubmissionState,\n type FormValue,\n type GeospatialState,\n type RepeatItemState,\n type RepeatListState,\n type UploadState\n} from '~/src/server/plugins/engine/types.js'\n\nexport class FormComponent extends ComponentBase {\n type: FormComponentsDef['type']\n hint: FormComponentsDef['hint']\n label: string\n summaryLabel: string\n\n isFormComponent = true\n isAppendageStateSingleObject = false\n\n constructor(\n def: FormComponentsDef,\n props: ConstructorParameters<typeof ComponentBase>[1]\n ) {\n super(def, props)\n\n const { hint, type } = def\n\n this.type = type\n this.hint = hint\n\n this.label = this.getLabel(def)\n this.summaryLabel = this.getSummaryLabel(def)\n }\n\n getLabel(def: FormComponentsDef) {\n if ('errorDescription' in def && def.errorDescription) {\n return def.errorDescription\n }\n\n return this.getSummaryLabel(def)\n }\n\n getSummaryLabel(def: FormComponentsDef) {\n if ('shortDescription' in def && def.shortDescription) {\n return def.shortDescription\n }\n\n return def.title\n }\n\n get keys() {\n const { collection, name } = this\n\n if (collection) {\n const { fields } = collection\n return [name, ...fields.map(({ name }) => name)]\n }\n\n return [name]\n }\n\n getFormDataFromState(state: FormSubmissionState): FormPayload {\n const { collection, name } = this\n\n if (collection) {\n return collection.getFormDataFromState(state)\n }\n\n return {\n [name]: this.getFormValue(state[name])\n }\n }\n\n getFormValueFromState(state: FormSubmissionState): FormValue | FormPayload {\n const { collection, name } = this\n\n if (collection) {\n return collection.getFormValueFromState(state)\n }\n\n return this.getFormValue(state[name])\n }\n\n getFormValue(value?: FormStateValue | FormState) {\n return this.isValue(value) ? value : undefined\n }\n\n getStateFromValidForm(payload: FormPayload): FormState {\n const { collection, name } = this\n\n if (collection) {\n return collection.getStateFromValidForm(payload)\n }\n\n return {\n [name]: this.getFormValue(payload[name]) ?? null\n }\n }\n\n getErrors(\n _translator: Translator,\n errors?: FormSubmissionError[]\n ): FormSubmissionError[] | undefined {\n const { name } = this\n\n // Filter component and child errors only\n const list = errors?.filter(\n (error) =>\n error.name === name ||\n error.path.includes(name) ||\n this.keys.includes(error.name)\n )\n\n if (!list?.length) {\n return\n }\n\n return list\n }\n\n getFirstError(\n translator: Translator,\n errors?: FormSubmissionError[]\n ): FormSubmissionError | undefined {\n return this.getErrors(translator, errors)?.[0]\n }\n\n getViewErrors(\n translator: Translator,\n errors?: FormSubmissionError[]\n ): FormSubmissionError[] | undefined {\n const firstError = this.getFirstError(translator, errors)\n return firstError && [firstError]\n }\n\n /**\n * Override in composite fields to return translated Joi message overrides for\n * their sub-fields, applied at validation time so schema-level English messages\n * are replaced with the correct language. Return null to skip message patching.\n * The return object may contain message overrides at component-level, or sub-field-level.\n * This would allow different error message overrides per field within a collection e.g.\n * for EastingNothingField\n */\n getValidationMessagesOverride(\n _translator: Translator\n ): Record<string, LanguageMessages> | null {\n return null\n }\n\n getViewModel({\n payload,\n errors,\n translator,\n isForceAccess: _isForceAccess = false\n }: RenderContext) {\n const { hint, name, options = {}, title, viewModel } = this\n\n const { t, tComponent } = translator\n\n const isRequired = !('required' in options) || options.required !== false\n const hideOptional = 'optionalText' in options && options.optionalText\n\n const resolvedTitle = tComponent(this.def, 'title') || title\n const optionalTag =\n !isRequired && !hideOptional ? ` ${t('common.optional')}` : ''\n const label = `${resolvedTitle}${optionalTag}`\n\n if (hint) {\n viewModel.hint = {\n text: tComponent(this.def, 'hint') || hint\n }\n }\n\n // Filter component errors only\n const componentErrors = this.getErrors(translator, errors)\n const componentError = this.getFirstError(translator, componentErrors)\n\n if (componentErrors) {\n viewModel.errors = componentErrors\n }\n\n if (componentError) {\n viewModel.errorMessage = {\n text: componentError.text\n }\n }\n\n return {\n ...viewModel,\n label: {\n text: label\n },\n id: name,\n name,\n value: payload[name]\n }\n }\n\n getDisplayStringFromFormValue(\n value: FormValue | FormPayload,\n _translator: Translator\n ): string {\n // Map selected values to text\n // eslint-disable-next-line @typescript-eslint/no-base-to-string\n return this.isValue(value) ? value.toString() : ''\n }\n\n getDisplayStringFromState(\n state: FormSubmissionState,\n translator: Translator\n ): string {\n const value = this.getFormValueFromState(state)\n return this.getDisplayStringFromFormValue(value, translator)\n }\n\n getContextValueFromFormValue(\n value: FormValue | FormPayload\n ): Item['value'] | Item['value'][] | null {\n // Filter object field values\n if (this.isState(value)) {\n const values = Object.values(value).filter(isFormValue)\n return values.length ? values : null\n }\n\n // Filter array field values\n if (this.isValue(value) && Array.isArray(value)) {\n return value.filter(isFormValue)\n }\n\n return this.isValue(value) ? value : null\n }\n\n getContextValueFromState(\n state: FormSubmissionState\n ): Item['value'] | Item['value'][] | null {\n const value = this.getFormValueFromState(state)\n\n return this.getContextValueFromFormValue(value)\n }\n\n isValue(\n value?: FormStateValue | FormState\n ): value is NonNullable<FormStateValue> {\n return isFormValue(value)\n }\n\n isState(value?: FormStateValue | FormState): value is FormState {\n return isFormState(value)\n }\n\n /**\n * For error preview page that shows all possible errors on a component\n */\n getAllPossibleErrors(): ErrorMessageTemplateList {\n return FormComponent.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 advancedSettingsErrors: []\n }\n }\n\n onSubmit(\n _request: FormRequestPayload,\n _metadata: FormMetadata,\n _context: FormContext\n ): Promise<void> {\n return Promise.resolve()\n }\n}\n\n/**\n * Check for form value\n */\nexport function isFormValue(\n value?: unknown\n): value is string | number | boolean {\n return (\n (typeof value === 'string' && value.length > 0) ||\n typeof value === 'number' ||\n typeof value === 'boolean'\n )\n}\n\n/**\n * Check for form state with nested values\n */\nexport function isFormState(value?: unknown): value is FormState {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) {\n return false\n }\n\n // Skip empty objects\n return !!Object.values(value).length\n}\n\n/**\n * Check for repeat list state\n */\nexport function isRepeatState(value?: unknown): value is RepeatListState {\n if (!Array.isArray(value)) {\n return false\n }\n\n // Skip checks when empty\n if (!value.length) {\n return true\n }\n\n return value.every(isRepeatValue)\n}\n\n/**\n * Check for repeat list value\n */\nexport function isRepeatValue(value?: unknown): value is RepeatItemState {\n return isFormState(value) && typeof value.itemId === 'string'\n}\n\n/**\n * Check for upload state\n */\nexport function isUploadState(value?: unknown): value is UploadState {\n if (!Array.isArray(value)) {\n return false\n }\n\n // Skip checks when empty\n if (!value.length) {\n return true\n }\n\n return value.every(isUploadValue)\n}\n\n/**\n * Check for geospatial state\n */\nexport function isGeospatialState(value?: unknown): value is GeospatialState {\n if (!Array.isArray(value)) {\n return false\n }\n\n // Skip checks when empty\n if (!value.length) {\n return true\n }\n\n return value.every(isGeospatialValue)\n}\n\n/**\n * Check for upload state value\n */\nexport function isUploadValue(value?: unknown): value is FileState {\n return isFormState(value) && typeof value.uploadId === 'string'\n}\n\n/**\n * Check for geospatial state value\n */\nexport function isGeospatialValue(value?: unknown): value is Feature {\n return (\n isFormState(value) &&\n typeof value.type === 'string' &&\n value.type === 'Feature'\n )\n}\n"],"mappings":"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","ignoreList":[]}
@@ -9,6 +9,11 @@ export declare class GeospatialField extends FormComponent {
9
9
  options: GeospatialFieldComponent['options'];
10
10
  formSchema: ArraySchema<GeospatialState>;
11
11
  stateSchema: ArraySchema<GeospatialState>;
12
+ limits: {
13
+ min?: number;
14
+ max?: number;
15
+ length?: number;
16
+ };
12
17
  constructor(def: GeospatialFieldComponent, props: ConstructorParameters<typeof ComponentBase>[1]);
13
18
  getFormValueFromState(state: FormSubmissionState): import("../../../../server/plugins/engine/types.js").FeatureCollection | undefined;
14
19
  getFormValue(value?: FormStateValue | FormState): import("../../../../server/plugins/engine/types.js").FeatureCollection | undefined;
@@ -17,6 +22,7 @@ export declare class GeospatialField extends FormComponent {
17
22
  getContextValueFromFormValue(features: GeospatialState | undefined): string[] | null;
18
23
  getContextValueFromState(state: FormSubmissionState): string[] | null;
19
24
  getViewModel(context: RenderContext): {
25
+ lang: string;
20
26
  country: import("@defra/forms-model").GeospatialFieldOptionsCountry | undefined;
21
27
  geometryTypes: import("@defra/forms-model").GeospatialFieldGeometryTypesEnum[] | undefined;
22
28
  mapLayers: string;
@@ -66,11 +72,19 @@ export declare class GeospatialField extends FormComponent {
66
72
  upload?: {
67
73
  count: number;
68
74
  summaryList: import("../../../../server/plugins/engine/types.js").SummaryList;
75
+ uploadingLabel?: string;
69
76
  };
70
77
  };
71
78
  getErrors(translator: Translator, errors?: FormSubmissionError[]): FormSubmissionError[] | undefined;
72
79
  getViewErrors(translator: Translator, errors?: FormSubmissionError[]): FormSubmissionError[] | undefined;
73
80
  isValue(value?: FormStateValue | FormState): value is GeospatialState;
81
+ getValidationMessagesOverride(translator: Translator): {
82
+ [x: string]: {
83
+ 'array.min': string;
84
+ 'array.max': string;
85
+ 'array.length': string;
86
+ };
87
+ };
74
88
  /**
75
89
  * For error preview page that shows all possible errors on a component
76
90
  */
@@ -79,4 +93,13 @@ export declare class GeospatialField extends FormComponent {
79
93
  * Static version of getAllPossibleErrors that doesn't require a component instance.
80
94
  */
81
95
  static getAllPossibleErrors(): ErrorMessageTemplateList;
96
+ static buildErrorMessages(language: string, limits?: {
97
+ min?: number;
98
+ max?: number;
99
+ length?: number;
100
+ }): {
101
+ 'array.min': string;
102
+ 'array.max': string;
103
+ 'array.length': string;
104
+ };
82
105
  }
@@ -1,6 +1,8 @@
1
+ import { EN_GB } from "../../../constants.js";
1
2
  import { FormComponent, isGeospatialState } from "./FormComponent.js";
2
3
  import { getMapLayers } from "./LocationFieldHelpers.js";
3
- import { getGeospatialSchema } from "./helpers/geospatial.js";
4
+ import { determineLimits, getGeospatialSchema } from "./helpers/geospatial.js";
5
+ import { t as tPlugin } from "../i18n/index.js";
4
6
  import { messageTemplate } from "../pageControllers/validationOptions.js";
5
7
  export class GeospatialField extends FormComponent {
6
8
  constructor(def, props) {
@@ -8,17 +10,17 @@ export class GeospatialField extends FormComponent {
8
10
  const {
9
11
  options
10
12
  } = def;
11
- const formSchema = getGeospatialSchema(def).label(this.label).messages({
12
- 'array.min': messageTemplate.featuresMin,
13
- 'array.max': messageTemplate.featuresMax,
14
- 'array.length': messageTemplate.featuresLength
15
- });
13
+ let formSchema = getGeospatialSchema(def).label(this.label);
14
+ const isOptional = options.required === false;
15
+ const limits = determineLimits(def, isOptional);
16
+ formSchema = formSchema.messages(GeospatialField.buildErrorMessages(EN_GB, limits));
16
17
  this.formSchema = formSchema;
17
18
  this.stateSchema = formSchema.default(null);
18
- if (options.required === false) {
19
+ if (isOptional) {
19
20
  this.stateSchema = this.stateSchema.allow(null);
20
21
  }
21
22
  this.options = options;
23
+ this.limits = limits;
22
24
  }
23
25
  getFormValueFromState(state) {
24
26
  const {
@@ -55,6 +57,7 @@ export class GeospatialField extends FormComponent {
55
57
  const value = typeof viewModel.value === 'string' ? viewModel.value : JSON.stringify(viewModel.value, null, 2);
56
58
  return {
57
59
  ...viewModel,
60
+ lang: context.translator.language,
58
61
  country: this.options.countries?.at(0),
59
62
  geometryTypes: this.options.geometryTypes,
60
63
  mapLayers: getMapLayers(this),
@@ -73,7 +76,7 @@ export class GeospatialField extends FormComponent {
73
76
  err.href = `#description_${err.path[1]}`;
74
77
  err.text = translator.t('components.geospatialField.validation.wrongCountry', {
75
78
  count: Number(err.path[1]) + 1,
76
- country: err.context.country
79
+ country: translator.t(`common.${err.context.country}`)
77
80
  });
78
81
  }
79
82
  });
@@ -85,6 +88,14 @@ export class GeospatialField extends FormComponent {
85
88
  isValue(value) {
86
89
  return isGeospatialState(value);
87
90
  }
91
+ getValidationMessagesOverride(translator) {
92
+ const {
93
+ language
94
+ } = translator;
95
+ return {
96
+ [this.name]: GeospatialField.buildErrorMessages(language, this.limits)
97
+ };
98
+ }
88
99
 
89
100
  /**
90
101
  * For error preview page that shows all possible errors on a component
@@ -107,7 +118,7 @@ export class GeospatialField extends FormComponent {
107
118
  template: messageTemplate.selectRequired
108
119
  }, {
109
120
  type: 'array.min',
110
- template: '{{#title}} must contain at least 1 items'
121
+ template: '{{#title}} must contain at least 1 item'
111
122
  }, {
112
123
  type: 'object.invalidjson',
113
124
  template: messageTemplate.format
@@ -115,5 +126,18 @@ export class GeospatialField extends FormComponent {
115
126
  advancedSettingsErrors: []
116
127
  };
117
128
  }
129
+ static buildErrorMessages(language, limits = {}) {
130
+ return {
131
+ 'array.min': tPlugin('validation.featuresMin', language, {
132
+ count: limits.min ?? 1
133
+ }),
134
+ 'array.max': tPlugin('validation.featuresMax', language, {
135
+ count: limits.max ?? 1
136
+ }),
137
+ 'array.length': tPlugin('validation.featuresLength', language, {
138
+ count: limits.length ?? 1
139
+ })
140
+ };
141
+ }
118
142
  }
119
143
  //# sourceMappingURL=GeospatialField.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"GeospatialField.js","names":["FormComponent","isGeospatialState","getMapLayers","getGeospatialSchema","messageTemplate","GeospatialField","constructor","def","props","options","formSchema","label","messages","featuresMin","featuresMax","featuresLength","stateSchema","default","required","allow","getFormValueFromState","state","name","getFormValue","value","isValue","undefined","getDisplayStringFromFormValue","features","translator","length","t","count","getDisplayStringFromState","getContextValueFromFormValue","map","id","getContextValueFromState","getViewModel","context","viewModel","JSON","stringify","country","countries","at","geometryTypes","mapLayers","getErrors","errors","fieldErrors","forEach","err","href","path","text","Number","getViewErrors","getAllPossibleErrors","staticErrors","advancedSettingsErrors","baseErrors","type","template","selectRequired","format"],"sources":["../../../../../src/server/plugins/engine/components/GeospatialField.ts"],"sourcesContent":["import { type GeospatialFieldComponent } from '@defra/forms-model'\nimport { type ArraySchema } from 'joi'\n\nimport { type ComponentBase } from '~/src/server/plugins/engine/components/ComponentBase.js'\nimport {\n FormComponent,\n isGeospatialState\n} from '~/src/server/plugins/engine/components/FormComponent.js'\nimport { getMapLayers } from '~/src/server/plugins/engine/components/LocationFieldHelpers.js'\nimport { getGeospatialSchema } from '~/src/server/plugins/engine/components/helpers/geospatial.js'\nimport { type RenderContext } from '~/src/server/plugins/engine/components/types.js'\nimport { type Translator } from '~/src/server/plugins/engine/i18n/types.js'\nimport { messageTemplate } from '~/src/server/plugins/engine/pageControllers/validationOptions.js'\nimport {\n type ErrorMessageTemplateList,\n type FormState,\n type FormStateValue,\n type FormSubmissionError,\n type FormSubmissionState,\n type GeospatialState\n} from '~/src/server/plugins/engine/types.js'\n\nexport class GeospatialField extends FormComponent {\n declare options: GeospatialFieldComponent['options']\n declare formSchema: ArraySchema<GeospatialState>\n declare stateSchema: ArraySchema<GeospatialState>\n\n constructor(\n def: GeospatialFieldComponent,\n props: ConstructorParameters<typeof ComponentBase>[1]\n ) {\n super(def, props)\n\n const { options } = def\n\n const formSchema = getGeospatialSchema(def).label(this.label).messages({\n 'array.min': messageTemplate.featuresMin,\n 'array.max': messageTemplate.featuresMax,\n 'array.length': messageTemplate.featuresLength\n })\n\n this.formSchema = formSchema\n this.stateSchema = formSchema.default(null)\n\n if (options.required === false) {\n this.stateSchema = this.stateSchema.allow(null)\n }\n\n this.options = options\n }\n\n getFormValueFromState(state: FormSubmissionState) {\n const { name } = this\n return this.getFormValue(state[name])\n }\n\n getFormValue(value?: FormStateValue | FormState) {\n return this.isValue(value) ? value : undefined\n }\n\n getDisplayStringFromFormValue(\n features: GeospatialState | undefined,\n translator: Translator\n ): string {\n if (!features?.length) {\n return ''\n }\n\n return translator.t('components.geospatialField.added', {\n count: features.length\n })\n }\n\n getDisplayStringFromState(\n state: FormSubmissionState,\n translator: Translator\n ) {\n const features = this.getFormValueFromState(state)\n\n return this.getDisplayStringFromFormValue(features, translator)\n }\n\n getContextValueFromFormValue(\n features: GeospatialState | undefined\n ): string[] | null {\n return features?.map(({ id }) => id) ?? null\n }\n\n getContextValueFromState(state: FormSubmissionState) {\n const features = this.getFormValueFromState(state)\n\n return this.getContextValueFromFormValue(features)\n }\n\n getViewModel(context: RenderContext) {\n const viewModel = super.getViewModel(context)\n const value =\n typeof viewModel.value === 'string'\n ? viewModel.value\n : JSON.stringify(viewModel.value, null, 2)\n\n return {\n ...viewModel,\n country: this.options.countries?.at(0),\n geometryTypes: this.options.geometryTypes,\n mapLayers: getMapLayers(this),\n value\n }\n }\n\n getErrors(\n translator: Translator,\n errors?: FormSubmissionError[]\n ): FormSubmissionError[] | undefined {\n const fieldErrors = super.getErrors(translator, errors)\n\n fieldErrors?.forEach((err) => {\n if (err.name === 'description') {\n err.href = `#description_${err.path[1]}`\n err.text = translator.t(\n 'components.geospatialField.validation.descriptionRequired',\n { count: Number(err.path[1]) + 1 }\n )\n } else if (typeof err.name === 'number' && err.context?.country) {\n err.href = `#description_${err.path[1]}`\n err.text = translator.t(\n 'components.geospatialField.validation.wrongCountry',\n { count: Number(err.path[1]) + 1, country: err.context.country }\n )\n }\n })\n\n return fieldErrors\n }\n\n getViewErrors(\n translator: Translator,\n errors?: FormSubmissionError[]\n ): FormSubmissionError[] | undefined {\n return this.getErrors(translator, errors)\n }\n\n isValue(value?: FormStateValue | FormState): value is GeospatialState {\n return isGeospatialState(value)\n }\n\n /**\n * For error preview page that shows all possible errors on a component\n */\n getAllPossibleErrors(): ErrorMessageTemplateList {\n const staticErrors = GeospatialField.getAllPossibleErrors()\n return {\n ...staticErrors,\n advancedSettingsErrors: [...staticErrors.advancedSettingsErrors]\n }\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.selectRequired },\n {\n type: 'array.min',\n template: '{{#title}} must contain at least 1 items'\n },\n { type: 'object.invalidjson', template: messageTemplate.format }\n ],\n advancedSettingsErrors: []\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"GeospatialField.js","names":["EN_GB","FormComponent","isGeospatialState","getMapLayers","determineLimits","getGeospatialSchema","t","tPlugin","messageTemplate","GeospatialField","constructor","def","props","options","formSchema","label","isOptional","required","limits","messages","buildErrorMessages","stateSchema","default","allow","getFormValueFromState","state","name","getFormValue","value","isValue","undefined","getDisplayStringFromFormValue","features","translator","length","count","getDisplayStringFromState","getContextValueFromFormValue","map","id","getContextValueFromState","getViewModel","context","viewModel","JSON","stringify","lang","language","country","countries","at","geometryTypes","mapLayers","getErrors","errors","fieldErrors","forEach","err","href","path","text","Number","getViewErrors","getValidationMessagesOverride","getAllPossibleErrors","staticErrors","advancedSettingsErrors","baseErrors","type","template","selectRequired","format","min","max"],"sources":["../../../../../src/server/plugins/engine/components/GeospatialField.ts"],"sourcesContent":["import { type GeospatialFieldComponent } from '@defra/forms-model'\nimport { type ArraySchema } from 'joi'\n\nimport { EN_GB } from '~/src/server/constants.js'\nimport { type ComponentBase } from '~/src/server/plugins/engine/components/ComponentBase.js'\nimport {\n FormComponent,\n isGeospatialState\n} from '~/src/server/plugins/engine/components/FormComponent.js'\nimport { getMapLayers } from '~/src/server/plugins/engine/components/LocationFieldHelpers.js'\nimport {\n determineLimits,\n getGeospatialSchema\n} from '~/src/server/plugins/engine/components/helpers/geospatial.js'\nimport { type RenderContext } from '~/src/server/plugins/engine/components/types.js'\nimport { t as tPlugin } from '~/src/server/plugins/engine/i18n/index.js'\nimport { type Translator } from '~/src/server/plugins/engine/i18n/types.js'\nimport { messageTemplate } from '~/src/server/plugins/engine/pageControllers/validationOptions.js'\nimport {\n type ErrorMessageTemplateList,\n type FormState,\n type FormStateValue,\n type FormSubmissionError,\n type FormSubmissionState,\n type GeospatialState\n} from '~/src/server/plugins/engine/types.js'\n\nexport class GeospatialField extends FormComponent {\n declare options: GeospatialFieldComponent['options']\n declare formSchema: ArraySchema<GeospatialState>\n declare stateSchema: ArraySchema<GeospatialState>\n declare limits: { min?: number; max?: number; length?: number }\n\n constructor(\n def: GeospatialFieldComponent,\n props: ConstructorParameters<typeof ComponentBase>[1]\n ) {\n super(def, props)\n\n const { options } = def\n\n let formSchema = getGeospatialSchema(def).label(this.label)\n\n const isOptional = options.required === false\n const limits = determineLimits(def, isOptional)\n\n formSchema = formSchema.messages(\n GeospatialField.buildErrorMessages(EN_GB, limits)\n )\n\n this.formSchema = formSchema\n this.stateSchema = formSchema.default(null)\n\n if (isOptional) {\n this.stateSchema = this.stateSchema.allow(null)\n }\n\n this.options = options\n this.limits = limits\n }\n\n getFormValueFromState(state: FormSubmissionState) {\n const { name } = this\n return this.getFormValue(state[name])\n }\n\n getFormValue(value?: FormStateValue | FormState) {\n return this.isValue(value) ? value : undefined\n }\n\n getDisplayStringFromFormValue(\n features: GeospatialState | undefined,\n translator: Translator\n ): string {\n if (!features?.length) {\n return ''\n }\n\n return translator.t('components.geospatialField.added', {\n count: features.length\n })\n }\n\n getDisplayStringFromState(\n state: FormSubmissionState,\n translator: Translator\n ) {\n const features = this.getFormValueFromState(state)\n\n return this.getDisplayStringFromFormValue(features, translator)\n }\n\n getContextValueFromFormValue(\n features: GeospatialState | undefined\n ): string[] | null {\n return features?.map(({ id }) => id) ?? null\n }\n\n getContextValueFromState(state: FormSubmissionState) {\n const features = this.getFormValueFromState(state)\n\n return this.getContextValueFromFormValue(features)\n }\n\n getViewModel(context: RenderContext) {\n const viewModel = super.getViewModel(context)\n const value =\n typeof viewModel.value === 'string'\n ? viewModel.value\n : JSON.stringify(viewModel.value, null, 2)\n\n return {\n ...viewModel,\n lang: context.translator.language,\n country: this.options.countries?.at(0),\n geometryTypes: this.options.geometryTypes,\n mapLayers: getMapLayers(this),\n value\n }\n }\n\n getErrors(\n translator: Translator,\n errors?: FormSubmissionError[]\n ): FormSubmissionError[] | undefined {\n const fieldErrors = super.getErrors(translator, errors)\n\n fieldErrors?.forEach((err) => {\n if (err.name === 'description') {\n err.href = `#description_${err.path[1]}`\n err.text = translator.t(\n 'components.geospatialField.validation.descriptionRequired',\n { count: Number(err.path[1]) + 1 }\n )\n } else if (typeof err.name === 'number' && err.context?.country) {\n err.href = `#description_${err.path[1]}`\n err.text = translator.t(\n 'components.geospatialField.validation.wrongCountry',\n {\n count: Number(err.path[1]) + 1,\n country: translator.t(`common.${err.context.country}`)\n }\n )\n }\n })\n\n return fieldErrors\n }\n\n getViewErrors(\n translator: Translator,\n errors?: FormSubmissionError[]\n ): FormSubmissionError[] | undefined {\n return this.getErrors(translator, errors)\n }\n\n isValue(value?: FormStateValue | FormState): value is GeospatialState {\n return isGeospatialState(value)\n }\n\n getValidationMessagesOverride(translator: Translator) {\n const { language } = translator\n return {\n [this.name]: GeospatialField.buildErrorMessages(language, this.limits)\n }\n }\n\n /**\n * For error preview page that shows all possible errors on a component\n */\n getAllPossibleErrors(): ErrorMessageTemplateList {\n const staticErrors = GeospatialField.getAllPossibleErrors()\n return {\n ...staticErrors,\n advancedSettingsErrors: [...staticErrors.advancedSettingsErrors]\n }\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.selectRequired },\n {\n type: 'array.min',\n template: '{{#title}} must contain at least 1 item'\n },\n { type: 'object.invalidjson', template: messageTemplate.format }\n ],\n advancedSettingsErrors: []\n }\n }\n\n static buildErrorMessages(\n language: string,\n limits: { min?: number; max?: number; length?: number } = {}\n ) {\n return {\n 'array.min': tPlugin('validation.featuresMin', language, {\n count: limits.min ?? 1\n }),\n 'array.max': tPlugin('validation.featuresMax', language, {\n count: limits.max ?? 1\n }),\n 'array.length': tPlugin('validation.featuresLength', language, {\n count: limits.length ?? 1\n })\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -49,6 +49,7 @@ export declare class Html extends ComponentBase {
49
49
  upload?: {
50
50
  count: number;
51
51
  summaryList: import("../types.js").SummaryList;
52
+ uploadingLabel?: string;
52
53
  };
53
54
  };
54
55
  }
@@ -48,6 +48,7 @@ export declare class InsetText extends ComponentBase {
48
48
  upload?: {
49
49
  count: number;
50
50
  summaryList: import("../types.js").SummaryList;
51
+ uploadingLabel?: string;
51
52
  };
52
53
  };
53
54
  }
@@ -1,5 +1,5 @@
1
1
  import { type LatLongFieldComponent } from '@defra/forms-model';
2
- import { type ObjectSchema } from 'joi';
2
+ import { type LanguageMessages, type ObjectSchema } from 'joi';
3
3
  import { ComponentCollection } from '../../../../server/plugins/engine/components/ComponentCollection.js';
4
4
  import { FormComponent } from '../../../../server/plugins/engine/components/FormComponent.js';
5
5
  import { type LatLongState, type RenderContext } from '../../../../server/plugins/engine/components/types.js';
@@ -12,7 +12,7 @@ export declare class LatLongField extends FormComponent {
12
12
  collection: ComponentCollection;
13
13
  constructor(def: LatLongFieldComponent, props: ConstructorParameters<typeof FormComponent>[1]);
14
14
  getFormValueFromState(state: FormSubmissionState): LatLongState | undefined;
15
- getDisplayStringFromFormValue(value: LatLongState | undefined, _translator: Translator): string;
15
+ getDisplayStringFromFormValue(value: LatLongState | undefined, translator: Translator): string;
16
16
  getDisplayStringFromState(state: FormSubmissionState, translator: Translator): string;
17
17
  getContextValueFromFormValue(value: LatLongState | undefined): string | null;
18
18
  getContextValueFromState(state: FormSubmissionState): string | null;
@@ -23,6 +23,8 @@ export declare class LatLongField extends FormComponent {
23
23
  };
24
24
  items: import("../../../../server/plugins/engine/components/types.js").DateInputItem[];
25
25
  mapLayers: string;
26
+ country: import("@defra/forms-model").GeospatialFieldOptionsCountry | undefined;
27
+ lang: string;
26
28
  label: import("../../../../server/plugins/engine/components/types.js").Label;
27
29
  type?: string;
28
30
  id: string;
@@ -62,15 +64,20 @@ export declare class LatLongField extends FormComponent {
62
64
  upload?: {
63
65
  count: number;
64
66
  summaryList: import("../../../../server/plugins/engine/types.js").SummaryList;
67
+ uploadingLabel?: string;
65
68
  };
66
69
  } | {
70
+ instructionSummary: string;
67
71
  instructionText: string;
72
+ t: (key: string, opts?: Record<string, unknown>) => string;
68
73
  fieldset: {
69
74
  attributes?: string | Record<string, string>;
70
75
  legend?: import("../../../../server/plugins/engine/components/types.js").Label;
71
76
  };
72
77
  items: import("../../../../server/plugins/engine/components/types.js").DateInputItem[];
73
78
  mapLayers: string;
79
+ country: import("@defra/forms-model").GeospatialFieldOptionsCountry | undefined;
80
+ lang: string;
74
81
  label: import("../../../../server/plugins/engine/components/types.js").Label;
75
82
  type?: string;
76
83
  id: string;
@@ -110,10 +117,14 @@ export declare class LatLongField extends FormComponent {
110
117
  upload?: {
111
118
  count: number;
112
119
  summaryList: import("../../../../server/plugins/engine/types.js").SummaryList;
120
+ uploadingLabel?: string;
113
121
  };
114
122
  };
115
123
  getViewErrors(translator: Translator, errors?: FormSubmissionError[]): FormSubmissionError[] | undefined;
116
124
  isState(value?: FormStateValue | FormState): value is LatLongState;
125
+ getValidationMessagesOverride(translator: Translator): {
126
+ [x: string]: LanguageMessages;
127
+ };
117
128
  /**
118
129
  * For error preview page that shows all possible errors on a component
119
130
  */
@@ -123,4 +134,23 @@ export declare class LatLongField extends FormComponent {
123
134
  */
124
135
  static getAllPossibleErrors(): ErrorMessageTemplateList;
125
136
  static isLatLong(value?: FormStateValue | FormState): value is LatLongState;
137
+ static buildErrorMessages(label: string, latitudeMin: number, latitudeMax: number, longitudeMin: number, longitudeMax: number, language: string): {
138
+ latitudeMessages: LanguageMessages;
139
+ longitudeMessages: LanguageMessages;
140
+ };
141
+ static getMinMax(schema: {
142
+ latitude?: {
143
+ min?: number;
144
+ max?: number;
145
+ };
146
+ longitude?: {
147
+ min?: number;
148
+ max?: number;
149
+ };
150
+ } | undefined): {
151
+ latitudeMin: number;
152
+ latitudeMax: number;
153
+ longitudeMin: number;
154
+ longitudeMax: number;
155
+ };
126
156
  }