@defra/forms-engine-plugin 4.2.0 → 4.4.0

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 (98) hide show
  1. package/.public/javascripts/application.min.js.map +1 -1
  2. package/.public/javascripts/shared.min.js +1 -1
  3. package/.public/javascripts/shared.min.js.map +1 -1
  4. package/.public/javascripts/vendor/accessible-autocomplete.min.js.map +1 -1
  5. package/.public/stylesheets/application.min.css +1 -1
  6. package/.public/stylesheets/application.min.css.map +1 -1
  7. package/.server/client/javascripts/geospatial-map.d.ts +189 -0
  8. package/.server/client/javascripts/geospatial-map.js +1068 -0
  9. package/.server/client/javascripts/geospatial-map.js.map +1 -0
  10. package/.server/client/javascripts/location-map.d.ts +6 -91
  11. package/.server/client/javascripts/location-map.js +78 -385
  12. package/.server/client/javascripts/location-map.js.map +1 -1
  13. package/.server/client/javascripts/map.d.ts +199 -0
  14. package/.server/client/javascripts/map.js +384 -0
  15. package/.server/client/javascripts/map.js.map +1 -0
  16. package/.server/client/javascripts/shared.d.ts +3 -1
  17. package/.server/client/javascripts/shared.js +3 -1
  18. package/.server/client/javascripts/shared.js.map +1 -1
  19. package/.server/client/stylesheets/shared.scss +7 -0
  20. package/.server/server/plugins/engine/components/ComponentBase.d.ts +1 -0
  21. package/.server/server/plugins/engine/components/ComponentBase.js +2 -0
  22. package/.server/server/plugins/engine/components/ComponentBase.js.map +1 -1
  23. package/.server/server/plugins/engine/components/FormComponent.d.ts +9 -1
  24. package/.server/server/plugins/engine/components/FormComponent.js +22 -0
  25. package/.server/server/plugins/engine/components/FormComponent.js.map +1 -1
  26. package/.server/server/plugins/engine/components/GeospatialField.d.ts +77 -0
  27. package/.server/server/plugins/engine/components/GeospatialField.js +102 -0
  28. package/.server/server/plugins/engine/components/GeospatialField.js.map +1 -0
  29. package/.server/server/plugins/engine/components/helpers/__stubs__/geospatial.d.ts +3 -0
  30. package/.server/server/plugins/engine/components/helpers/__stubs__/geospatial.js +63 -0
  31. package/.server/server/plugins/engine/components/helpers/__stubs__/geospatial.js.map +1 -0
  32. package/.server/server/plugins/engine/components/helpers/components.d.ts +1 -1
  33. package/.server/server/plugins/engine/components/helpers/components.js +7 -0
  34. package/.server/server/plugins/engine/components/helpers/components.js.map +1 -1
  35. package/.server/server/plugins/engine/components/helpers/geospatial.d.ts +6 -0
  36. package/.server/server/plugins/engine/components/helpers/geospatial.js +71 -0
  37. package/.server/server/plugins/engine/components/helpers/geospatial.js.map +1 -0
  38. package/.server/server/plugins/engine/components/helpers/geospatial.test.js +42 -0
  39. package/.server/server/plugins/engine/components/helpers/geospatial.test.js.map +1 -0
  40. package/.server/server/plugins/engine/components/index.d.ts +1 -0
  41. package/.server/server/plugins/engine/components/index.js +1 -0
  42. package/.server/server/plugins/engine/components/index.js.map +1 -1
  43. package/.server/server/plugins/engine/models/FormModel.js +0 -4
  44. package/.server/server/plugins/engine/models/FormModel.js.map +1 -1
  45. package/.server/server/plugins/engine/pageControllers/PageController.d.ts +1 -0
  46. package/.server/server/plugins/engine/pageControllers/PageController.js +2 -0
  47. package/.server/server/plugins/engine/pageControllers/PageController.js.map +1 -1
  48. package/.server/server/plugins/engine/pageControllers/QuestionPageController.js +2 -4
  49. package/.server/server/plugins/engine/pageControllers/QuestionPageController.js.map +1 -1
  50. package/.server/server/plugins/engine/pageControllers/helpers/state.d.ts +8 -7
  51. package/.server/server/plugins/engine/pageControllers/helpers/state.js +39 -12
  52. package/.server/server/plugins/engine/pageControllers/helpers/state.js.map +1 -1
  53. package/.server/server/plugins/engine/pageControllers/helpers/submission.js +13 -1
  54. package/.server/server/plugins/engine/pageControllers/helpers/submission.js.map +1 -1
  55. package/.server/server/plugins/engine/pageControllers/validationOptions.js +2 -1
  56. package/.server/server/plugins/engine/pageControllers/validationOptions.js.map +1 -1
  57. package/.server/server/plugins/engine/routes/index.js +8 -1
  58. package/.server/server/plugins/engine/routes/index.js.map +1 -1
  59. package/.server/server/plugins/engine/types.d.ts +63 -2
  60. package/.server/server/plugins/engine/types.js +33 -0
  61. package/.server/server/plugins/engine/types.js.map +1 -1
  62. package/.server/server/plugins/engine/views/components/geospatialfield.html +7 -0
  63. package/.server/server/plugins/nunjucks/context.test.js.map +1 -1
  64. package/.server/server/plugins/nunjucks/filters/field.d.ts +1 -1
  65. package/.server/server/routes/types.js.map +1 -1
  66. package/.server/server/services/cacheService.js +3 -0
  67. package/.server/server/services/cacheService.js.map +1 -1
  68. package/package.json +9 -5
  69. package/src/client/javascripts/geospatial-map.js +1023 -0
  70. package/src/client/javascripts/location-map.js +94 -390
  71. package/src/client/javascripts/map.js +389 -0
  72. package/src/client/javascripts/shared.js +3 -1
  73. package/src/client/stylesheets/shared.scss +7 -0
  74. package/src/server/plugins/engine/components/ComponentBase.ts +2 -0
  75. package/src/server/plugins/engine/components/FormComponent.ts +29 -0
  76. package/src/server/plugins/engine/components/GeospatialField.test.ts +380 -0
  77. package/src/server/plugins/engine/components/GeospatialField.ts +145 -0
  78. package/src/server/plugins/engine/components/helpers/__stubs__/geospatial.ts +85 -0
  79. package/src/server/plugins/engine/components/helpers/components.test.ts +44 -0
  80. package/src/server/plugins/engine/components/helpers/components.ts +10 -0
  81. package/src/server/plugins/engine/components/helpers/geospatial.test.js +55 -0
  82. package/src/server/plugins/engine/components/helpers/geospatial.ts +93 -0
  83. package/src/server/plugins/engine/components/index.ts +1 -0
  84. package/src/server/plugins/engine/models/FormModel.ts +0 -4
  85. package/src/server/plugins/engine/pageControllers/PageController.ts +2 -0
  86. package/src/server/plugins/engine/pageControllers/QuestionPageController.ts +2 -6
  87. package/src/server/plugins/engine/pageControllers/helpers/state.test.ts +80 -16
  88. package/src/server/plugins/engine/pageControllers/helpers/state.ts +57 -17
  89. package/src/server/plugins/engine/pageControllers/helpers/submission.test.ts +74 -0
  90. package/src/server/plugins/engine/pageControllers/helpers/submission.ts +17 -1
  91. package/src/server/plugins/engine/pageControllers/validationOptions.ts +3 -1
  92. package/src/server/plugins/engine/routes/index.test.ts +4 -2
  93. package/src/server/plugins/engine/routes/index.ts +13 -1
  94. package/src/server/plugins/engine/types.ts +77 -4
  95. package/src/server/plugins/engine/views/components/geospatialfield.html +7 -0
  96. package/src/server/plugins/nunjucks/context.test.js +2 -3
  97. package/src/server/routes/types.ts +4 -2
  98. package/src/server/services/cacheService.ts +2 -0
@@ -23,6 +23,10 @@ import {
23
23
  proceed
24
24
  } from '~/src/server/plugins/engine/helpers.js'
25
25
  import { type PageControllerClass } from '~/src/server/plugins/engine/pageControllers/helpers/pages.js'
26
+ import {
27
+ checkSaveAndExitRepeater,
28
+ copyNotYetValidatedState
29
+ } from '~/src/server/plugins/engine/pageControllers/helpers/state.js'
26
30
  import { generateUniqueReference } from '~/src/server/plugins/engine/referenceNumbers.js'
27
31
  import * as defaultServices from '~/src/server/plugins/engine/services/index.js'
28
32
  import {
@@ -78,6 +82,9 @@ export async function redirectOrMakeHandler(
78
82
 
79
83
  const flash = cacheService.getFlash(request)
80
84
  const context = model.getFormContext(request, state, flash?.errors)
85
+
86
+ await copyNotYetValidatedState(request, context)
87
+
81
88
  const relevantPath = page.getRelevantPath(request, context)
82
89
  const summaryPath = page.getSummaryPath()
83
90
 
@@ -89,6 +96,12 @@ export async function redirectOrMakeHandler(
89
96
  }
90
97
  }
91
98
 
99
+ // Check whether save-and-exit should resume from within a repeater
100
+ const resumeInRepeaterUrl = checkSaveAndExitRepeater(context, model)
101
+ if (resumeInRepeaterUrl) {
102
+ return proceed(request, h, resumeInRepeaterUrl)
103
+ }
104
+
92
105
  // Return handler for relevant pages or preview URL direct access
93
106
  if (relevantPath.startsWith(page.path) || context.isForceAccess) {
94
107
  return makeHandler(page, context)
@@ -96,7 +109,6 @@ export async function redirectOrMakeHandler(
96
109
 
97
110
  // Redirect back to last relevant page
98
111
  const redirectTo = findPage(model, relevantPath)
99
-
100
112
  // Set the return URL unless an exit page
101
113
  if (redirectTo?.next.length) {
102
114
  request.query.returnUrl = page.getHref(summaryPath)
@@ -94,8 +94,10 @@ export type FormSubmissionState = {
94
94
  upload?: Record<string, TempFileState>
95
95
  } & FormState
96
96
 
97
- export interface FormSubmissionError
98
- extends Pick<ValidationErrorItem, 'context' | 'path'> {
97
+ export interface FormSubmissionError extends Pick<
98
+ ValidationErrorItem,
99
+ 'context' | 'path'
100
+ > {
99
101
  href: string // e.g: '#dateField__day'
100
102
  name: string // e.g: 'dateField__day'
101
103
  text: string // e.g: 'Date field must be a real date'
@@ -125,6 +127,7 @@ export type FormValue =
125
127
  | Item['value'][]
126
128
  | UploadState
127
129
  | RepeatListState
130
+ | GeospatialState
128
131
  | undefined
129
132
 
130
133
  export type FormState = Partial<Record<string, FormStateValue>>
@@ -285,6 +288,76 @@ export interface RepeatItemState extends FormPayload {
285
288
 
286
289
  export type RepeatListState = RepeatItemState[]
287
290
 
291
+ /**
292
+ * A longitude/latitude coordinate pair in WGS84 format
293
+ * Format: [longitude, latitude]
294
+ */
295
+ export type Coordinates = [longitude: number, latitude: number]
296
+
297
+ /**
298
+ * GeoJSON Point geometry
299
+ */
300
+ export interface PointGeometry {
301
+ type: 'Point'
302
+ coordinates: Coordinates
303
+ }
304
+
305
+ /**
306
+ * GeoJSON LineString geometry
307
+ */
308
+ export interface LineStringGeometry {
309
+ type: 'LineString'
310
+ coordinates: Coordinates[]
311
+ }
312
+
313
+ /**
314
+ * GeoJSON Polygon geometry
315
+ */
316
+ export interface PolygonGeometry {
317
+ type: 'Polygon'
318
+ coordinates: Coordinates[][]
319
+ }
320
+
321
+ /**
322
+ * Supported geometry types
323
+ */
324
+ export type Geometry = PointGeometry | LineStringGeometry | PolygonGeometry
325
+
326
+ /**
327
+ * Feature metadata
328
+ */
329
+ export interface FeatureProperties {
330
+ /**
331
+ * Human-readable description of the feature
332
+ */
333
+ description: string
334
+ /**
335
+ * The OS grid reference of the first coordinate of the feature
336
+ */
337
+ coordinateGridReference?: string
338
+ /**
339
+ * The OS grid reference of the centroid of the feature
340
+ */
341
+ centroidGridReference?: string
342
+ }
343
+
344
+ /**
345
+ * A single GeoJSON Feature
346
+ */
347
+ export interface Feature {
348
+ id: string
349
+ type: 'Feature'
350
+ properties: FeatureProperties
351
+ geometry: Geometry
352
+ }
353
+
354
+ /**
355
+ * A GeoJSON FeatureCollection
356
+ */
357
+ export type FeatureCollection = Feature[]
358
+
359
+ export type GeospatialState = FeatureCollection
360
+
288
361
  export interface CheckAnswers {
289
362
  title?: ComponentText
290
363
  summaryList: SummaryList
@@ -502,6 +575,7 @@ export type RichFormValue =
502
575
  | UkAddressState
503
576
  | EastingNorthingState
504
577
  | LatLongState
578
+ | GeospatialState
505
579
 
506
580
  export interface FormAdapterSubmissionMessageData {
507
581
  main: Record<string, RichFormValue | null>
@@ -516,8 +590,7 @@ export interface FormAdapterSubmissionMessagePayload {
516
590
  result: FormAdapterSubmissionMessageResult
517
591
  }
518
592
 
519
- export interface FormAdapterSubmissionMessage
520
- extends FormAdapterSubmissionMessagePayload {
593
+ export interface FormAdapterSubmissionMessage extends FormAdapterSubmissionMessagePayload {
521
594
  messageId: string
522
595
  recordCreatedAt: Date
523
596
  }
@@ -0,0 +1,7 @@
1
+ {% from "govuk/components/textarea/macro.njk" import govukTextarea %}
2
+
3
+ {% macro GeospatialField(component) %}
4
+ <div class="app-geospatial-field">
5
+ {{ govukTextarea(component.model) }}
6
+ </div>
7
+ {% endmacro %}
@@ -33,9 +33,8 @@ describe('Nunjucks context', () => {
33
33
  const { config } = await import('~/src/config/index.js')
34
34
 
35
35
  // Import when isolated to avoid cache
36
- const { devtoolContext } = await import(
37
- '~/src/server/plugins/nunjucks/context.js'
38
- )
36
+ const { devtoolContext } =
37
+ await import('~/src/server/plugins/nunjucks/context.js')
39
38
 
40
39
  // Update config for missing manifest
41
40
  config.set('publicDir', tmpdir())
@@ -24,8 +24,10 @@ export interface FormParams extends Partial<Record<string, string>> {
24
24
  state?: FormStatus
25
25
  }
26
26
 
27
- export interface FormRequestRefs
28
- extends Omit<ReqRefDefaults, 'Params' | 'Payload' | 'Query'> {
27
+ export interface FormRequestRefs extends Omit<
28
+ ReqRefDefaults,
29
+ 'Params' | 'Payload' | 'Query'
30
+ > {
29
31
  Params: FormParams
30
32
  Payload: object | undefined
31
33
  Query: FormQuery
@@ -147,7 +147,9 @@ export class CacheService {
147
147
  throw new Error('No session ID found')
148
148
  }
149
149
 
150
+ // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style
150
151
  const state = (request.params.state as string) || ''
152
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
151
153
  const slug = (request.params.slug as string) || ''
152
154
  const key = `${request.yar.id}:${state}:${slug}:`
153
155