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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (347) hide show
  1. package/.public/assets-manifest.json +3 -5
  2. package/.public/javascripts/im-core.min.js +2 -0
  3. package/.public/javascripts/im-core.min.js.map +1 -0
  4. package/.public/javascripts/shared.min.js +1 -1
  5. package/.public/javascripts/shared.min.js.map +1 -1
  6. package/.public/javascripts/vendor/@defra.min.js +1 -1
  7. package/.public/javascripts/vendor/@defra.min.js.map +1 -1
  8. package/.public/stylesheets/application.min.css +1 -1
  9. package/.public/stylesheets/application.min.css.map +1 -1
  10. package/.server/client/javascripts/geospatial-map.js +8 -6
  11. package/.server/client/javascripts/geospatial-map.js.map +1 -1
  12. package/.server/client/javascripts/location-map.js +8 -1
  13. package/.server/client/javascripts/location-map.js.map +1 -1
  14. package/.server/client/javascripts/map.d.ts +6 -0
  15. package/.server/client/javascripts/map.js +10 -0
  16. package/.server/client/javascripts/map.js.map +1 -1
  17. package/.server/client/javascripts/sssi-dataset.d.ts +34 -0
  18. package/.server/client/javascripts/sssi-dataset.js +101 -0
  19. package/.server/client/javascripts/sssi-dataset.js.map +1 -0
  20. package/.server/client/stylesheets/shared.scss +0 -2
  21. package/.server/server/forms/register-as-a-unicorn-breeder.yaml +0 -14
  22. package/.server/server/forms/simple-form.yaml +106 -3
  23. package/.server/server/plugins/engine/components/AutocompleteField.d.ts +11 -11
  24. package/.server/server/plugins/engine/components/AutocompleteField.js +2 -2
  25. package/.server/server/plugins/engine/components/AutocompleteField.js.map +1 -1
  26. package/.server/server/plugins/engine/components/CheckboxesField.d.ts +3 -2
  27. package/.server/server/plugins/engine/components/CheckboxesField.js +4 -9
  28. package/.server/server/plugins/engine/components/CheckboxesField.js.map +1 -1
  29. package/.server/server/plugins/engine/components/ComponentCollection.d.ts +8 -7
  30. package/.server/server/plugins/engine/components/ComponentCollection.js +106 -51
  31. package/.server/server/plugins/engine/components/ComponentCollection.js.map +1 -1
  32. package/.server/server/plugins/engine/components/DatePartsField.d.ts +8 -6
  33. package/.server/server/plugins/engine/components/DatePartsField.js +27 -9
  34. package/.server/server/plugins/engine/components/DatePartsField.js.map +1 -1
  35. package/.server/server/plugins/engine/components/DeclarationField.d.ts +13 -11
  36. package/.server/server/plugins/engine/components/DeclarationField.js +31 -9
  37. package/.server/server/plugins/engine/components/DeclarationField.js.map +1 -1
  38. package/.server/server/plugins/engine/components/EastingNorthingField.d.ts +8 -5
  39. package/.server/server/plugins/engine/components/EastingNorthingField.js +42 -22
  40. package/.server/server/plugins/engine/components/EastingNorthingField.js.map +1 -1
  41. package/.server/server/plugins/engine/components/EmailAddressField.d.ts +11 -14
  42. package/.server/server/plugins/engine/components/EmailAddressField.js +2 -2
  43. package/.server/server/plugins/engine/components/EmailAddressField.js.map +1 -1
  44. package/.server/server/plugins/engine/components/FileUploadField.d.ts +14 -12
  45. package/.server/server/plugins/engine/components/FileUploadField.js +22 -12
  46. package/.server/server/plugins/engine/components/FileUploadField.js.map +1 -1
  47. package/.server/server/plugins/engine/components/FormComponent.d.ts +21 -12
  48. package/.server/server/plugins/engine/components/FormComponent.js +33 -14
  49. package/.server/server/plugins/engine/components/FormComponent.js.map +1 -1
  50. package/.server/server/plugins/engine/components/GeospatialField.d.ts +15 -12
  51. package/.server/server/plugins/engine/components/GeospatialField.js +21 -13
  52. package/.server/server/plugins/engine/components/GeospatialField.js.map +1 -1
  53. package/.server/server/plugins/engine/components/LatLongField.d.ts +8 -5
  54. package/.server/server/plugins/engine/components/LatLongField.js +32 -20
  55. package/.server/server/plugins/engine/components/LatLongField.js.map +1 -1
  56. package/.server/server/plugins/engine/components/ListFormComponent.d.ts +7 -6
  57. package/.server/server/plugins/engine/components/ListFormComponent.js +19 -7
  58. package/.server/server/plugins/engine/components/ListFormComponent.js.map +1 -1
  59. package/.server/server/plugins/engine/components/LocationFieldBase.d.ts +17 -16
  60. package/.server/server/plugins/engine/components/LocationFieldBase.js +2 -2
  61. package/.server/server/plugins/engine/components/LocationFieldBase.js.map +1 -1
  62. package/.server/server/plugins/engine/components/LocationFieldHelpers.d.ts +8 -3
  63. package/.server/server/plugins/engine/components/LocationFieldHelpers.js +14 -3
  64. package/.server/server/plugins/engine/components/LocationFieldHelpers.js.map +1 -1
  65. package/.server/server/plugins/engine/components/Markdown.d.ts +8 -7
  66. package/.server/server/plugins/engine/components/Markdown.js +5 -2
  67. package/.server/server/plugins/engine/components/Markdown.js.map +1 -1
  68. package/.server/server/plugins/engine/components/MonthYearField.d.ts +9 -7
  69. package/.server/server/plugins/engine/components/MonthYearField.js +26 -8
  70. package/.server/server/plugins/engine/components/MonthYearField.js.map +1 -1
  71. package/.server/server/plugins/engine/components/MultilineTextField.d.ts +10 -9
  72. package/.server/server/plugins/engine/components/MultilineTextField.js +2 -2
  73. package/.server/server/plugins/engine/components/MultilineTextField.js.map +1 -1
  74. package/.server/server/plugins/engine/components/NationalGridFieldNumberField.d.ts +2 -1
  75. package/.server/server/plugins/engine/components/NationalGridFieldNumberField.js +14 -6
  76. package/.server/server/plugins/engine/components/NationalGridFieldNumberField.js.map +1 -1
  77. package/.server/server/plugins/engine/components/NumberField.d.ts +10 -9
  78. package/.server/server/plugins/engine/components/NumberField.js +2 -2
  79. package/.server/server/plugins/engine/components/NumberField.js.map +1 -1
  80. package/.server/server/plugins/engine/components/OsGridRefField.d.ts +2 -1
  81. package/.server/server/plugins/engine/components/OsGridRefField.js +14 -6
  82. package/.server/server/plugins/engine/components/OsGridRefField.js.map +1 -1
  83. package/.server/server/plugins/engine/components/PaymentField.d.ts +12 -10
  84. package/.server/server/plugins/engine/components/PaymentField.js +21 -8
  85. package/.server/server/plugins/engine/components/PaymentField.js.map +1 -1
  86. package/.server/server/plugins/engine/components/SelectField.d.ts +11 -11
  87. package/.server/server/plugins/engine/components/SelectField.js +2 -2
  88. package/.server/server/plugins/engine/components/SelectField.js.map +1 -1
  89. package/.server/server/plugins/engine/components/SelectionControlField.d.ts +4 -4
  90. package/.server/server/plugins/engine/components/SelectionControlField.js +2 -2
  91. package/.server/server/plugins/engine/components/SelectionControlField.js.map +1 -1
  92. package/.server/server/plugins/engine/components/TelephoneNumberField.d.ts +10 -9
  93. package/.server/server/plugins/engine/components/TelephoneNumberField.js +2 -2
  94. package/.server/server/plugins/engine/components/TelephoneNumberField.js.map +1 -1
  95. package/.server/server/plugins/engine/components/UkAddressField.d.ts +12 -10
  96. package/.server/server/plugins/engine/components/UkAddressField.js +29 -17
  97. package/.server/server/plugins/engine/components/UkAddressField.js.map +1 -1
  98. package/.server/server/plugins/engine/components/YesNoField.d.ts +3 -0
  99. package/.server/server/plugins/engine/components/YesNoField.js +9 -0
  100. package/.server/server/plugins/engine/components/YesNoField.js.map +1 -1
  101. package/.server/server/plugins/engine/components/helpers/components.d.ts +3 -2
  102. package/.server/server/plugins/engine/components/helpers/components.js +11 -8
  103. package/.server/server/plugins/engine/components/helpers/components.js.map +1 -1
  104. package/.server/server/plugins/engine/components/types.d.ts +8 -1
  105. package/.server/server/plugins/engine/components/types.js.map +1 -1
  106. package/.server/server/plugins/engine/configureEnginePlugin.js +8 -1
  107. package/.server/server/plugins/engine/configureEnginePlugin.js.map +1 -1
  108. package/.server/server/plugins/engine/form-context.d.ts +1 -0
  109. package/.server/server/plugins/engine/form-context.js +4 -2
  110. package/.server/server/plugins/engine/form-context.js.map +1 -1
  111. package/.server/server/plugins/engine/helpers.d.ts +1 -1
  112. package/.server/server/plugins/engine/helpers.js +8 -13
  113. package/.server/server/plugins/engine/helpers.js.map +1 -1
  114. package/.server/server/plugins/engine/i18n/buildValidationMessages.d.ts +39 -0
  115. package/.server/server/plugins/engine/i18n/buildValidationMessages.js +50 -0
  116. package/.server/server/plugins/engine/i18n/buildValidationMessages.js.map +1 -0
  117. package/.server/server/plugins/engine/i18n/createFormTranslator.d.ts +5 -0
  118. package/.server/server/plugins/engine/i18n/createFormTranslator.js +18 -0
  119. package/.server/server/plugins/engine/i18n/createFormTranslator.js.map +1 -0
  120. package/.server/server/plugins/engine/i18n/createTranslator.d.ts +9 -0
  121. package/.server/server/plugins/engine/i18n/createTranslator.js +51 -0
  122. package/.server/server/plugins/engine/i18n/createTranslator.js.map +1 -0
  123. package/.server/server/plugins/engine/i18n/extractBaseTranslations.d.ts +5 -0
  124. package/.server/server/plugins/engine/i18n/extractBaseTranslations.js +57 -0
  125. package/.server/server/plugins/engine/i18n/extractBaseTranslations.js.map +1 -0
  126. package/.server/server/plugins/engine/i18n/index.d.ts +18 -0
  127. package/.server/server/plugins/engine/i18n/index.js +71 -0
  128. package/.server/server/plugins/engine/i18n/index.js.map +1 -0
  129. package/.server/server/plugins/engine/i18n/translations/cy.json +271 -0
  130. package/.server/server/plugins/engine/i18n/translations/en-GB.json +271 -0
  131. package/.server/server/plugins/engine/i18n/types.d.ts +41 -0
  132. package/.server/server/plugins/engine/i18n/types.js +2 -0
  133. package/.server/server/plugins/engine/i18n/types.js.map +1 -0
  134. package/.server/server/plugins/engine/index.js +3 -2
  135. package/.server/server/plugins/engine/index.js.map +1 -1
  136. package/.server/server/plugins/engine/models/FormModel.d.ts +9 -1
  137. package/.server/server/plugins/engine/models/FormModel.js +44 -18
  138. package/.server/server/plugins/engine/models/FormModel.js.map +1 -1
  139. package/.server/server/plugins/engine/models/SummaryViewModel.d.ts +5 -2
  140. package/.server/server/plugins/engine/models/SummaryViewModel.js +44 -18
  141. package/.server/server/plugins/engine/models/SummaryViewModel.js.map +1 -1
  142. package/.server/server/plugins/engine/options.js +2 -1
  143. package/.server/server/plugins/engine/options.js.map +1 -1
  144. package/.server/server/plugins/engine/outputFormatters/adapter/v1.js +4 -0
  145. package/.server/server/plugins/engine/outputFormatters/adapter/v1.js.map +1 -1
  146. package/.server/server/plugins/engine/outputFormatters/human/v1.js +2 -1
  147. package/.server/server/plugins/engine/outputFormatters/human/v1.js.map +1 -1
  148. package/.server/server/plugins/engine/outputFormatters/machine/v1.js +7 -6
  149. package/.server/server/plugins/engine/outputFormatters/machine/v1.js.map +1 -1
  150. package/.server/server/plugins/engine/pageControllers/FileUploadPageController.d.ts +2 -1
  151. package/.server/server/plugins/engine/pageControllers/FileUploadPageController.js +6 -3
  152. package/.server/server/plugins/engine/pageControllers/FileUploadPageController.js.map +1 -1
  153. package/.server/server/plugins/engine/pageControllers/PageController.d.ts +3 -1
  154. package/.server/server/plugins/engine/pageControllers/PageController.js +11 -1
  155. package/.server/server/plugins/engine/pageControllers/PageController.js.map +1 -1
  156. package/.server/server/plugins/engine/pageControllers/QuestionPageController.d.ts +4 -2
  157. package/.server/server/plugins/engine/pageControllers/QuestionPageController.js +52 -21
  158. package/.server/server/plugins/engine/pageControllers/QuestionPageController.js.map +1 -1
  159. package/.server/server/plugins/engine/pageControllers/RepeatPageController.d.ts +3 -2
  160. package/.server/server/plugins/engine/pageControllers/RepeatPageController.js +63 -26
  161. package/.server/server/plugins/engine/pageControllers/RepeatPageController.js.map +1 -1
  162. package/.server/server/plugins/engine/pageControllers/StartPageController.d.ts +3 -1
  163. package/.server/server/plugins/engine/pageControllers/StartPageController.js +2 -2
  164. package/.server/server/plugins/engine/pageControllers/StartPageController.js.map +1 -1
  165. package/.server/server/plugins/engine/pageControllers/StatusPageController.js +12 -2
  166. package/.server/server/plugins/engine/pageControllers/StatusPageController.js.map +1 -1
  167. package/.server/server/plugins/engine/pageControllers/SummaryPageController.d.ts +4 -3
  168. package/.server/server/plugins/engine/pageControllers/SummaryPageController.js +44 -28
  169. package/.server/server/plugins/engine/pageControllers/SummaryPageController.js.map +1 -1
  170. package/.server/server/plugins/engine/pageControllers/__stubs__/translator.d.ts +2 -0
  171. package/.server/server/plugins/engine/pageControllers/__stubs__/translator.js +24 -0
  172. package/.server/server/plugins/engine/pageControllers/__stubs__/translator.js.map +1 -0
  173. package/.server/server/plugins/engine/pageControllers/errors.d.ts +1 -1
  174. package/.server/server/plugins/engine/pageControllers/errors.js +3 -2
  175. package/.server/server/plugins/engine/pageControllers/errors.js.map +1 -1
  176. package/.server/server/plugins/engine/pageControllers/helpers/submission.d.ts +3 -2
  177. package/.server/server/plugins/engine/pageControllers/helpers/submission.js +4 -4
  178. package/.server/server/plugins/engine/pageControllers/helpers/submission.js.map +1 -1
  179. package/.server/server/plugins/engine/pageControllers/validationOptions.d.ts +7 -3
  180. package/.server/server/plugins/engine/pageControllers/validationOptions.js +34 -33
  181. package/.server/server/plugins/engine/pageControllers/validationOptions.js.map +1 -1
  182. package/.server/server/plugins/engine/plugin.js +2 -0
  183. package/.server/server/plugins/engine/plugin.js.map +1 -1
  184. package/.server/server/plugins/engine/routes/index.js +4 -1
  185. package/.server/server/plugins/engine/routes/index.js.map +1 -1
  186. package/.server/server/plugins/engine/routes/questions.js +5 -2
  187. package/.server/server/plugins/engine/routes/questions.js.map +1 -1
  188. package/.server/server/plugins/engine/types/index.d.ts +1 -0
  189. package/.server/server/plugins/engine/types/index.js.map +1 -1
  190. package/.server/server/plugins/engine/types/schema.js +1 -0
  191. package/.server/server/plugins/engine/types/schema.js.map +1 -1
  192. package/.server/server/plugins/engine/types.d.ts +12 -1
  193. package/.server/server/plugins/engine/types.js.map +1 -1
  194. package/.server/server/plugins/engine/views/components/_location-field-base.html +4 -2
  195. package/.server/server/plugins/engine/views/components/fileuploadfield.html +3 -3
  196. package/.server/server/plugins/engine/views/components/geospatialfield.html +4 -1
  197. package/.server/server/plugins/engine/views/components/nationalgridfieldnumberfield.html +1 -1
  198. package/.server/server/plugins/engine/views/components/osgridreffield.html +1 -1
  199. package/.server/server/plugins/engine/views/components/paymentfield.html +8 -8
  200. package/.server/server/plugins/engine/views/components/ukaddressfield.html +4 -4
  201. package/.server/server/plugins/engine/views/confirmation.html +4 -4
  202. package/.server/server/plugins/engine/views/exit.html +4 -4
  203. package/.server/server/plugins/engine/views/file-upload.html +3 -3
  204. package/.server/server/plugins/engine/views/index.html +3 -3
  205. package/.server/server/plugins/engine/views/item-delete.html +1 -1
  206. package/.server/server/plugins/engine/views/partials/form.html +3 -3
  207. package/.server/server/plugins/engine/views/partials/preview-banner.html +4 -4
  208. package/.server/server/plugins/engine/views/partials/warn-missing-notification-email.html +4 -5
  209. package/.server/server/plugins/engine/views/repeat-list-summary.html +4 -4
  210. package/.server/server/plugins/engine/views/summary.html +14 -7
  211. package/.server/server/plugins/map/routes/index.js +1 -1
  212. package/.server/server/plugins/map/routes/index.js.map +1 -1
  213. package/.server/server/plugins/map/types.d.ts +1 -25
  214. package/.server/server/plugins/map/types.js +1 -16
  215. package/.server/server/plugins/map/types.js.map +1 -1
  216. package/.server/server/plugins/nunjucks/enviroment.test.js +10 -0
  217. package/.server/server/plugins/nunjucks/enviroment.test.js.map +1 -1
  218. package/.server/server/plugins/nunjucks/environment.d.ts +8 -0
  219. package/.server/server/plugins/nunjucks/environment.js +13 -0
  220. package/.server/server/plugins/nunjucks/environment.js.map +1 -1
  221. package/.server/server/plugins/nunjucks/filters/answer.js +9 -1
  222. package/.server/server/plugins/nunjucks/filters/answer.js.map +1 -1
  223. package/.server/server/plugins/nunjucks/filters/answer.test.js +13 -2
  224. package/.server/server/plugins/nunjucks/filters/answer.test.js.map +1 -1
  225. package/.server/server/plugins/nunjucks/filters/field.d.ts +1 -1
  226. package/.server/server/plugins/postcode-lookup/models/index.d.ts +24 -19
  227. package/.server/server/plugins/postcode-lookup/models/index.js +83 -76
  228. package/.server/server/plugins/postcode-lookup/models/index.js.map +1 -1
  229. package/.server/server/plugins/postcode-lookup/routes/index.js +7 -13
  230. package/.server/server/plugins/postcode-lookup/routes/index.js.map +1 -1
  231. package/.server/server/plugins/postcode-lookup/types.d.ts +1 -0
  232. package/.server/server/plugins/postcode-lookup/types.js +1 -0
  233. package/.server/server/plugins/postcode-lookup/types.js.map +1 -1
  234. package/.server/server/plugins/postcode-lookup/views/postcode-lookup-details.html +3 -3
  235. package/.server/server/types.d.ts +2 -1
  236. package/.server/server/types.js.map +1 -1
  237. package/.server/server/utils/utils.d.ts +5 -0
  238. package/.server/server/utils/utils.js +16 -0
  239. package/.server/server/utils/utils.js.map +1 -1
  240. package/.server/typings/hapi/index.d.js.map +1 -1
  241. package/package.json +5 -4
  242. package/src/client/javascripts/geospatial-map.js +10 -6
  243. package/src/client/javascripts/location-map.js +11 -0
  244. package/src/client/javascripts/map.js +10 -0
  245. package/src/client/javascripts/sssi-dataset.js +106 -0
  246. package/src/client/stylesheets/shared.scss +0 -2
  247. package/src/server/forms/register-as-a-unicorn-breeder.yaml +0 -14
  248. package/src/server/forms/simple-form.yaml +106 -3
  249. package/src/server/plugins/engine/components/AutocompleteField.ts +3 -6
  250. package/src/server/plugins/engine/components/CheckboxesField.ts +12 -11
  251. package/src/server/plugins/engine/components/ComponentCollection.ts +143 -61
  252. package/src/server/plugins/engine/components/DatePartsField.ts +33 -11
  253. package/src/server/plugins/engine/components/DeclarationField.ts +37 -14
  254. package/src/server/plugins/engine/components/EastingNorthingField.ts +83 -22
  255. package/src/server/plugins/engine/components/EmailAddressField.ts +4 -7
  256. package/src/server/plugins/engine/components/FileUploadField.ts +28 -22
  257. package/src/server/plugins/engine/components/FormComponent.ts +49 -12
  258. package/src/server/plugins/engine/components/GeospatialField.ts +38 -21
  259. package/src/server/plugins/engine/components/LatLongField.ts +52 -21
  260. package/src/server/plugins/engine/components/ListFormComponent.ts +26 -10
  261. package/src/server/plugins/engine/components/LocationFieldBase.ts +5 -8
  262. package/src/server/plugins/engine/components/LocationFieldHelpers.ts +24 -4
  263. package/src/server/plugins/engine/components/Markdown.ts +7 -3
  264. package/src/server/plugins/engine/components/MonthYearField.ts +32 -10
  265. package/src/server/plugins/engine/components/MultilineTextField.ts +5 -8
  266. package/src/server/plugins/engine/components/NationalGridFieldNumberField.ts +25 -11
  267. package/src/server/plugins/engine/components/NumberField.ts +3 -4
  268. package/src/server/plugins/engine/components/OsGridRefField.ts +25 -9
  269. package/src/server/plugins/engine/components/PaymentField.ts +22 -12
  270. package/src/server/plugins/engine/components/SelectField.ts +3 -6
  271. package/src/server/plugins/engine/components/SelectionControlField.ts +7 -8
  272. package/src/server/plugins/engine/components/TelephoneNumberField.ts +4 -7
  273. package/src/server/plugins/engine/components/UkAddressField.ts +33 -18
  274. package/src/server/plugins/engine/components/YesNoField.ts +10 -0
  275. package/src/server/plugins/engine/components/helpers/components.ts +13 -6
  276. package/src/server/plugins/engine/components/types.ts +9 -0
  277. package/src/server/plugins/engine/configureEnginePlugin.ts +12 -1
  278. package/src/server/plugins/engine/form-context.ts +8 -2
  279. package/src/server/plugins/engine/helpers.ts +10 -18
  280. package/src/server/plugins/engine/i18n/buildValidationMessages.ts +69 -0
  281. package/src/server/plugins/engine/i18n/createFormTranslator.ts +33 -0
  282. package/src/server/plugins/engine/i18n/createTranslator.ts +61 -0
  283. package/src/server/plugins/engine/i18n/extractBaseTranslations.ts +61 -0
  284. package/src/server/plugins/engine/i18n/index.ts +80 -0
  285. package/src/server/plugins/engine/i18n/translations/cy.json +271 -0
  286. package/src/server/plugins/engine/i18n/translations/en-GB.json +271 -0
  287. package/src/server/plugins/engine/i18n/types.ts +62 -0
  288. package/src/server/plugins/engine/index.ts +4 -2
  289. package/src/server/plugins/engine/models/FormModel.ts +59 -23
  290. package/src/server/plugins/engine/models/SummaryViewModel.ts +68 -25
  291. package/src/server/plugins/engine/options.js +2 -1
  292. package/src/server/plugins/engine/outputFormatters/adapter/v1.ts +5 -0
  293. package/src/server/plugins/engine/outputFormatters/human/v1.ts +2 -3
  294. package/src/server/plugins/engine/outputFormatters/machine/v1.ts +9 -8
  295. package/src/server/plugins/engine/pageControllers/FileUploadPageController.ts +7 -3
  296. package/src/server/plugins/engine/pageControllers/PageController.ts +12 -1
  297. package/src/server/plugins/engine/pageControllers/QuestionPageController.ts +53 -21
  298. package/src/server/plugins/engine/pageControllers/RepeatPageController.ts +66 -29
  299. package/src/server/plugins/engine/pageControllers/StartPageController.ts +7 -2
  300. package/src/server/plugins/engine/pageControllers/StatusPageController.ts +10 -2
  301. package/src/server/plugins/engine/pageControllers/SummaryPageController.ts +48 -22
  302. package/src/server/plugins/engine/pageControllers/__stubs__/translator.ts +28 -0
  303. package/src/server/plugins/engine/pageControllers/errors.ts +4 -2
  304. package/src/server/plugins/engine/pageControllers/helpers/submission.ts +11 -4
  305. package/src/server/plugins/engine/pageControllers/validationOptions.ts +43 -53
  306. package/src/server/plugins/engine/plugin.ts +2 -0
  307. package/src/server/plugins/engine/routes/index.ts +9 -1
  308. package/src/server/plugins/engine/routes/questions.ts +5 -1
  309. package/src/server/plugins/engine/types/index.ts +5 -0
  310. package/src/server/plugins/engine/types/schema.ts +1 -0
  311. package/src/server/plugins/engine/types.ts +10 -0
  312. package/src/server/plugins/engine/views/components/_location-field-base.html +4 -2
  313. package/src/server/plugins/engine/views/components/fileuploadfield.html +3 -3
  314. package/src/server/plugins/engine/views/components/geospatialfield.html +4 -1
  315. package/src/server/plugins/engine/views/components/nationalgridfieldnumberfield.html +1 -1
  316. package/src/server/plugins/engine/views/components/osgridreffield.html +1 -1
  317. package/src/server/plugins/engine/views/components/paymentfield.html +8 -8
  318. package/src/server/plugins/engine/views/components/ukaddressfield.html +4 -4
  319. package/src/server/plugins/engine/views/confirmation.html +4 -4
  320. package/src/server/plugins/engine/views/exit.html +4 -4
  321. package/src/server/plugins/engine/views/file-upload.html +3 -3
  322. package/src/server/plugins/engine/views/index.html +3 -3
  323. package/src/server/plugins/engine/views/item-delete.html +1 -1
  324. package/src/server/plugins/engine/views/partials/form.html +3 -3
  325. package/src/server/plugins/engine/views/partials/preview-banner.html +4 -4
  326. package/src/server/plugins/engine/views/partials/warn-missing-notification-email.html +4 -5
  327. package/src/server/plugins/engine/views/repeat-list-summary.html +4 -4
  328. package/src/server/plugins/engine/views/summary.html +14 -7
  329. package/src/server/plugins/map/routes/index.js +1 -1
  330. package/src/server/plugins/map/types.js +1 -16
  331. package/src/server/plugins/nunjucks/environment.js +14 -0
  332. package/src/server/plugins/nunjucks/filters/answer.js +12 -1
  333. package/src/server/plugins/postcode-lookup/models/index.js +144 -87
  334. package/src/server/plugins/postcode-lookup/routes/index.js +13 -16
  335. package/src/server/plugins/postcode-lookup/types.js +1 -0
  336. package/src/server/plugins/postcode-lookup/views/postcode-lookup-details.html +3 -3
  337. package/src/server/types.ts +2 -0
  338. package/src/server/utils/utils.js +14 -0
  339. package/src/typings/hapi/index.d.ts +1 -0
  340. package/.public/javascripts/im-search-plugin.min.js +0 -2
  341. package/.public/javascripts/im-search-plugin.min.js.map +0 -1
  342. package/.public/javascripts/vendor/preact.min.js +0 -2
  343. package/.public/javascripts/vendor/preact.min.js.map +0 -1
  344. package/.server/server/plugins/engine/components/constants.d.ts +0 -1
  345. package/.server/server/plugins/engine/components/constants.js +0 -2
  346. package/.server/server/plugins/engine/components/constants.js.map +0 -1
  347. package/src/server/plugins/engine/components/constants.ts +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"QuestionPageController.js","names":["ComponentType","ControllerType","Engine","hasComponents","hasNext","hasRepeater","isPaymentPage","Boom","COMPONENT_STATE_ERROR","EXTERNAL_STATE_APPENDAGE","EXTERNAL_STATE_PAYLOAD","PAYMENT_EXPIRED_NOTIFICATION","ComponentCollection","PaymentField","optionalText","checkFormStatus","getCacheService","getErrors","getSaveAndExitHelpers","normalisePath","proceed","PageController","prefillStateFromQueryParameters","getComponentsByType","formatCurrency","FormAction","FormStatus","actionSchema","crumbSchema","paramsSchema","merge","QuestionPageController","collection","errorSummaryTitle","allowSaveAndExit","constructor","model","pageDef","components","page","formSchema","keys","crumb","action","next","def","filter","path","linkPath","pages","some","pagePath","allowContinue","engine","V2","controller","Terminal","length","getItemId","request","itemId","getFormParams","params","getViewModel","context","viewModel","query","payload","errors","pageTitle","showTitle","formComponents","isFormComponent","fieldset","label","isPageHeading","labelOrLegend","legend","size","classes","isOptional","fields","at","options","required","text","comp","paymentField","find","f","resolvedAmount","resolveAmount","evaluationState","amount","hasIncompletePayment","paymentState","preAuth","status","backLink","getBackLink","shouldShowSaveAndExit","server","showSubmitButton","getRelevantPath","paths","startPath","getStartPath","relevantPath","getNextPath","summaryPath","getSummaryPath","statusPath","getStatusPath","defaultPath","undefined","pageIndex","indexOf","nextPage","slice","condition","conditionResult","fn","nextLink","link","conditions","getFormDataFromState","state","result","validate","abortEarly","stripUnknown","value","getStateFromValidForm","details","getState","cacheService","setState","mergeState","update","updated","filterConditionalComponents","filtered","component","content","type","Details","map","evaluatedComponent","Array","isArray","item","items","makeGetRouteHandler","h","viewName","redirect","url","pathname","getViewErrors","flashedError","yar","flash","flashedErrors","concat","paymentExpiredFlash","showPaymentExpiredNotification","hasMissingNotificationEmail","view","isForceAccess","formsService","services","getFormMetadata","includes","notificationEmail","slug","returnUrl","href","backPath","endsWith","getHref","makePostRouteHandler","startsWith","External","dispatchExternal","SaveAndExit","handleSaveAndExit","externalComponents","externalActionsWithArgs","split","externalActionArgs","arg","args","Object","fromEntries","componentName","componentDefMap","get","componentType","internal","selectedComponent","stashedPayload","clear","isPreview","isLive","Live","dispatcher","sourceUrl","search","actionArgs","nextPath","nextUrl","saveAndExit","getRouteOptions","ext","onPostHandler","method","_request","continue","postRouteOptions","parse","maxBytes","Number","MAX_SAFE_INTEGER","failAction"],"sources":["../../../../../src/server/plugins/engine/pageControllers/QuestionPageController.ts"],"sourcesContent":["import {\n ComponentType,\n ControllerType,\n Engine,\n hasComponents,\n hasNext,\n hasRepeater,\n isPaymentPage,\n type Link,\n type Page\n} from '@defra/forms-model'\nimport Boom from '@hapi/boom'\nimport { type RouteOptions } from '@hapi/hapi'\nimport { type ValidationErrorItem } from 'joi'\n\nimport {\n COMPONENT_STATE_ERROR,\n EXTERNAL_STATE_APPENDAGE,\n EXTERNAL_STATE_PAYLOAD,\n PAYMENT_EXPIRED_NOTIFICATION\n} from '~/src/server/constants.js'\nimport { ComponentCollection } from '~/src/server/plugins/engine/components/ComponentCollection.js'\nimport { PaymentField } from '~/src/server/plugins/engine/components/PaymentField.js'\nimport { optionalText } from '~/src/server/plugins/engine/components/constants.js'\nimport { type BackLink } from '~/src/server/plugins/engine/components/types.js'\nimport {\n checkFormStatus,\n getCacheService,\n getErrors,\n getSaveAndExitHelpers,\n normalisePath,\n proceed\n} from '~/src/server/plugins/engine/helpers.js'\nimport { type FormModel } from '~/src/server/plugins/engine/models/index.js'\nimport { PageController } from '~/src/server/plugins/engine/pageControllers/PageController.js'\nimport { prefillStateFromQueryParameters } from '~/src/server/plugins/engine/pageControllers/helpers/state.js'\nimport {\n type AnyFormRequest,\n type FormContext,\n type FormContextRequest,\n type FormPageViewModel,\n type FormPayload,\n type FormPayloadParams,\n type FormState,\n type FormStateValue,\n type FormSubmissionState\n} from '~/src/server/plugins/engine/types.js'\nimport { getComponentsByType } from '~/src/server/plugins/engine/validationHelpers.js'\nimport { formatCurrency } from '~/src/server/plugins/payment/helper.js'\nimport {\n FormAction,\n FormStatus,\n type FormRequest,\n type FormRequestPayload,\n type FormRequestPayloadRefs,\n type FormRequestRefs,\n type FormResponseToolkit\n} from '~/src/server/routes/types.js'\nimport {\n actionSchema,\n crumbSchema,\n paramsSchema\n} from '~/src/server/schemas/index.js'\nimport { merge } from '~/src/server/services/cacheService.js'\n\nexport class QuestionPageController extends PageController {\n collection: ComponentCollection\n errorSummaryTitle = 'There is a problem'\n allowSaveAndExit = true\n\n constructor(model: FormModel, pageDef: Page) {\n super(model, pageDef)\n\n // Components collection\n this.collection = new ComponentCollection(\n hasComponents(pageDef) ? pageDef.components : [],\n { model, page: this }\n )\n\n this.collection.formSchema = this.collection.formSchema.keys({\n crumb: crumbSchema,\n action: actionSchema\n })\n }\n\n get next(): Link[] {\n const { def, pageDef } = this\n\n if (!hasNext(pageDef)) {\n return []\n }\n\n // Remove stale links\n return pageDef.next.filter(({ path }) => {\n const linkPath = normalisePath(path)\n\n return def.pages.some((page) => {\n const pagePath = normalisePath(page.path)\n return pagePath === linkPath\n })\n })\n }\n\n get allowContinue(): boolean {\n if (this.model.engine === Engine.V2) {\n return this.pageDef.controller !== ControllerType.Terminal\n }\n\n return this.next.length > 0\n }\n\n getItemId(request?: FormContextRequest) {\n const { itemId } = this.getFormParams(request)\n return itemId ?? request?.params.itemId\n }\n\n /**\n * Used for mapping form payloads and errors to govuk-frontend's template api, so a page can be rendered\n * @param request - the hapi request\n * @param context - the form context\n */\n getViewModel(\n request: FormContextRequest,\n context: FormContext\n ): FormPageViewModel {\n const { collection, viewModel } = this\n const { query } = request\n const { payload, errors } = context\n\n let { pageTitle, showTitle } = viewModel\n\n const components = collection.getViewModel(payload, errors, query)\n const formComponents = components.filter(\n ({ isFormComponent }) => isFormComponent\n )\n\n // Single form component? Hide title and customise label or legend instead\n if (formComponents.length === 1) {\n const { model } = formComponents[0]\n const { fieldset, label } = model\n\n // Set as page heading when not following other content\n const isPageHeading = formComponents[0] === components[0]\n\n // Check for legend or label\n const labelOrLegend = fieldset?.legend ?? label\n\n // Use legend or label as page heading\n if (labelOrLegend) {\n const size = isPageHeading ? 'l' : 'm'\n\n labelOrLegend.classes =\n labelOrLegend === label\n ? `govuk-label--${size}`\n : `govuk-fieldset__legend--${size}`\n\n if (isPageHeading) {\n labelOrLegend.isPageHeading = isPageHeading\n\n // Check for optional in label\n const isOptional =\n this.collection.fields.at(0)?.options.required === false\n\n if (pageTitle) {\n labelOrLegend.text = isOptional\n ? `${pageTitle}${optionalText}`\n : pageTitle\n }\n\n pageTitle = pageTitle || labelOrLegend.text\n }\n }\n\n showTitle = !isPageHeading\n } else if (formComponents.length > 1) {\n // When there is more than one form component,\n // adjust the label/legends to give equal prominence\n for (const { model } of formComponents) {\n if (model.fieldset?.legend) {\n model.fieldset.legend.classes = 'govuk-fieldset__legend--m'\n }\n if (model.label) {\n model.label.classes = 'govuk-label--m'\n }\n }\n }\n\n // Override payment amount display with resolved conditional amount\n // getViewModel() only has the current page's payload, not full form state.\n // The full state is available via context.evaluationState.\n for (const comp of components) {\n if ('amount' in comp.model && 'paymentState' in comp.model) {\n const paymentField = this.collection.fields.find(\n (f): f is PaymentField => f instanceof PaymentField\n )\n if (paymentField) {\n const resolvedAmount = PaymentField.resolveAmount(\n paymentField.options,\n this.model,\n context.evaluationState\n )\n comp.model.amount = formatCurrency(resolvedAmount)\n }\n }\n }\n\n const hasIncompletePayment = components.some(({ model }) => {\n if ('paymentState' in model) {\n const paymentState = model.paymentState as\n | { preAuth?: { status?: string } }\n | undefined\n return !paymentState?.preAuth?.status\n }\n return false\n })\n\n return {\n ...viewModel,\n backLink: this.getBackLink(request, context),\n context,\n showTitle,\n components,\n errors,\n allowSaveAndExit:\n this.shouldShowSaveAndExit(request.server) &&\n !isPaymentPage(this.pageDef),\n showSubmitButton: !hasIncompletePayment\n }\n }\n\n getRelevantPath(request: AnyFormRequest, context: FormContext) {\n const { paths } = context\n\n const startPath = this.getStartPath()\n const relevantPath = paths.at(-1) ?? startPath\n\n return !paths.length\n ? startPath // First possible path\n : relevantPath // Last possible path\n }\n\n /**\n * Apply conditions to evaluation state to determine next page path\n */\n getNextPath(context: FormContext) {\n const { model, next, path } = this\n const { evaluationState } = context\n\n const summaryPath = this.getSummaryPath()\n const statusPath = this.getStatusPath()\n\n // Walk from summary page (no next links) to status page\n let defaultPath = path === summaryPath ? statusPath : undefined\n\n if (model.engine === Engine.V2) {\n if (this.pageDef.controller !== ControllerType.Terminal) {\n const { pages } = this.model\n const pageIndex = pages.indexOf(this)\n\n // The \"next\" page is the first found after the current which is\n // either unconditional or has a condition that evaluates to \"true\"\n const nextPage = pages.slice(pageIndex + 1).find((page) => {\n const { condition } = page\n\n if (condition) {\n const conditionResult = condition.fn(evaluationState)\n\n if (!conditionResult) {\n return false\n }\n }\n\n // Skip payment pages in the normal page walk.\n // Users reach the payment page via \"Pay and submit\" on CYA,\n // not by navigating forward through the form.\n if (isPaymentPage(page.pageDef)) {\n return false\n }\n\n return true\n })\n\n return nextPage?.path ?? defaultPath\n } else {\n return defaultPath\n }\n }\n\n const nextLink = next.find((link) => {\n const { condition } = link\n\n if (condition) {\n return model.conditions[condition]?.fn(evaluationState) ?? false\n }\n\n defaultPath = link.path\n return false\n })\n\n return nextLink?.path ?? defaultPath\n }\n\n /**\n * Gets the form payload (from state) for this page only\n */\n getFormDataFromState(\n request: FormContextRequest | undefined,\n state: FormSubmissionState\n ): FormPayload {\n const { collection } = this\n\n // Form params from request\n const params = this.getFormParams(request)\n\n // Form payload from state\n const payload = collection.getFormDataFromState(state)\n\n return {\n ...params,\n ...payload\n }\n }\n\n /**\n * Gets form params (from payload) for this page only\n */\n getFormParams(request?: FormContextRequest): FormPayloadParams {\n const { payload } = request ?? {}\n\n const result = paramsSchema.validate(payload, {\n abortEarly: false,\n stripUnknown: true\n })\n\n return result.value as FormPayloadParams\n }\n\n getStateFromValidForm(\n request: FormContextRequest,\n state: FormSubmissionState,\n payload: FormPayload\n ): FormState {\n return this.collection.getStateFromValidForm(payload)\n }\n\n getErrors(details?: ValidationErrorItem[]) {\n return getErrors(details)\n }\n\n async getState(request: AnyFormRequest) {\n const { query } = request\n\n // Skip get for preview URL direct access\n if ('force' in query) {\n return {}\n }\n\n const cacheService = getCacheService(request.server)\n\n return cacheService.getState(request)\n }\n\n async setState(request: AnyFormRequest, state: FormSubmissionState) {\n const { query } = request\n\n // Skip set for preview URL direct access\n if ('force' in query) {\n return state\n }\n\n const cacheService = getCacheService(request.server)\n\n return cacheService.setState(request, state)\n }\n\n async mergeState(\n request: AnyFormRequest,\n state: FormSubmissionState,\n update: object\n ) {\n const { query } = request\n\n // Merge state before set\n const updated = merge(state, update)\n\n // Skip set for preview URL direct access\n if ('force' in query) {\n return updated\n }\n\n const cacheService = getCacheService(request.server)\n\n return cacheService.setState(request, updated)\n }\n\n filterConditionalComponents(\n viewModel: FormPageViewModel,\n model: FormModel,\n evaluationState: Partial<Record<string, FormStateValue>>\n ) {\n // Filter our components based on their conditions using our evaluated state\n let filtered = viewModel.components.filter((component) => {\n if (\n (!!component.model.content ||\n component.type === ComponentType.Details) &&\n component.model.condition\n ) {\n const condition = model.conditions[component.model.condition]\n return condition?.fn(evaluationState)\n }\n return true\n })\n\n /**\n * For conditional reveal components (which we no longer support until GDS resolves the related accessibility issues {@link https://github.com/alphagov/govuk-frontend/issues/1991}\n */\n filtered = filtered.map((component) => {\n const evaluatedComponent = component\n const content = evaluatedComponent.model.content\n if (Array.isArray(content)) {\n evaluatedComponent.model.content = content.filter((item) =>\n item.condition\n ? model.conditions[item.condition]?.fn(evaluationState)\n : true\n )\n }\n // apply condition to items for radios, checkboxes etc\n const items = evaluatedComponent.model.items\n\n if (Array.isArray(items)) {\n evaluatedComponent.model.items = items.filter((item) =>\n item.condition\n ? model.conditions[item.condition]?.fn(evaluationState)\n : true\n )\n }\n\n return evaluatedComponent\n })\n\n return filtered\n }\n\n makeGetRouteHandler() {\n return async (\n request: FormRequest,\n context: FormContext,\n h: FormResponseToolkit\n ) => {\n const { collection, model, viewName } = this\n const { evaluationState } = context\n\n // Copy any URL params into the form state (if not already done so)\n if (await prefillStateFromQueryParameters(request, this)) {\n // Forward to same page without query string\n return h.redirect(request.url.pathname)\n }\n\n const viewModel = this.getViewModel(request, context)\n viewModel.errors = collection.getViewErrors(viewModel.errors)\n\n const flashedError = request.yar.flash(COMPONENT_STATE_ERROR)\n const flashedErrors = !Array.isArray(flashedError) ? [flashedError] : []\n\n viewModel.errors = (viewModel.errors ?? []).concat(flashedErrors)\n\n const paymentExpiredFlash = request.yar.flash(\n PAYMENT_EXPIRED_NOTIFICATION\n )\n viewModel.showPaymentExpiredNotification =\n !Array.isArray(paymentExpiredFlash)\n\n /**\n * Content components can be hidden based on a condition. If the condition evaluates to true, it is safe to be kept, otherwise discard it\n */\n\n // Filter our components based on their conditions using our evaluated state\n viewModel.components = this.filterConditionalComponents(\n viewModel,\n model,\n evaluationState\n )\n\n viewModel.hasMissingNotificationEmail =\n await this.hasMissingNotificationEmail(request, context)\n\n return h.view(viewName, viewModel)\n }\n }\n\n async hasMissingNotificationEmail(\n request: FormRequest,\n context: FormContext\n ) {\n const { path } = this\n const { params } = request\n const { isForceAccess } = context\n\n const startPath = this.getStartPath()\n const summaryPath = this.getSummaryPath()\n const { formsService } = this.model.services\n const { getFormMetadata } = formsService\n\n // Warn the user if the form has no notification email set only on start page and summary page\n if ([startPath, summaryPath].includes(path) && !isForceAccess) {\n const { notificationEmail } = await getFormMetadata(params.slug)\n return !notificationEmail\n }\n\n return false\n }\n\n /**\n * Get the back link for a given progress.\n */\n protected getBackLink(\n request: FormContextRequest,\n context: FormContext\n ): BackLink | undefined {\n const { pageDef } = this\n const { path, query } = request\n const { returnUrl } = query\n const { paths } = context\n\n const itemId = this.getItemId(request)\n\n // Check answers back link\n if (returnUrl) {\n return {\n text:\n hasRepeater(pageDef) && itemId\n ? 'Go back to add another'\n : 'Go back to check answers',\n href: returnUrl\n }\n }\n\n // Item delete pages etc\n const backPath =\n itemId && !path.endsWith(itemId)\n ? paths.at(-1) // Back to main page\n : paths.at(-2) // Back to previous page\n\n // No back link\n if (!backPath) {\n return\n }\n\n // Default back link\n return {\n text: 'Back',\n href: this.getHref(backPath)\n }\n }\n\n makePostRouteHandler() {\n return async (\n request: FormRequestPayload,\n context: FormContext,\n h: FormResponseToolkit\n ) => {\n const { collection, viewName, model } = this\n const { isForceAccess, state, evaluationState } = context\n const action = request.payload.action\n\n if (action?.startsWith(FormAction.External)) {\n return await this.dispatchExternal(request, h, context)\n }\n\n /**\n * If there are any errors, render the page with the parsed errors\n * @todo Refactor to match POST REDIRECT GET pattern\n */\n if (context.errors || isForceAccess) {\n const viewModel = this.getViewModel(request, context)\n viewModel.errors = collection.getViewErrors(viewModel.errors)\n\n // Filter our components based on their conditions using our evaluated state\n viewModel.components = this.filterConditionalComponents(\n viewModel,\n model,\n evaluationState\n )\n\n return h.view(viewName, viewModel)\n }\n\n // Save state\n await this.setState(request, state)\n\n // Check if this is a save-and-exit action\n if (action === FormAction.SaveAndExit) {\n return this.handleSaveAndExit(request, context, h)\n }\n\n // Proceed to the next page\n return this.proceed(request, h, this.getNextPath(context))\n }\n }\n\n private async dispatchExternal(\n request: FormRequestPayload,\n h: FormResponseToolkit,\n context: FormContext\n ) {\n const { externalComponents } = getComponentsByType()\n const action = request.payload.action ?? ''\n\n // Find the external action and arguments\n // `external-{componentName}--{argname1}:{argvalue1}--{argname2}:{argvalue2}`\n // E.g. external-abcdef--amount:10--step:manual\n const externalActionsWithArgs = action\n .slice(`${FormAction.External}-`.length)\n .split('--')\n\n const externalActionArgs = externalActionsWithArgs\n .slice(1)\n .map((arg) => arg.split(':'))\n\n const args = Object.fromEntries(externalActionArgs) as Record<\n string,\n string\n >\n\n const componentName = externalActionsWithArgs[0]\n const component = this.model.componentDefMap.get(componentName)\n const componentType = component?.type\n\n if (!componentType) {\n throw Boom.internal(\n `External component of type ${componentType} not found`\n )\n }\n\n const selectedComponent = externalComponents.get(componentType)\n\n if (!selectedComponent) {\n throw Boom.internal(`External component ${componentName} not found`)\n }\n\n // Stash payload without crumb and action\n const stashedPayload = {\n ...context.payload,\n crumb: undefined,\n action: undefined\n }\n request.yar.flash(EXTERNAL_STATE_PAYLOAD, stashedPayload, true)\n\n // Clear any previous state appendage\n request.yar.clear(EXTERNAL_STATE_APPENDAGE)\n\n // Determine if this is a live form (not preview/draft)\n const { state, isPreview } = checkFormStatus(request.params)\n const isLive = state === FormStatus.Live\n\n return await selectedComponent.dispatcher(request, h, {\n component,\n controller: this,\n sourceUrl: `${request.url.pathname}${request.url.search}`,\n actionArgs: args,\n isLive,\n isPreview\n })\n }\n\n proceed(\n request: FormContextRequest,\n h: FormResponseToolkit,\n nextPath?: string\n ) {\n const nextUrl = nextPath\n ? this.getHref(nextPath) // Redirect to next page\n : this.href // Redirect to current page (refresh)\n\n return proceed(request, h, nextUrl)\n }\n\n /**\n * Handle save-and-exit action\n */\n handleSaveAndExit(\n request: FormRequestPayload,\n context: FormContext,\n h: FormResponseToolkit\n ) {\n const saveAndExit = getSaveAndExitHelpers(request.server)\n\n if (!saveAndExit) {\n throw Boom.internal('Server misconfigured for save and exit')\n }\n\n return saveAndExit(request, h, context)\n }\n\n /**\n * {@link https://hapi.dev/api/?v=20.1.2#route-options}\n */\n get getRouteOptions(): RouteOptions<FormRequestRefs> {\n return {\n ext: {\n onPostHandler: {\n method(_request, h) {\n return h.continue\n }\n }\n }\n }\n }\n\n /**\n * {@link https://hapi.dev/api/?v=20.1.2#route-options}\n */\n get postRouteOptions(): RouteOptions<FormRequestPayloadRefs> {\n return {\n payload: {\n parse: true,\n maxBytes: Number.MAX_SAFE_INTEGER,\n failAction: 'ignore'\n },\n ext: {\n onPostHandler: {\n method(_request, h) {\n return h.continue\n }\n }\n }\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"QuestionPageController.js","names":["ComponentType","ControllerType","Engine","hasComponents","hasNext","hasRepeater","isPaymentPage","Boom","COMPONENT_STATE_ERROR","EXTERNAL_STATE_APPENDAGE","EXTERNAL_STATE_PAYLOAD","PAYMENT_EXPIRED_NOTIFICATION","ComponentCollection","PaymentField","checkFormStatus","getCacheService","getErrors","getSaveAndExitHelpers","normalisePath","proceed","PageController","prefillStateFromQueryParameters","getComponentsByType","formatCurrency","FormAction","FormStatus","actionSchema","crumbSchema","paramsSchema","merge","QuestionPageController","collection","errorSummaryTitle","allowSaveAndExit","constructor","model","pageDef","components","page","formSchema","keys","crumb","action","next","def","filter","path","linkPath","pages","some","pagePath","allowContinue","engine","V2","controller","Terminal","length","getItemId","request","itemId","getFormParams","params","getViewModel","context","translator","viewModel","payload","errors","t","tPage","tSection","showTitle","sectionTitle","pageTitle","title","section","hideTitle","formComponents","isFormComponent","fieldset","label","isPageHeading","labelOrLegend","legend","size","classes","isOptional","fields","at","options","required","text","comp","paymentField","find","f","resolvedAmount","resolveAmount","evaluationState","amount","hasIncompletePayment","paymentState","preAuth","status","backLink","getBackLink","shouldShowSaveAndExit","server","showSubmitButton","getRelevantPath","paths","startPath","getStartPath","relevantPath","getNextPath","summaryPath","getSummaryPath","statusPath","getStatusPath","defaultPath","undefined","pageIndex","indexOf","nextPage","slice","condition","conditionResult","fn","nextLink","link","conditions","getFormDataFromState","state","result","validate","abortEarly","stripUnknown","value","getStateFromValidForm","details","getState","query","cacheService","setState","mergeState","update","updated","filterConditionalComponents","filtered","component","content","type","Details","map","evaluatedComponent","Array","isArray","item","items","makeGetRouteHandler","h","viewName","getTranslator","redirect","url","pathname","getViewErrors","flashedError","yar","flash","flashedErrors","concat","paymentExpiredFlash","showPaymentExpiredNotification","hasMissingNotificationEmail","view","isForceAccess","formsService","services","getFormMetadata","includes","notificationEmail","slug","returnUrl","href","backPath","endsWith","getHref","makePostRouteHandler","startsWith","External","dispatchExternal","SaveAndExit","handleSaveAndExit","externalComponents","externalActionsWithArgs","split","externalActionArgs","arg","args","Object","fromEntries","componentName","componentDefMap","get","componentType","internal","selectedComponent","stashedPayload","clear","isPreview","isLive","Live","dispatcher","sourceUrl","search","actionArgs","nextPath","nextUrl","saveAndExit","getRouteOptions","ext","onPostHandler","method","_request","continue","postRouteOptions","parse","maxBytes","Number","MAX_SAFE_INTEGER","failAction"],"sources":["../../../../../src/server/plugins/engine/pageControllers/QuestionPageController.ts"],"sourcesContent":["import {\n ComponentType,\n ControllerType,\n Engine,\n hasComponents,\n hasNext,\n hasRepeater,\n isPaymentPage,\n type Link,\n type Page\n} from '@defra/forms-model'\nimport Boom from '@hapi/boom'\nimport { type RouteOptions } from '@hapi/hapi'\nimport { type ValidationErrorItem } from 'joi'\n\nimport {\n COMPONENT_STATE_ERROR,\n EXTERNAL_STATE_APPENDAGE,\n EXTERNAL_STATE_PAYLOAD,\n PAYMENT_EXPIRED_NOTIFICATION\n} from '~/src/server/constants.js'\nimport { ComponentCollection } from '~/src/server/plugins/engine/components/ComponentCollection.js'\nimport { PaymentField } from '~/src/server/plugins/engine/components/PaymentField.js'\nimport { type BackLink } from '~/src/server/plugins/engine/components/types.js'\nimport {\n checkFormStatus,\n getCacheService,\n getErrors,\n getSaveAndExitHelpers,\n normalisePath,\n proceed\n} from '~/src/server/plugins/engine/helpers.js'\nimport { type Translator } from '~/src/server/plugins/engine/i18n/types.js'\nimport { type FormModel } from '~/src/server/plugins/engine/models/index.js'\nimport { PageController } from '~/src/server/plugins/engine/pageControllers/PageController.js'\nimport { prefillStateFromQueryParameters } from '~/src/server/plugins/engine/pageControllers/helpers/state.js'\nimport {\n type AnyFormRequest,\n type FormContext,\n type FormContextRequest,\n type FormPageViewModel,\n type FormPayload,\n type FormPayloadParams,\n type FormState,\n type FormStateValue,\n type FormSubmissionState\n} from '~/src/server/plugins/engine/types.js'\nimport { getComponentsByType } from '~/src/server/plugins/engine/validationHelpers.js'\nimport { formatCurrency } from '~/src/server/plugins/payment/helper.js'\nimport {\n FormAction,\n FormStatus,\n type FormRequest,\n type FormRequestPayload,\n type FormRequestPayloadRefs,\n type FormRequestRefs,\n type FormResponseToolkit\n} from '~/src/server/routes/types.js'\nimport {\n actionSchema,\n crumbSchema,\n paramsSchema\n} from '~/src/server/schemas/index.js'\nimport { merge } from '~/src/server/services/cacheService.js'\n\nexport class QuestionPageController extends PageController {\n collection: ComponentCollection\n errorSummaryTitle = 'There is a problem'\n allowSaveAndExit = true\n\n constructor(model: FormModel, pageDef: Page) {\n super(model, pageDef)\n\n // Components collection\n this.collection = new ComponentCollection(\n hasComponents(pageDef) ? pageDef.components : [],\n { model, page: this }\n )\n\n this.collection.formSchema = this.collection.formSchema.keys({\n crumb: crumbSchema,\n action: actionSchema\n })\n }\n\n get next(): Link[] {\n const { def, pageDef } = this\n\n if (!hasNext(pageDef)) {\n return []\n }\n\n // Remove stale links\n return pageDef.next.filter(({ path }) => {\n const linkPath = normalisePath(path)\n\n return def.pages.some((page) => {\n const pagePath = normalisePath(page.path)\n return pagePath === linkPath\n })\n })\n }\n\n get allowContinue(): boolean {\n if (this.model.engine === Engine.V2) {\n return this.pageDef.controller !== ControllerType.Terminal\n }\n\n return this.next.length > 0\n }\n\n getItemId(request?: FormContextRequest) {\n const { itemId } = this.getFormParams(request)\n return itemId ?? request?.params.itemId\n }\n\n /**\n * Used for mapping form payloads and errors to govuk-frontend's template api, so a page can be rendered\n * @param request - the hapi request\n * @param context - the form context\n * @param translator - optional per-request translator pair\n */\n getViewModel(\n request: FormContextRequest,\n context: FormContext,\n translator: Translator\n ): FormPageViewModel {\n const { collection, viewModel } = this\n const { payload, errors } = context\n\n const { t, tPage, tSection } = translator\n\n let { showTitle, sectionTitle } = viewModel\n\n let pageTitle = this.pageDef.title ? tPage(this.pageDef, 'title') : ''\n\n if (this.section) {\n sectionTitle =\n this.section.hideTitle !== true ? tSection(this.section, 'title') : ''\n }\n\n const components = collection.getViewModel({ payload, errors, translator })\n const formComponents = components.filter(\n ({ isFormComponent }) => isFormComponent\n )\n\n // Single form component? Hide title and customise label or legend instead\n if (formComponents.length === 1) {\n const { model } = formComponents[0]\n const { fieldset, label } = model\n\n // Set as page heading when not following other content\n const isPageHeading = formComponents[0] === components[0]\n\n // Check for legend or label\n const labelOrLegend = fieldset?.legend ?? label\n\n // Use legend or label as page heading\n if (labelOrLegend) {\n const size = isPageHeading ? 'l' : 'm'\n\n labelOrLegend.classes =\n labelOrLegend === label\n ? `govuk-label--${size}`\n : `govuk-fieldset__legend--${size}`\n\n if (isPageHeading) {\n labelOrLegend.isPageHeading = isPageHeading\n\n // Check for optional in label\n const isOptional =\n this.collection.fields.at(0)?.options.required === false\n\n if (!pageTitle) {\n pageTitle = labelOrLegend.text\n }\n labelOrLegend.text = isOptional\n ? `${pageTitle} ${t('common.optional')}`\n : pageTitle\n }\n\n // Fallback if still no pageTitle set\n if (!pageTitle) {\n pageTitle = labelOrLegend.text\n }\n }\n\n showTitle = !isPageHeading\n } else if (formComponents.length > 1) {\n // When there is more than one form component,\n // adjust the label/legends to give equal prominence\n for (const { model } of formComponents) {\n if (model.fieldset?.legend) {\n model.fieldset.legend.classes = 'govuk-fieldset__legend--m'\n }\n if (model.label) {\n model.label.classes = 'govuk-label--m'\n }\n }\n }\n\n // Override payment amount display with resolved conditional amount\n // getViewModel() only has the current page's payload, not full form state.\n // The full state is available via context.evaluationState.\n for (const comp of components) {\n if ('amount' in comp.model && 'paymentState' in comp.model) {\n const paymentField = this.collection.fields.find(\n (f): f is PaymentField => f instanceof PaymentField\n )\n if (paymentField) {\n const resolvedAmount = PaymentField.resolveAmount(\n paymentField.options,\n this.model,\n context.evaluationState\n )\n comp.model.amount = formatCurrency(resolvedAmount)\n }\n }\n }\n\n const hasIncompletePayment = components.some(({ model }) => {\n if ('paymentState' in model) {\n const paymentState = model.paymentState as\n | { preAuth?: { status?: string } }\n | undefined\n return !paymentState?.preAuth?.status\n }\n return false\n })\n\n return {\n ...viewModel,\n backLink: this.getBackLink(request, context, t),\n context,\n pageTitle,\n sectionTitle,\n showTitle,\n components,\n errors,\n allowSaveAndExit:\n this.shouldShowSaveAndExit(request.server) &&\n !isPaymentPage(this.pageDef),\n showSubmitButton: !hasIncompletePayment\n }\n }\n\n getRelevantPath(request: AnyFormRequest, context: FormContext) {\n const { paths } = context\n\n const startPath = this.getStartPath()\n const relevantPath = paths.at(-1) ?? startPath\n\n return !paths.length\n ? startPath // First possible path\n : relevantPath // Last possible path\n }\n\n /**\n * Apply conditions to evaluation state to determine next page path\n */\n getNextPath(context: FormContext) {\n const { model, next, path } = this\n const { evaluationState } = context\n\n const summaryPath = this.getSummaryPath()\n const statusPath = this.getStatusPath()\n\n // Walk from summary page (no next links) to status page\n let defaultPath = path === summaryPath ? statusPath : undefined\n\n if (model.engine === Engine.V2) {\n if (this.pageDef.controller !== ControllerType.Terminal) {\n const { pages } = this.model\n const pageIndex = pages.indexOf(this)\n\n // The \"next\" page is the first found after the current which is\n // either unconditional or has a condition that evaluates to \"true\"\n const nextPage = pages.slice(pageIndex + 1).find((page) => {\n const { condition } = page\n\n if (condition) {\n const conditionResult = condition.fn(evaluationState)\n\n if (!conditionResult) {\n return false\n }\n }\n\n // Skip payment pages in the normal page walk.\n // Users reach the payment page via \"Pay and submit\" on CYA,\n // not by navigating forward through the form.\n if (isPaymentPage(page.pageDef)) {\n return false\n }\n\n return true\n })\n\n return nextPage?.path ?? defaultPath\n } else {\n return defaultPath\n }\n }\n\n const nextLink = next.find((link) => {\n const { condition } = link\n\n if (condition) {\n return model.conditions[condition]?.fn(evaluationState) ?? false\n }\n\n defaultPath = link.path\n return false\n })\n\n return nextLink?.path ?? defaultPath\n }\n\n /**\n * Gets the form payload (from state) for this page only\n */\n getFormDataFromState(\n request: FormContextRequest | undefined,\n state: FormSubmissionState\n ): FormPayload {\n const { collection } = this\n\n // Form params from request\n const params = this.getFormParams(request)\n\n // Form payload from state\n const payload = collection.getFormDataFromState(state)\n\n return {\n ...params,\n ...payload\n }\n }\n\n /**\n * Gets form params (from payload) for this page only\n */\n getFormParams(request?: FormContextRequest): FormPayloadParams {\n const { payload } = request ?? {}\n\n const result = paramsSchema.validate(payload, {\n abortEarly: false,\n stripUnknown: true\n })\n\n return result.value as FormPayloadParams\n }\n\n getStateFromValidForm(\n request: FormContextRequest,\n state: FormSubmissionState,\n payload: FormPayload\n ): FormState {\n return this.collection.getStateFromValidForm(payload)\n }\n\n getErrors(details?: ValidationErrorItem[]) {\n return getErrors(details)\n }\n\n async getState(request: AnyFormRequest) {\n const { query } = request\n\n // Skip get for preview URL direct access\n if ('force' in query) {\n return {}\n }\n\n const cacheService = getCacheService(request.server)\n\n return cacheService.getState(request)\n }\n\n async setState(request: AnyFormRequest, state: FormSubmissionState) {\n const { query } = request\n\n // Skip set for preview URL direct access\n if ('force' in query) {\n return state\n }\n\n const cacheService = getCacheService(request.server)\n\n return cacheService.setState(request, state)\n }\n\n async mergeState(\n request: AnyFormRequest,\n state: FormSubmissionState,\n update: object\n ) {\n const { query } = request\n\n // Merge state before set\n const updated = merge(state, update)\n\n // Skip set for preview URL direct access\n if ('force' in query) {\n return updated\n }\n\n const cacheService = getCacheService(request.server)\n\n return cacheService.setState(request, updated)\n }\n\n filterConditionalComponents(\n viewModel: FormPageViewModel,\n model: FormModel,\n evaluationState: Partial<Record<string, FormStateValue>>\n ) {\n // Filter our components based on their conditions using our evaluated state\n let filtered = viewModel.components.filter((component) => {\n if (\n (!!component.model.content ||\n component.type === ComponentType.Details) &&\n component.model.condition\n ) {\n const condition = model.conditions[component.model.condition]\n return condition?.fn(evaluationState)\n }\n return true\n })\n\n /**\n * For conditional reveal components (which we no longer support until GDS resolves the related accessibility issues {@link https://github.com/alphagov/govuk-frontend/issues/1991}\n */\n filtered = filtered.map((component) => {\n const evaluatedComponent = component\n const content = evaluatedComponent.model.content\n if (Array.isArray(content)) {\n evaluatedComponent.model.content = content.filter((item) =>\n item.condition\n ? model.conditions[item.condition]?.fn(evaluationState)\n : true\n )\n }\n // apply condition to items for radios, checkboxes etc\n const items = evaluatedComponent.model.items\n\n if (Array.isArray(items)) {\n evaluatedComponent.model.items = items.filter((item) =>\n item.condition\n ? model.conditions[item.condition]?.fn(evaluationState)\n : true\n )\n }\n\n return evaluatedComponent\n })\n\n return filtered\n }\n\n makeGetRouteHandler() {\n return async (\n request: FormRequest,\n context: FormContext,\n h: FormResponseToolkit\n ) => {\n const { collection, model, viewName } = this\n const { evaluationState } = context\n\n const translator = this.getTranslator(request)\n const { t } = translator\n\n // Copy any URL params into the form state (if not already done so)\n if (await prefillStateFromQueryParameters(request, this)) {\n // Forward to same page without query string\n return h.redirect(request.url.pathname)\n }\n\n const viewModel = this.getViewModel(request, context, translator)\n viewModel.errors = collection.getViewErrors(translator, viewModel.errors)\n\n const flashedError = request.yar.flash(COMPONENT_STATE_ERROR)\n const flashedErrors = !Array.isArray(flashedError) ? [flashedError] : []\n\n viewModel.errors = (viewModel.errors ?? []).concat(flashedErrors)\n\n const paymentExpiredFlash = request.yar.flash(\n PAYMENT_EXPIRED_NOTIFICATION\n )\n viewModel.showPaymentExpiredNotification =\n !Array.isArray(paymentExpiredFlash)\n\n /**\n * Content components can be hidden based on a condition. If the condition evaluates to true, it is safe to be kept, otherwise discard it\n */\n\n // Filter our components based on their conditions using our evaluated state\n viewModel.components = this.filterConditionalComponents(\n viewModel,\n model,\n evaluationState\n )\n\n viewModel.hasMissingNotificationEmail =\n await this.hasMissingNotificationEmail(request, context)\n\n return h.view(viewName, {\n ...viewModel,\n t\n })\n }\n }\n\n async hasMissingNotificationEmail(\n request: FormRequest,\n context: FormContext\n ) {\n const { path } = this\n const { params } = request\n const { isForceAccess } = context\n\n const startPath = this.getStartPath()\n const summaryPath = this.getSummaryPath()\n const { formsService } = this.model.services\n const { getFormMetadata } = formsService\n\n // Warn the user if the form has no notification email set only on start page and summary page\n if ([startPath, summaryPath].includes(path) && !isForceAccess) {\n const { notificationEmail } = await getFormMetadata(params.slug)\n return !notificationEmail\n }\n\n return false\n }\n\n /**\n * Get the back link for a given progress.\n */\n protected getBackLink(\n request: FormContextRequest,\n context: FormContext,\n t: (key: string, opts?: Record<string, unknown>) => string\n ): BackLink | undefined {\n const { pageDef } = this\n const { path, query } = request\n const { returnUrl } = query\n const { paths } = context\n\n const itemId = this.getItemId(request)\n\n // Check answers back link\n if (returnUrl) {\n return {\n text:\n hasRepeater(pageDef) && itemId\n ? t('pages.question.backToAddAnother')\n : t('pages.question.backToCheckAnswers'),\n href: returnUrl\n }\n }\n\n // Item delete pages etc\n const backPath =\n itemId && !path.endsWith(itemId)\n ? paths.at(-1) // Back to main page\n : paths.at(-2) // Back to previous page\n\n // No back link\n if (!backPath) {\n return\n }\n\n // Default back link\n return {\n text: t('common.back'),\n href: this.getHref(backPath)\n }\n }\n\n makePostRouteHandler() {\n return async (\n request: FormRequestPayload,\n context: FormContext,\n h: FormResponseToolkit\n ) => {\n const { collection, viewName, model } = this\n const { isForceAccess, state, evaluationState } = context\n const action = request.payload.action\n\n const translator = this.getTranslator(request)\n const { t } = translator\n\n if (action?.startsWith(FormAction.External)) {\n return await this.dispatchExternal(request, h, context)\n }\n\n /**\n * If there are any errors, render the page with the parsed errors\n * @todo Refactor to match POST REDIRECT GET pattern\n */\n if (context.errors || isForceAccess) {\n const viewModel = this.getViewModel(request, context, translator)\n viewModel.errors = collection.getViewErrors(\n translator,\n viewModel.errors\n )\n\n // Filter our components based on their conditions using our evaluated state\n viewModel.components = this.filterConditionalComponents(\n viewModel,\n model,\n evaluationState\n )\n\n return h.view(viewName, {\n ...viewModel,\n t\n })\n }\n\n // Save state\n await this.setState(request, state)\n\n // Check if this is a save-and-exit action\n if (action === FormAction.SaveAndExit) {\n return this.handleSaveAndExit(request, context, h)\n }\n\n // Proceed to the next page\n return this.proceed(request, h, this.getNextPath(context))\n }\n }\n\n private async dispatchExternal(\n request: FormRequestPayload,\n h: FormResponseToolkit,\n context: FormContext\n ) {\n const { externalComponents } = getComponentsByType()\n const action = request.payload.action ?? ''\n\n // Find the external action and arguments\n // `external-{componentName}--{argname1}:{argvalue1}--{argname2}:{argvalue2}`\n // E.g. external-abcdef--amount:10--step:manual\n const externalActionsWithArgs = action\n .slice(`${FormAction.External}-`.length)\n .split('--')\n\n const externalActionArgs = externalActionsWithArgs\n .slice(1)\n .map((arg) => arg.split(':'))\n\n const args = Object.fromEntries(externalActionArgs) as Record<\n string,\n string\n >\n\n const componentName = externalActionsWithArgs[0]\n const component = this.model.componentDefMap.get(componentName)\n const componentType = component?.type\n\n if (!componentType) {\n throw Boom.internal(\n `External component of type ${componentType} not found`\n )\n }\n\n const selectedComponent = externalComponents.get(componentType)\n\n if (!selectedComponent) {\n throw Boom.internal(`External component ${componentName} not found`)\n }\n\n // Stash payload without crumb and action\n const stashedPayload = {\n ...context.payload,\n crumb: undefined,\n action: undefined\n }\n request.yar.flash(EXTERNAL_STATE_PAYLOAD, stashedPayload, true)\n\n // Clear any previous state appendage\n request.yar.clear(EXTERNAL_STATE_APPENDAGE)\n\n // Determine if this is a live form (not preview/draft)\n const { state, isPreview } = checkFormStatus(request.params)\n const isLive = state === FormStatus.Live\n\n return await selectedComponent.dispatcher(request, h, {\n component,\n controller: this,\n sourceUrl: `${request.url.pathname}${request.url.search}`,\n actionArgs: args,\n isLive,\n isPreview\n })\n }\n\n proceed(\n request: FormContextRequest,\n h: FormResponseToolkit,\n nextPath?: string\n ) {\n const nextUrl = nextPath\n ? this.getHref(nextPath) // Redirect to next page\n : this.href // Redirect to current page (refresh)\n\n return proceed(request, h, nextUrl)\n }\n\n /**\n * Handle save-and-exit action\n */\n handleSaveAndExit(\n request: FormRequestPayload,\n context: FormContext,\n h: FormResponseToolkit\n ) {\n const saveAndExit = getSaveAndExitHelpers(request.server)\n\n if (!saveAndExit) {\n throw Boom.internal('Server misconfigured for save and exit')\n }\n\n return saveAndExit(request, h, context)\n }\n\n /**\n * {@link https://hapi.dev/api/?v=20.1.2#route-options}\n */\n get getRouteOptions(): RouteOptions<FormRequestRefs> {\n return {\n ext: {\n onPostHandler: {\n method(_request, h) {\n return h.continue\n }\n }\n }\n }\n }\n\n /**\n * {@link https://hapi.dev/api/?v=20.1.2#route-options}\n */\n get postRouteOptions(): RouteOptions<FormRequestPayloadRefs> {\n return {\n payload: {\n parse: true,\n maxBytes: Number.MAX_SAFE_INTEGER,\n failAction: 'ignore'\n },\n ext: {\n onPostHandler: {\n method(_request, h) {\n return h.continue\n }\n }\n }\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -1,4 +1,5 @@
1
1
  import { type PageRepeat, type Repeat } from '@defra/forms-model';
2
+ import { type Translator } from '../../../../server/plugins/engine/i18n/types.js';
2
3
  import { type FormModel } from '../../../../server/plugins/engine/models/index.js';
3
4
  import { QuestionPageController } from '../../../../server/plugins/engine/pageControllers/QuestionPageController.js';
4
5
  import { type FormContext, type FormContextRequest, type FormPageViewModel, type FormPayload, type FormSubmissionState, type RepeatItemState, type RepeatListState, type RepeaterSummaryPageViewModel } from '../../../../server/plugins/engine/types.js';
@@ -29,7 +30,7 @@ export declare class RepeatPageController extends QuestionPageController {
29
30
  makePostListSummaryRouteHandler(): (request: FormRequestPayload, context: FormContext, h: FormResponseToolkit) => import("@hapi/hapi").ResponseObject;
30
31
  makeGetItemDeleteRouteHandler(): (request: FormRequest, context: FormContext, h: FormResponseToolkit) => import("@hapi/hapi").ResponseObject;
31
32
  makePostItemDeleteRouteHandler(): (request: FormRequestPayload, context: FormContext, h: FormResponseToolkit) => Promise<import("@hapi/hapi").ResponseObject>;
32
- getViewModel(request: FormContextRequest, context: FormContext): FormPageViewModel;
33
- getListSummaryViewModel(request: FormContextRequest, context: FormContext, list: RepeatListState): RepeaterSummaryPageViewModel;
33
+ getViewModel(request: FormContextRequest, context: FormContext, translator: Translator): FormPageViewModel;
34
+ getListSummaryViewModel(request: FormContextRequest, context: FormContext, list: RepeatListState, translator: Translator): RepeaterSummaryPageViewModel;
34
35
  getSummaryPath(request?: FormContextRequest): string;
35
36
  }
@@ -147,8 +147,15 @@ export class RepeatPageController extends QuestionPageController {
147
147
  });
148
148
  return super.proceed(request, h, nextPath);
149
149
  }
150
- const viewModel = this.getListSummaryViewModel(request, context, list);
151
- return h.view(this.listSummaryViewName, viewModel);
150
+ const translator = this.getTranslator(request);
151
+ const {
152
+ t
153
+ } = translator;
154
+ const viewModel = this.getListSummaryViewModel(request, context, list, translator);
155
+ return h.view(this.listSummaryViewName, {
156
+ ...viewModel,
157
+ t
158
+ });
152
159
  };
153
160
  }
154
161
  makePostListSummaryRouteHandler() {
@@ -173,6 +180,10 @@ export class RepeatPageController extends QuestionPageController {
173
180
  });
174
181
  return super.proceed(request, h, nextPath);
175
182
  }
183
+ const translator = this.getTranslator(request);
184
+ const {
185
+ t
186
+ } = translator;
176
187
  const {
177
188
  action
178
189
  } = this.getFormParams(request);
@@ -182,15 +193,21 @@ export class RepeatPageController extends QuestionPageController {
182
193
  // Show error if repeat limits apply
183
194
  if (hasErrorMin || hasErrorMax) {
184
195
  const count = hasErrorMax ? schema.max : schema.min;
185
- const itemTitle = `answer${count === 1 ? '' : 's'}`;
186
196
  context.errors = [{
187
197
  path: [],
188
198
  href: '',
189
199
  name: '',
190
- text: hasErrorMax ? `You can only add up to ${count} ${itemTitle}` : `You must add at least ${count} ${itemTitle}`
200
+ text: hasErrorMax ? t('pages.repeater.tooMany', {
201
+ count
202
+ }) : t('pages.repeater.tooFew', {
203
+ count
204
+ })
191
205
  }];
192
- const viewModel = this.getListSummaryViewModel(request, context, list);
193
- return h.view(this.listSummaryViewName, viewModel);
206
+ const viewModel = this.getListSummaryViewModel(request, context, list, translator);
207
+ return h.view(this.listSummaryViewName, {
208
+ ...viewModel,
209
+ t
210
+ });
194
211
  }
195
212
  if (action === FormAction.AddAnother) {
196
213
  const nextPath = redirectPath(`${path}/${randomUUID()}`, {
@@ -218,8 +235,12 @@ export class RepeatPageController extends QuestionPageController {
218
235
  const list = this.getListFromState(state);
219
236
  const itemId = this.getItemId(request);
220
237
  const item = this.getItemFromList(list, itemId);
238
+ const translator = this.getTranslator(request);
239
+ const {
240
+ t
241
+ } = translator;
221
242
  if (!item || list.length === 1) {
222
- throw Boom.notFound(item ? 'Last list item cannot be removed' : 'List item to remove not found');
243
+ throw Boom.notFound(item ? t('pages.repeater.lastItemCannotBeRemoved') : t('pages.repeater.itemToRemoveNotFound'));
223
244
  }
224
245
  const {
225
246
  title
@@ -227,15 +248,16 @@ export class RepeatPageController extends QuestionPageController {
227
248
  return h.view(this.listDeleteViewName, {
228
249
  ...viewModel,
229
250
  context,
230
- backLink: this.getBackLink(request, context),
231
- pageTitle: 'Are you sure you want to remove this answer?',
251
+ backLink: this.getBackLink(request, context, t),
252
+ pageTitle: t('pages.repeater.removeAnswer'),
232
253
  itemTitle: `${title} ${list.indexOf(item) + 1}`,
233
254
  buttonConfirm: {
234
- text: 'Remove'
255
+ text: t('pages.repeater.remove')
235
256
  },
236
257
  buttonCancel: {
237
- text: 'Cancel'
238
- }
258
+ text: t('pages.repeater.cancel')
259
+ },
260
+ t
239
261
  });
240
262
  };
241
263
  }
@@ -253,8 +275,11 @@ export class RepeatPageController extends QuestionPageController {
253
275
  const list = this.getListFromState(state);
254
276
  const itemId = this.getItemId(request);
255
277
  const item = this.getItemFromList(list, itemId);
278
+ const {
279
+ t
280
+ } = this.getTranslator(request);
256
281
  if (!item || list.length === 1) {
257
- throw Boom.notFound(item ? 'Last list item cannot be removed' : 'List item to remove not found');
282
+ throw Boom.notFound(item ? t('pages.repeater.lastItemCannotBeRemoved') : t('pages.repeater.itemToRemoveNotFound'));
258
283
  }
259
284
 
260
285
  // Remove the item from the list
@@ -268,22 +293,26 @@ export class RepeatPageController extends QuestionPageController {
268
293
  return this.proceed(request, h);
269
294
  };
270
295
  }
271
- getViewModel(request, context) {
296
+ getViewModel(request, context, translator) {
272
297
  const {
273
298
  state
274
299
  } = context;
300
+ const {
301
+ tPage
302
+ } = translator;
275
303
  const list = this.getListFromState(state);
276
304
  const itemId = this.getItemId(request);
277
305
  const item = this.getItemFromList(list, itemId);
278
- const viewModel = super.getViewModel(request, context);
306
+ const viewModel = super.getViewModel(request, context, translator);
279
307
  const itemNumber = item ? list.indexOf(item) + 1 : list.length + 1;
280
- const repeatCaption = `${this.repeat.options.title} ${itemNumber}`;
308
+ const title = tPage(this.pageDef, 'repeatTitle') || this.pageDef.repeat.options.title;
309
+ const repeatCaption = `${title} ${itemNumber}`;
281
310
  return {
282
311
  ...viewModel,
283
312
  sectionTitle: viewModel.sectionTitle ? `${viewModel.sectionTitle}: ${repeatCaption}` : repeatCaption
284
313
  };
285
314
  }
286
- getListSummaryViewModel(request, context, list) {
315
+ getListSummaryViewModel(request, context, list, translator) {
287
316
  const {
288
317
  collection,
289
318
  href,
@@ -296,6 +325,9 @@ export class RepeatPageController extends QuestionPageController {
296
325
  isForceAccess,
297
326
  errors
298
327
  } = context;
328
+ const {
329
+ t
330
+ } = translator;
299
331
  const {
300
332
  title
301
333
  } = repeat.options;
@@ -316,28 +348,32 @@ export class RepeatPageController extends QuestionPageController {
316
348
  href: redirectPath(`${href}/${item.itemId}`, {
317
349
  returnUrl: query.returnUrl ?? this.getHref(summaryPath)
318
350
  }),
319
- text: 'Change',
351
+ text: t('pages.repeater.change'),
320
352
  classes: 'govuk-link--no-visited-state',
321
- visuallyHiddenText: `item ${index + 1}`
353
+ visuallyHiddenText: t('pages.repeater.visuallyHiddenItem', {
354
+ index: index + 1
355
+ })
322
356
  });
323
357
  if (count > 1) {
324
358
  items.push({
325
359
  href: redirectPath(`${href}/${item.itemId}/confirm-delete`, {
326
360
  returnUrl: query.returnUrl
327
361
  }),
328
- text: 'Remove',
362
+ text: t('pages.repeater.remove'),
329
363
  classes: 'govuk-link--no-visited-state',
330
- visuallyHiddenText: `item ${index + 1}`
364
+ visuallyHiddenText: t('pages.repeater.visuallyHiddenItem', {
365
+ index: index + 1
366
+ })
331
367
  });
332
368
  }
333
369
  }
334
- const itemDisplayText = collection.fields.length ? collection.fields[0].getDisplayStringFromState(item) : '';
370
+ const itemDisplayText = collection.fields.length ? collection.fields[0].getDisplayStringFromState(item, translator) : '';
335
371
  summaryList.rows.push({
336
372
  key: {
337
373
  text: `${title} ${index + 1}`
338
374
  },
339
375
  value: {
340
- text: itemDisplayText || 'Not provided'
376
+ text: itemDisplayText || t('pages.repeater.notProvided')
341
377
  },
342
378
  actions: {
343
379
  items
@@ -345,12 +381,13 @@ export class RepeatPageController extends QuestionPageController {
345
381
  });
346
382
  });
347
383
  }
348
- const unit = count === 1 ? 'answer' : 'answers';
349
384
  return {
350
385
  ...this.viewModel,
351
- backLink: this.getBackLink(request, context),
386
+ backLink: this.getBackLink(request, context, t),
352
387
  repeatTitle: title,
353
- pageTitle: `You have added ${count} ${unit}`,
388
+ pageTitle: t('pages.repeater.pageTitle', {
389
+ count
390
+ }),
354
391
  showTitle: true,
355
392
  context,
356
393
  errors,
@@ -1 +1 @@
1
- {"version":3,"file":"RepeatPageController.js","names":["randomUUID","Boom","Joi","isRepeatState","redirectPath","QuestionPageController","FormAction","RepeatPageController","listSummaryViewName","listDeleteViewName","repeat","allowSaveAndExit","constructor","model","pageDef","options","schema","itemId","string","uuid","required","collection","formSchema","append","stateSchema","object","keys","name","array","items","min","max","label","title","getFormParams","request","params","payload","getFormDataFromState","state","list","getListFromState","getItemId","item","getItemFromList","getStateFromValidForm","badRequest","itemState","updated","newList","push","indexOf","proceed","h","nextPath","getSummaryPath","find","values","makeGetRouteHandler","context","path","query","summaryPath","returnUrl","force","length","makeGetListSummaryRouteHandler","viewModel","getListSummaryViewModel","view","makePostListSummaryRouteHandler","action","hasErrorMin","Continue","hasErrorMax","AddAnother","count","itemTitle","errors","href","text","SaveAndExit","handleSaveAndExit","getNextPath","makeGetItemDeleteRouteHandler","notFound","backLink","getBackLink","pageTitle","buttonConfirm","buttonCancel","makePostItemDeleteRouteHandler","confirm","splice","update","mergeState","getViewModel","itemNumber","repeatCaption","sectionTitle","isForceAccess","summaryList","classes","rows","Array","isArray","forEach","index","getHref","visuallyHiddenText","itemDisplayText","fields","getDisplayStringFromState","key","value","actions","unit","repeatTitle","showTitle","checkAnswers","shouldShowSaveAndExit","server"],"sources":["../../../../../src/server/plugins/engine/pageControllers/RepeatPageController.ts"],"sourcesContent":["import { randomUUID } from 'crypto'\n\nimport { type PageRepeat, type Repeat } from '@defra/forms-model'\nimport Boom from '@hapi/boom'\nimport Joi from 'joi'\n\nimport { isRepeatState } from '~/src/server/plugins/engine/components/FormComponent.js'\nimport { redirectPath } from '~/src/server/plugins/engine/helpers.js'\nimport { type FormModel } from '~/src/server/plugins/engine/models/index.js'\nimport { QuestionPageController } from '~/src/server/plugins/engine/pageControllers/QuestionPageController.js'\nimport {\n type FormContext,\n type FormContextRequest,\n type FormPageViewModel,\n type FormPayload,\n type FormSubmissionState,\n type ItemDeletePageViewModel,\n type RepeatItemState,\n type RepeatListState,\n type RepeaterSummaryPageViewModel,\n type SummaryList,\n type SummaryListAction\n} from '~/src/server/plugins/engine/types.js'\nimport {\n FormAction,\n type FormRequest,\n type FormRequestPayload,\n type FormResponseToolkit\n} from '~/src/server/routes/types.js'\n\nexport class RepeatPageController extends QuestionPageController {\n declare pageDef: PageRepeat\n\n listSummaryViewName = 'repeat-list-summary'\n listDeleteViewName = 'item-delete'\n repeat: Repeat\n allowSaveAndExit = true\n\n constructor(model: FormModel, pageDef: PageRepeat) {\n super(model, pageDef)\n\n this.repeat = pageDef.repeat\n\n const { options, schema } = this.repeat\n const itemId = Joi.string().uuid().required()\n\n this.collection.formSchema = this.collection.formSchema.append({ itemId })\n this.collection.stateSchema = Joi.object<RepeatItemState>().keys({\n [options.name]: Joi.array()\n .items(this.collection.stateSchema.append({ itemId }))\n .min(schema.min)\n .max(schema.max)\n .label(`${options.title} list`)\n .required()\n })\n }\n\n get keys() {\n const { repeat } = this\n return [repeat.options.name, ...super.keys]\n }\n\n getFormParams(request?: FormContextRequest) {\n const params = super.getFormParams(request)\n\n // Apply an itemId to the form payload\n if (request?.payload) {\n params.itemId = request.params.itemId ?? randomUUID()\n }\n\n return params\n }\n\n getFormDataFromState(\n request: FormContextRequest | undefined,\n state: FormSubmissionState\n ) {\n const { repeat } = this\n\n const params = this.getFormParams(request)\n const list = this.getListFromState(state)\n const itemId = this.getItemId(request)\n\n // Create payload with repeater list state\n if (!itemId) {\n return {\n ...params,\n [repeat.options.name]: list\n }\n }\n\n // Create payload with repeater item state\n const item = this.getItemFromList(list, itemId)\n\n return {\n ...params,\n ...item\n }\n }\n\n getStateFromValidForm(\n request: FormContextRequest,\n state: FormSubmissionState,\n payload: FormPayload\n ) {\n const itemId = this.getItemId(request)\n\n if (!itemId) {\n throw Boom.badRequest('No item ID found')\n }\n\n const list = this.getListFromState(state)\n const item = this.getItemFromList(list, itemId)\n\n const itemState = super.getStateFromValidForm(request, state, payload)\n const updated: RepeatItemState = { ...itemState, itemId }\n const newList = [...list]\n\n if (!item) {\n // Adding a new item\n newList.push(updated)\n } else {\n // Update an existing item\n newList[list.indexOf(item)] = updated\n }\n\n return {\n [this.repeat.options.name]: newList\n }\n }\n\n proceed(request: FormContextRequest, h: FormResponseToolkit) {\n const nextPath = this.getSummaryPath(request)\n return super.proceed(request, h, nextPath)\n }\n\n getItemFromList(list: RepeatListState, itemId?: string) {\n return list.find((item) => item.itemId === itemId)\n }\n\n getListFromState(state: FormSubmissionState) {\n const { name } = this.repeat.options\n const values = state[name]\n\n return isRepeatState(values) ? values : []\n }\n\n makeGetRouteHandler() {\n return async (\n request: FormRequest,\n context: FormContext,\n h: FormResponseToolkit\n ) => {\n const { path } = this\n const { query } = request\n const { state } = context\n\n const itemId = this.getItemId(request)\n const list = this.getListFromState(state)\n\n if (!itemId) {\n const summaryPath = this.getSummaryPath(request)\n const nextPath = redirectPath(`${path}/${randomUUID()}`, {\n returnUrl: query.returnUrl,\n force: query.force\n })\n\n // Only redirect to new item when list is empty\n return super.proceed(request, h, list.length ? summaryPath : nextPath)\n }\n\n return super.makeGetRouteHandler()(request, context, h)\n }\n }\n\n makeGetListSummaryRouteHandler() {\n return (\n request: FormRequest,\n context: FormContext,\n h: FormResponseToolkit\n ) => {\n const { path } = this\n const { query } = request\n const { state } = context\n\n const list = this.getListFromState(state)\n\n if (!list.length) {\n const nextPath = redirectPath(`${path}/${randomUUID()}`, {\n returnUrl: query.returnUrl\n })\n\n return super.proceed(request, h, nextPath)\n }\n\n const viewModel = this.getListSummaryViewModel(request, context, list)\n\n return h.view(this.listSummaryViewName, viewModel)\n }\n }\n\n makePostListSummaryRouteHandler() {\n return (\n request: FormRequestPayload,\n context: FormContext,\n h: FormResponseToolkit\n ) => {\n const { path, repeat } = this\n const { query } = request\n const { schema } = repeat\n const { state } = context\n\n const list = this.getListFromState(state)\n\n if (!list.length) {\n const nextPath = redirectPath(`${path}/${randomUUID()}`, {\n returnUrl: query.returnUrl\n })\n\n return super.proceed(request, h, nextPath)\n }\n\n const { action } = this.getFormParams(request)\n\n const hasErrorMin =\n action === FormAction.Continue && list.length < schema.min\n\n const hasErrorMax =\n (action === FormAction.AddAnother && list.length >= schema.max) ||\n (action === FormAction.Continue && list.length > schema.max)\n\n // Show error if repeat limits apply\n if (hasErrorMin || hasErrorMax) {\n const count = hasErrorMax ? schema.max : schema.min\n const itemTitle = `answer${count === 1 ? '' : 's'}`\n\n context.errors = [\n {\n path: [],\n href: '',\n name: '',\n text: hasErrorMax\n ? `You can only add up to ${count} ${itemTitle}`\n : `You must add at least ${count} ${itemTitle}`\n }\n ]\n\n const viewModel = this.getListSummaryViewModel(request, context, list)\n\n return h.view(this.listSummaryViewName, viewModel)\n }\n\n if (action === FormAction.AddAnother) {\n const nextPath = redirectPath(`${path}/${randomUUID()}`, {\n returnUrl: query.returnUrl\n })\n\n return super.proceed(request, h, nextPath)\n }\n\n // Check if this is a save-and-exit action\n if (action === FormAction.SaveAndExit) {\n return this.handleSaveAndExit(request, context, h)\n }\n\n const nextPath = this.getNextPath(context)\n return super.proceed(request, h, nextPath)\n }\n }\n\n makeGetItemDeleteRouteHandler() {\n return (\n request: FormRequest,\n context: FormContext,\n h: FormResponseToolkit\n ) => {\n const { viewModel } = this\n const { state } = context\n\n const list = this.getListFromState(state)\n const itemId = this.getItemId(request)\n const item = this.getItemFromList(list, itemId)\n\n if (!item || list.length === 1) {\n throw Boom.notFound(\n item\n ? 'Last list item cannot be removed'\n : 'List item to remove not found'\n )\n }\n\n const { title } = this.repeat.options\n\n return h.view(this.listDeleteViewName, {\n ...viewModel,\n context,\n backLink: this.getBackLink(request, context),\n pageTitle: 'Are you sure you want to remove this answer?',\n itemTitle: `${title} ${list.indexOf(item) + 1}`,\n buttonConfirm: { text: 'Remove' },\n buttonCancel: { text: 'Cancel' }\n } satisfies ItemDeletePageViewModel)\n }\n }\n\n makePostItemDeleteRouteHandler() {\n return async (\n request: FormRequestPayload,\n context: FormContext,\n h: FormResponseToolkit\n ) => {\n const { repeat } = this\n const { state } = context\n\n const { confirm } = this.getFormParams(request)\n\n const list = this.getListFromState(state)\n const itemId = this.getItemId(request)\n const item = this.getItemFromList(list, itemId)\n\n if (!item || list.length === 1) {\n throw Boom.notFound(\n item\n ? 'Last list item cannot be removed'\n : 'List item to remove not found'\n )\n }\n\n // Remove the item from the list\n if (confirm) {\n list.splice(list.indexOf(item), 1)\n\n const update = {\n [repeat.options.name]: list\n }\n\n await this.mergeState(request, state, update)\n }\n\n return this.proceed(request, h)\n }\n }\n\n getViewModel(\n request: FormContextRequest,\n context: FormContext\n ): FormPageViewModel {\n const { state } = context\n\n const list = this.getListFromState(state)\n const itemId = this.getItemId(request)\n const item = this.getItemFromList(list, itemId)\n\n const viewModel = super.getViewModel(request, context)\n const itemNumber = item ? list.indexOf(item) + 1 : list.length + 1\n const repeatCaption = `${this.repeat.options.title} ${itemNumber}`\n\n return {\n ...viewModel,\n\n sectionTitle: viewModel.sectionTitle\n ? `${viewModel.sectionTitle}: ${repeatCaption}`\n : repeatCaption\n }\n }\n\n getListSummaryViewModel(\n request: FormContextRequest,\n context: FormContext,\n list: RepeatListState\n ): RepeaterSummaryPageViewModel {\n const { collection, href, repeat } = this\n const { query } = request\n const { isForceAccess, errors } = context\n\n const { title } = repeat.options\n\n const summaryList: SummaryList = {\n classes: 'govuk-summary-list--long-actions',\n rows: []\n }\n\n let count = 0\n\n if (Array.isArray(list)) {\n count = list.length\n\n const summaryPath = this.getSummaryPath(request)\n\n list.forEach((item, index) => {\n const items: SummaryListAction[] = []\n\n // Remove summary list actions from previews\n if (!isForceAccess) {\n items.push({\n href: redirectPath(`${href}/${item.itemId}`, {\n returnUrl: query.returnUrl ?? this.getHref(summaryPath)\n }),\n text: 'Change',\n classes: 'govuk-link--no-visited-state',\n visuallyHiddenText: `item ${index + 1}`\n })\n\n if (count > 1) {\n items.push({\n href: redirectPath(`${href}/${item.itemId}/confirm-delete`, {\n returnUrl: query.returnUrl\n }),\n text: 'Remove',\n classes: 'govuk-link--no-visited-state',\n visuallyHiddenText: `item ${index + 1}`\n })\n }\n }\n\n const itemDisplayText = collection.fields.length\n ? collection.fields[0].getDisplayStringFromState(item)\n : ''\n\n summaryList.rows.push({\n key: {\n text: `${title} ${index + 1}`\n },\n value: {\n text: itemDisplayText || 'Not provided'\n },\n actions: {\n items\n }\n })\n })\n }\n\n const unit = count === 1 ? 'answer' : 'answers'\n\n return {\n ...this.viewModel,\n backLink: this.getBackLink(request, context),\n repeatTitle: title,\n pageTitle: `You have added ${count} ${unit}`,\n showTitle: true,\n context,\n errors,\n checkAnswers: [{ summaryList }],\n allowSaveAndExit: this.shouldShowSaveAndExit(request.server)\n }\n }\n\n getSummaryPath(request?: FormContextRequest) {\n const { path } = this\n\n const summaryPath = super.getSummaryPath()\n\n if (!request) {\n return summaryPath\n }\n\n const { query } = request\n\n return redirectPath(`${path}${summaryPath}`, {\n returnUrl: query.returnUrl\n })\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"RepeatPageController.js","names":["randomUUID","Boom","Joi","isRepeatState","redirectPath","QuestionPageController","FormAction","RepeatPageController","listSummaryViewName","listDeleteViewName","repeat","allowSaveAndExit","constructor","model","pageDef","options","schema","itemId","string","uuid","required","collection","formSchema","append","stateSchema","object","keys","name","array","items","min","max","label","title","getFormParams","request","params","payload","getFormDataFromState","state","list","getListFromState","getItemId","item","getItemFromList","getStateFromValidForm","badRequest","itemState","updated","newList","push","indexOf","proceed","h","nextPath","getSummaryPath","find","values","makeGetRouteHandler","context","path","query","summaryPath","returnUrl","force","length","makeGetListSummaryRouteHandler","translator","getTranslator","t","viewModel","getListSummaryViewModel","view","makePostListSummaryRouteHandler","action","hasErrorMin","Continue","hasErrorMax","AddAnother","count","errors","href","text","SaveAndExit","handleSaveAndExit","getNextPath","makeGetItemDeleteRouteHandler","notFound","backLink","getBackLink","pageTitle","itemTitle","buttonConfirm","buttonCancel","makePostItemDeleteRouteHandler","confirm","splice","update","mergeState","getViewModel","tPage","itemNumber","repeatCaption","sectionTitle","isForceAccess","summaryList","classes","rows","Array","isArray","forEach","index","getHref","visuallyHiddenText","itemDisplayText","fields","getDisplayStringFromState","key","value","actions","repeatTitle","showTitle","checkAnswers","shouldShowSaveAndExit","server"],"sources":["../../../../../src/server/plugins/engine/pageControllers/RepeatPageController.ts"],"sourcesContent":["import { randomUUID } from 'crypto'\n\nimport { type PageRepeat, type Repeat } from '@defra/forms-model'\nimport Boom from '@hapi/boom'\nimport Joi from 'joi'\n\nimport { isRepeatState } from '~/src/server/plugins/engine/components/FormComponent.js'\nimport { redirectPath } from '~/src/server/plugins/engine/helpers.js'\nimport { type Translator } from '~/src/server/plugins/engine/i18n/types.js'\nimport { type FormModel } from '~/src/server/plugins/engine/models/index.js'\nimport { QuestionPageController } from '~/src/server/plugins/engine/pageControllers/QuestionPageController.js'\nimport {\n type FormContext,\n type FormContextRequest,\n type FormPageViewModel,\n type FormPayload,\n type FormSubmissionState,\n type ItemDeletePageViewModel,\n type RepeatItemState,\n type RepeatListState,\n type RepeaterSummaryPageViewModel,\n type SummaryList,\n type SummaryListAction\n} from '~/src/server/plugins/engine/types.js'\nimport {\n FormAction,\n type FormRequest,\n type FormRequestPayload,\n type FormResponseToolkit\n} from '~/src/server/routes/types.js'\n\nexport class RepeatPageController extends QuestionPageController {\n declare pageDef: PageRepeat\n\n listSummaryViewName = 'repeat-list-summary'\n listDeleteViewName = 'item-delete'\n repeat: Repeat\n allowSaveAndExit = true\n\n constructor(model: FormModel, pageDef: PageRepeat) {\n super(model, pageDef)\n\n this.repeat = pageDef.repeat\n\n const { options, schema } = this.repeat\n const itemId = Joi.string().uuid().required()\n\n this.collection.formSchema = this.collection.formSchema.append({ itemId })\n this.collection.stateSchema = Joi.object<RepeatItemState>().keys({\n [options.name]: Joi.array()\n .items(this.collection.stateSchema.append({ itemId }))\n .min(schema.min)\n .max(schema.max)\n .label(`${options.title} list`)\n .required()\n })\n }\n\n get keys() {\n const { repeat } = this\n return [repeat.options.name, ...super.keys]\n }\n\n getFormParams(request?: FormContextRequest) {\n const params = super.getFormParams(request)\n\n // Apply an itemId to the form payload\n if (request?.payload) {\n params.itemId = request.params.itemId ?? randomUUID()\n }\n\n return params\n }\n\n getFormDataFromState(\n request: FormContextRequest | undefined,\n state: FormSubmissionState\n ) {\n const { repeat } = this\n\n const params = this.getFormParams(request)\n const list = this.getListFromState(state)\n const itemId = this.getItemId(request)\n\n // Create payload with repeater list state\n if (!itemId) {\n return {\n ...params,\n [repeat.options.name]: list\n }\n }\n\n // Create payload with repeater item state\n const item = this.getItemFromList(list, itemId)\n\n return {\n ...params,\n ...item\n }\n }\n\n getStateFromValidForm(\n request: FormContextRequest,\n state: FormSubmissionState,\n payload: FormPayload\n ) {\n const itemId = this.getItemId(request)\n\n if (!itemId) {\n throw Boom.badRequest('No item ID found')\n }\n\n const list = this.getListFromState(state)\n const item = this.getItemFromList(list, itemId)\n\n const itemState = super.getStateFromValidForm(request, state, payload)\n const updated: RepeatItemState = { ...itemState, itemId }\n const newList = [...list]\n\n if (!item) {\n // Adding a new item\n newList.push(updated)\n } else {\n // Update an existing item\n newList[list.indexOf(item)] = updated\n }\n\n return {\n [this.repeat.options.name]: newList\n }\n }\n\n proceed(request: FormContextRequest, h: FormResponseToolkit) {\n const nextPath = this.getSummaryPath(request)\n return super.proceed(request, h, nextPath)\n }\n\n getItemFromList(list: RepeatListState, itemId?: string) {\n return list.find((item) => item.itemId === itemId)\n }\n\n getListFromState(state: FormSubmissionState) {\n const { name } = this.repeat.options\n const values = state[name]\n\n return isRepeatState(values) ? values : []\n }\n\n makeGetRouteHandler() {\n return async (\n request: FormRequest,\n context: FormContext,\n h: FormResponseToolkit\n ) => {\n const { path } = this\n const { query } = request\n const { state } = context\n\n const itemId = this.getItemId(request)\n const list = this.getListFromState(state)\n\n if (!itemId) {\n const summaryPath = this.getSummaryPath(request)\n const nextPath = redirectPath(`${path}/${randomUUID()}`, {\n returnUrl: query.returnUrl,\n force: query.force\n })\n\n // Only redirect to new item when list is empty\n return super.proceed(request, h, list.length ? summaryPath : nextPath)\n }\n\n return super.makeGetRouteHandler()(request, context, h)\n }\n }\n\n makeGetListSummaryRouteHandler() {\n return (\n request: FormRequest,\n context: FormContext,\n h: FormResponseToolkit\n ) => {\n const { path } = this\n const { query } = request\n const { state } = context\n\n const list = this.getListFromState(state)\n\n if (!list.length) {\n const nextPath = redirectPath(`${path}/${randomUUID()}`, {\n returnUrl: query.returnUrl\n })\n\n return super.proceed(request, h, nextPath)\n }\n\n const translator = this.getTranslator(request)\n const { t } = translator\n\n const viewModel = this.getListSummaryViewModel(\n request,\n context,\n list,\n translator\n )\n\n return h.view(this.listSummaryViewName, {\n ...viewModel,\n t\n })\n }\n }\n\n makePostListSummaryRouteHandler() {\n return (\n request: FormRequestPayload,\n context: FormContext,\n h: FormResponseToolkit\n ) => {\n const { path, repeat } = this\n const { query } = request\n const { schema } = repeat\n const { state } = context\n\n const list = this.getListFromState(state)\n\n if (!list.length) {\n const nextPath = redirectPath(`${path}/${randomUUID()}`, {\n returnUrl: query.returnUrl\n })\n\n return super.proceed(request, h, nextPath)\n }\n\n const translator = this.getTranslator(request)\n const { t } = translator\n\n const { action } = this.getFormParams(request)\n\n const hasErrorMin =\n action === FormAction.Continue && list.length < schema.min\n\n const hasErrorMax =\n (action === FormAction.AddAnother && list.length >= schema.max) ||\n (action === FormAction.Continue && list.length > schema.max)\n\n // Show error if repeat limits apply\n if (hasErrorMin || hasErrorMax) {\n const count = hasErrorMax ? schema.max : schema.min\n\n context.errors = [\n {\n path: [],\n href: '',\n name: '',\n text: hasErrorMax\n ? t('pages.repeater.tooMany', { count })\n : t('pages.repeater.tooFew', { count })\n }\n ]\n\n const viewModel = this.getListSummaryViewModel(\n request,\n context,\n list,\n translator\n )\n\n return h.view(this.listSummaryViewName, {\n ...viewModel,\n t\n })\n }\n\n if (action === FormAction.AddAnother) {\n const nextPath = redirectPath(`${path}/${randomUUID()}`, {\n returnUrl: query.returnUrl\n })\n\n return super.proceed(request, h, nextPath)\n }\n\n // Check if this is a save-and-exit action\n if (action === FormAction.SaveAndExit) {\n return this.handleSaveAndExit(request, context, h)\n }\n\n const nextPath = this.getNextPath(context)\n return super.proceed(request, h, nextPath)\n }\n }\n\n makeGetItemDeleteRouteHandler() {\n return (\n request: FormRequest,\n context: FormContext,\n h: FormResponseToolkit\n ) => {\n const { viewModel } = this\n const { state } = context\n\n const list = this.getListFromState(state)\n const itemId = this.getItemId(request)\n const item = this.getItemFromList(list, itemId)\n\n const translator = this.getTranslator(request)\n const { t } = translator\n\n if (!item || list.length === 1) {\n throw Boom.notFound(\n item\n ? t('pages.repeater.lastItemCannotBeRemoved')\n : t('pages.repeater.itemToRemoveNotFound')\n )\n }\n\n const { title } = this.repeat.options\n\n return h.view(this.listDeleteViewName, {\n ...viewModel,\n context,\n backLink: this.getBackLink(request, context, t),\n pageTitle: t('pages.repeater.removeAnswer'),\n itemTitle: `${title} ${list.indexOf(item) + 1}`,\n buttonConfirm: { text: t('pages.repeater.remove') },\n buttonCancel: { text: t('pages.repeater.cancel') },\n t\n } satisfies ItemDeletePageViewModel)\n }\n }\n\n makePostItemDeleteRouteHandler() {\n return async (\n request: FormRequestPayload,\n context: FormContext,\n h: FormResponseToolkit\n ) => {\n const { repeat } = this\n const { state } = context\n\n const { confirm } = this.getFormParams(request)\n\n const list = this.getListFromState(state)\n const itemId = this.getItemId(request)\n const item = this.getItemFromList(list, itemId)\n\n const { t } = this.getTranslator(request)\n\n if (!item || list.length === 1) {\n throw Boom.notFound(\n item\n ? t('pages.repeater.lastItemCannotBeRemoved')\n : t('pages.repeater.itemToRemoveNotFound')\n )\n }\n\n // Remove the item from the list\n if (confirm) {\n list.splice(list.indexOf(item), 1)\n\n const update = {\n [repeat.options.name]: list\n }\n\n await this.mergeState(request, state, update)\n }\n\n return this.proceed(request, h)\n }\n }\n\n getViewModel(\n request: FormContextRequest,\n context: FormContext,\n translator: Translator\n ): FormPageViewModel {\n const { state } = context\n const { tPage } = translator\n\n const list = this.getListFromState(state)\n const itemId = this.getItemId(request)\n const item = this.getItemFromList(list, itemId)\n\n const viewModel = super.getViewModel(request, context, translator)\n const itemNumber = item ? list.indexOf(item) + 1 : list.length + 1\n const title =\n tPage(this.pageDef, 'repeatTitle') || this.pageDef.repeat.options.title\n const repeatCaption = `${title} ${itemNumber}`\n\n return {\n ...viewModel,\n\n sectionTitle: viewModel.sectionTitle\n ? `${viewModel.sectionTitle}: ${repeatCaption}`\n : repeatCaption\n }\n }\n\n getListSummaryViewModel(\n request: FormContextRequest,\n context: FormContext,\n list: RepeatListState,\n translator: Translator\n ): RepeaterSummaryPageViewModel {\n const { collection, href, repeat } = this\n const { query } = request\n const { isForceAccess, errors } = context\n\n const { t } = translator\n\n const { title } = repeat.options\n\n const summaryList: SummaryList = {\n classes: 'govuk-summary-list--long-actions',\n rows: []\n }\n\n let count = 0\n\n if (Array.isArray(list)) {\n count = list.length\n\n const summaryPath = this.getSummaryPath(request)\n\n list.forEach((item, index) => {\n const items: SummaryListAction[] = []\n\n // Remove summary list actions from previews\n if (!isForceAccess) {\n items.push({\n href: redirectPath(`${href}/${item.itemId}`, {\n returnUrl: query.returnUrl ?? this.getHref(summaryPath)\n }),\n text: t('pages.repeater.change'),\n classes: 'govuk-link--no-visited-state',\n visuallyHiddenText: t('pages.repeater.visuallyHiddenItem', {\n index: index + 1\n })\n })\n\n if (count > 1) {\n items.push({\n href: redirectPath(`${href}/${item.itemId}/confirm-delete`, {\n returnUrl: query.returnUrl\n }),\n text: t('pages.repeater.remove'),\n classes: 'govuk-link--no-visited-state',\n visuallyHiddenText: t('pages.repeater.visuallyHiddenItem', {\n index: index + 1\n })\n })\n }\n }\n\n const itemDisplayText = collection.fields.length\n ? collection.fields[0].getDisplayStringFromState(item, translator)\n : ''\n\n summaryList.rows.push({\n key: {\n text: `${title} ${index + 1}`\n },\n value: {\n text: itemDisplayText || t('pages.repeater.notProvided')\n },\n actions: {\n items\n }\n })\n })\n }\n\n return {\n ...this.viewModel,\n backLink: this.getBackLink(request, context, t),\n repeatTitle: title,\n pageTitle: t('pages.repeater.pageTitle', { count }),\n showTitle: true,\n context,\n errors,\n checkAnswers: [{ summaryList }],\n allowSaveAndExit: this.shouldShowSaveAndExit(request.server)\n }\n }\n\n getSummaryPath(request?: FormContextRequest) {\n const { path } = this\n\n const summaryPath = super.getSummaryPath()\n\n if (!request) {\n return summaryPath\n }\n\n const { query } = request\n\n return redirectPath(`${path}${summaryPath}`, {\n returnUrl: query.returnUrl\n })\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -1,3 +1,4 @@
1
+ import { type Translator } from '../../../../server/plugins/engine/i18n/types.js';
1
2
  import { QuestionPageController } from '../../../../server/plugins/engine/pageControllers/QuestionPageController.js';
2
3
  import { type FormContext } from '../../../../server/plugins/engine/types.js';
3
4
  import { type FormRequest } from '../../../../server/routes/types.js';
@@ -8,7 +9,7 @@ export declare class StartPageController extends QuestionPageController {
8
9
  * but start pages should really live on gov.uk (whitehall publisher) so a user can be properly signposted.
9
10
  */
10
11
  allowSaveAndExit: boolean;
11
- getViewModel(request: FormRequest, context: FormContext): {
12
+ getViewModel(request: FormRequest, context: FormContext, translator: Translator): {
12
13
  isStartPage: boolean;
13
14
  components: import("../components/types.js").ComponentViewModel[];
14
15
  context: FormContext;
@@ -26,6 +27,7 @@ export declare class StartPageController extends QuestionPageController {
26
27
  feedbackLink?: string;
27
28
  serviceUrl: string;
28
29
  phaseTag?: string;
30
+ t?: (key: string, opts?: Record<string, unknown>) => string;
29
31
  /**
30
32
  * - Base layout path
31
33
  */
@@ -7,9 +7,9 @@ export class StartPageController extends QuestionPageController {
7
7
  */
8
8
 
9
9
  allowSaveAndExit = false;
10
- getViewModel(request, context) {
10
+ getViewModel(request, context, translator) {
11
11
  return {
12
- ...super.getViewModel(request, context),
12
+ ...super.getViewModel(request, context, translator),
13
13
  isStartPage: true
14
14
  };
15
15
  }
@@ -1 +1 @@
1
- {"version":3,"file":"StartPageController.js","names":["QuestionPageController","StartPageController","allowSaveAndExit","getViewModel","request","context","isStartPage"],"sources":["../../../../../src/server/plugins/engine/pageControllers/StartPageController.ts"],"sourcesContent":["import { QuestionPageController } from '~/src/server/plugins/engine/pageControllers/QuestionPageController.js'\nimport { type FormContext } from '~/src/server/plugins/engine/types.js'\nimport { type FormRequest } from '~/src/server/routes/types.js'\n\nexport class StartPageController extends QuestionPageController {\n /**\n * The controller which is used when Page[\"controller\"] is defined as \"./pages/start.js\"\n * This page should not be used in production. This page is helpful for prototyping start pages within the app,\n * but start pages should really live on gov.uk (whitehall publisher) so a user can be properly signposted.\n */\n\n allowSaveAndExit = false\n\n getViewModel(request: FormRequest, context: FormContext) {\n return {\n ...super.getViewModel(request, context),\n isStartPage: true\n }\n }\n}\n"],"mappings":"AAAA,SAASA,sBAAsB;AAI/B,OAAO,MAAMC,mBAAmB,SAASD,sBAAsB,CAAC;EAC9D;AACF;AACA;AACA;AACA;;EAEEE,gBAAgB,GAAG,KAAK;EAExBC,YAAYA,CAACC,OAAoB,EAAEC,OAAoB,EAAE;IACvD,OAAO;MACL,GAAG,KAAK,CAACF,YAAY,CAACC,OAAO,EAAEC,OAAO,CAAC;MACvCC,WAAW,EAAE;IACf,CAAC;EACH;AACF","ignoreList":[]}
1
+ {"version":3,"file":"StartPageController.js","names":["QuestionPageController","StartPageController","allowSaveAndExit","getViewModel","request","context","translator","isStartPage"],"sources":["../../../../../src/server/plugins/engine/pageControllers/StartPageController.ts"],"sourcesContent":["import { type Translator } from '~/src/server/plugins/engine/i18n/types.js'\nimport { QuestionPageController } from '~/src/server/plugins/engine/pageControllers/QuestionPageController.js'\nimport { type FormContext } from '~/src/server/plugins/engine/types.js'\nimport { type FormRequest } from '~/src/server/routes/types.js'\n\nexport class StartPageController extends QuestionPageController {\n /**\n * The controller which is used when Page[\"controller\"] is defined as \"./pages/start.js\"\n * This page should not be used in production. This page is helpful for prototyping start pages within the app,\n * but start pages should really live on gov.uk (whitehall publisher) so a user can be properly signposted.\n */\n\n allowSaveAndExit = false\n\n getViewModel(\n request: FormRequest,\n context: FormContext,\n translator: Translator\n ) {\n return {\n ...super.getViewModel(request, context, translator),\n isStartPage: true\n }\n }\n}\n"],"mappings":"AACA,SAASA,sBAAsB;AAI/B,OAAO,MAAMC,mBAAmB,SAASD,sBAAsB,CAAC;EAC9D;AACF;AACA;AACA;AACA;;EAEEE,gBAAgB,GAAG,KAAK;EAExBC,YAAYA,CACVC,OAAoB,EACpBC,OAAoB,EACpBC,UAAsB,EACtB;IACA,OAAO;MACL,GAAG,KAAK,CAACH,YAAY,CAACC,OAAO,EAAEC,OAAO,EAAEC,UAAU,CAAC;MACnDC,WAAW,EAAE;IACf,CAAC;EACH;AACF","ignoreList":[]}