@defra/forms-engine-plugin 4.13.0 → 4.14.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.
- package/.public/javascripts/shared.min.js +1 -1
- package/.public/javascripts/shared.min.js.map +1 -1
- package/.server/client/javascripts/geospatial-map.d.ts +32 -0
- package/.server/client/javascripts/geospatial-map.js +161 -70
- package/.server/client/javascripts/geospatial-map.js.map +1 -1
- package/.server/client/javascripts/map.d.ts +6 -0
- package/.server/client/javascripts/map.js +5 -0
- package/.server/client/javascripts/map.js.map +1 -1
- package/.server/client/javascripts/utils.d.ts +7 -0
- package/.server/client/javascripts/utils.js +21 -0
- package/.server/client/javascripts/utils.js.map +1 -0
- package/.server/server/forms/simple-form.yaml +9 -0
- package/.server/server/plugins/engine/components/GeospatialField.d.ts +1 -0
- package/.server/server/plugins/engine/components/GeospatialField.js +9 -5
- package/.server/server/plugins/engine/components/GeospatialField.js.map +1 -1
- package/.server/server/plugins/engine/components/helpers/geospatial.d.ts +2 -2
- package/.server/server/plugins/engine/components/helpers/geospatial.js +32 -5
- package/.server/server/plugins/engine/components/helpers/geospatial.js.map +1 -1
- package/.server/server/plugins/engine/components/helpers/geospatial.test.js +37 -6
- package/.server/server/plugins/engine/components/helpers/geospatial.test.js.map +1 -1
- package/.server/server/plugins/engine/pageControllers/validationOptions.js +4 -1
- package/.server/server/plugins/engine/pageControllers/validationOptions.js.map +1 -1
- package/.server/server/plugins/engine/views/components/geospatialfield.html +1 -1
- package/package.json +2 -2
- package/src/client/javascripts/geospatial-map.js +168 -53
- package/src/client/javascripts/map.js +5 -0
- package/src/client/javascripts/utils.js +23 -0
- package/src/server/forms/simple-form.yaml +9 -0
- package/src/server/plugins/engine/components/GeospatialField.ts +11 -7
- package/src/server/plugins/engine/components/helpers/geospatial.ts +49 -11
- package/src/server/plugins/engine/pageControllers/validationOptions.ts +4 -1
- package/src/server/plugins/engine/views/components/geospatialfield.html +1 -1
|
@@ -25,6 +25,15 @@ pages:
|
|
|
25
25
|
required: true
|
|
26
26
|
schema: {}
|
|
27
27
|
id: b68df7f1-d4f4-4c17-83c8-402f584906c9
|
|
28
|
+
- type: GeospatialField
|
|
29
|
+
title: Where do you live?
|
|
30
|
+
name: applicantLocation
|
|
31
|
+
shortDescription: Your location
|
|
32
|
+
hint: ''
|
|
33
|
+
options:
|
|
34
|
+
required: true
|
|
35
|
+
schema: {}
|
|
36
|
+
id: e18116e0-7c3e-416a-af42-6f229017c5b1
|
|
28
37
|
next: []
|
|
29
38
|
id: 622a35ec-3795-418a-81f3-a45746959045
|
|
30
39
|
- title: Upload a copy of your passport
|
|
@@ -31,18 +31,21 @@ export class GeospatialField extends FormComponent {
|
|
|
31
31
|
|
|
32
32
|
const { options } = def
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
const formSchema = getGeospatialSchema(def)
|
|
35
35
|
.label(this.label)
|
|
36
|
-
.
|
|
36
|
+
.messages({
|
|
37
|
+
'array.min': messageTemplate.featuresMin as string,
|
|
38
|
+
'array.max': messageTemplate.featuresMax as string,
|
|
39
|
+
'array.length': messageTemplate.featuresLength as string
|
|
40
|
+
})
|
|
37
41
|
|
|
38
|
-
formSchema = formSchema
|
|
42
|
+
this.formSchema = formSchema
|
|
43
|
+
this.stateSchema = formSchema.default(null)
|
|
39
44
|
|
|
40
|
-
if (options.required
|
|
41
|
-
|
|
45
|
+
if (options.required === false) {
|
|
46
|
+
this.stateSchema = this.stateSchema.allow(null)
|
|
42
47
|
}
|
|
43
48
|
|
|
44
|
-
this.formSchema = formSchema
|
|
45
|
-
this.stateSchema = formSchema.default(null)
|
|
46
49
|
this.options = options
|
|
47
50
|
}
|
|
48
51
|
|
|
@@ -93,6 +96,7 @@ export class GeospatialField extends FormComponent {
|
|
|
93
96
|
return {
|
|
94
97
|
...viewModel,
|
|
95
98
|
country: this.options.countries?.at(0),
|
|
99
|
+
geometryTypes: this.options.geometryTypes,
|
|
96
100
|
value
|
|
97
101
|
}
|
|
98
102
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
GeospatialFieldOptionsCountryEnum,
|
|
3
|
+
type GeospatialFieldComponent,
|
|
3
4
|
type GeospatialFieldOptionsCountry
|
|
4
5
|
} from '@defra/forms-model'
|
|
5
6
|
import Bourne from '@hapi/bourne'
|
|
@@ -31,7 +32,8 @@ const Joi = JoiBase.extend({
|
|
|
31
32
|
from: 'string',
|
|
32
33
|
method(value, helpers) {
|
|
33
34
|
if (typeof value === 'string') {
|
|
34
|
-
|
|
35
|
+
const trimmed = value.trim()
|
|
36
|
+
if (trimmed === '' || trimmed === '[]') {
|
|
35
37
|
return {
|
|
36
38
|
value: undefined
|
|
37
39
|
}
|
|
@@ -96,14 +98,48 @@ const featureSchema = Joi.object<Feature>().keys({
|
|
|
96
98
|
geometry: featureGeometrySchema
|
|
97
99
|
})
|
|
98
100
|
|
|
99
|
-
|
|
100
|
-
.
|
|
101
|
-
|
|
102
|
-
|
|
101
|
+
function applySchemaConstraints(
|
|
102
|
+
schema: JoiBase.ArraySchema<Feature[]>,
|
|
103
|
+
def: GeospatialFieldComponent
|
|
104
|
+
) {
|
|
105
|
+
const { options, schema: constraints } = def
|
|
106
|
+
const isOptional = options.required === false
|
|
107
|
+
|
|
108
|
+
if (typeof constraints?.length === 'number') {
|
|
109
|
+
schema = schema.length(constraints.length)
|
|
110
|
+
} else {
|
|
111
|
+
if (typeof constraints?.min === 'number') {
|
|
112
|
+
schema = schema.min(constraints.min)
|
|
113
|
+
} else if (!isOptional) {
|
|
114
|
+
schema = schema.min(1)
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
schema = schema.max(
|
|
118
|
+
typeof constraints?.max === 'number' ? constraints.max : 50
|
|
119
|
+
)
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (isOptional) {
|
|
123
|
+
schema = schema.optional()
|
|
124
|
+
} else {
|
|
125
|
+
schema = schema.required()
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return schema
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export function getGeospatialSchema(
|
|
132
|
+
def: GeospatialFieldComponent
|
|
133
|
+
): JoiBase.ArraySchema<Feature[]> {
|
|
134
|
+
const { options = {} } = def
|
|
135
|
+
const country: GeospatialFieldOptionsCountry | undefined =
|
|
136
|
+
options.countries?.at(0)
|
|
103
137
|
|
|
104
|
-
export function getGeospatialSchema(country?: GeospatialFieldOptionsCountry) {
|
|
105
138
|
if (!country) {
|
|
106
|
-
return
|
|
139
|
+
return applySchemaConstraints(
|
|
140
|
+
Joi.array<Feature[]>().items(featureSchema).unique('id'),
|
|
141
|
+
def
|
|
142
|
+
)
|
|
107
143
|
}
|
|
108
144
|
|
|
109
145
|
const validateCountryBounds: CustomValidator = (value, helpers) => {
|
|
@@ -128,10 +164,12 @@ export function getGeospatialSchema(country?: GeospatialFieldOptionsCountry) {
|
|
|
128
164
|
return value
|
|
129
165
|
}
|
|
130
166
|
|
|
131
|
-
return
|
|
132
|
-
.
|
|
133
|
-
|
|
134
|
-
|
|
167
|
+
return applySchemaConstraints(
|
|
168
|
+
Joi.array<Feature[]>()
|
|
169
|
+
.items(featureSchema.custom(validateCountryBounds))
|
|
170
|
+
.unique('id'),
|
|
171
|
+
def
|
|
172
|
+
)
|
|
135
173
|
}
|
|
136
174
|
|
|
137
175
|
/**
|
|
@@ -64,7 +64,10 @@ export const messageTemplate: Record<string, JoiExpression> = {
|
|
|
64
64
|
dateMax: '{{#title}} must be the same as or before {{#limit}}',
|
|
65
65
|
arrayMin: 'Select at least {{#limit}} options from the list',
|
|
66
66
|
arrayMax: 'Only {{#limit}} can be selected from the list',
|
|
67
|
-
arrayLength: 'Select only {{#limit}} options from the list'
|
|
67
|
+
arrayLength: 'Select only {{#limit}} options from the list',
|
|
68
|
+
featuresMin: 'Define at least {{#limit}} features',
|
|
69
|
+
featuresMax: 'Only {{#limit}} features can be defined',
|
|
70
|
+
featuresLength: 'Define exactly {{#limit}} features'
|
|
68
71
|
}
|
|
69
72
|
|
|
70
73
|
export const messages: LanguageMessagesExt = {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{% from "govuk/components/textarea/macro.njk" import govukTextarea %}
|
|
2
2
|
|
|
3
3
|
{% macro GeospatialField(component) %}
|
|
4
|
-
<div class="app-geospatial-field" data-country="{{component.model.country}}">
|
|
4
|
+
<div class="app-geospatial-field" data-country="{{component.model.country}}" data-geometryTypes="{{component.model.geometryTypes}}">
|
|
5
5
|
{{ govukTextarea(component.model) }}
|
|
6
6
|
</div>
|
|
7
7
|
{% endmacro %}
|