@defra/forms-engine-plugin 5.0.0-alpha.11 → 5.0.0-alpha.13

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 (101) hide show
  1. package/.public/javascripts/shared.min.js +1 -1
  2. package/.public/javascripts/shared.min.js.map +1 -1
  3. package/.server/client/javascripts/geospatial-map.d.ts +153 -5
  4. package/.server/client/javascripts/geospatial-map.js +147 -46
  5. package/.server/client/javascripts/geospatial-map.js.map +1 -1
  6. package/.server/client/javascripts/location-map.d.ts +38 -0
  7. package/.server/client/javascripts/location-map.js +42 -2
  8. package/.server/client/javascripts/location-map.js.map +1 -1
  9. package/.server/client/javascripts/map-constants.d.ts +3 -0
  10. package/.server/client/javascripts/map-constants.js +4 -0
  11. package/.server/client/javascripts/map-constants.js.map +1 -0
  12. package/.server/client/javascripts/map.d.ts +4 -0
  13. package/.server/client/javascripts/map.js +5 -0
  14. package/.server/client/javascripts/map.js.map +1 -1
  15. package/.server/server/plugins/engine/__stubs__/definitions.d.ts +29 -0
  16. package/.server/server/plugins/engine/__stubs__/definitions.js +125 -0
  17. package/.server/server/plugins/engine/__stubs__/definitions.js.map +1 -0
  18. package/.server/server/plugins/engine/components/CheckboxesField.d.ts +20 -2
  19. package/.server/server/plugins/engine/components/CheckboxesField.js +24 -12
  20. package/.server/server/plugins/engine/components/CheckboxesField.js.map +1 -1
  21. package/.server/server/plugins/engine/components/EastingNorthingField.d.ts +4 -0
  22. package/.server/server/plugins/engine/components/EastingNorthingField.js +1 -1
  23. package/.server/server/plugins/engine/components/EastingNorthingField.js.map +1 -1
  24. package/.server/server/plugins/engine/components/FileUploadField.d.ts +10 -1
  25. package/.server/server/plugins/engine/components/FileUploadField.js +18 -6
  26. package/.server/server/plugins/engine/components/FileUploadField.js.map +1 -1
  27. package/.server/server/plugins/engine/components/GeospatialField.d.ts +22 -0
  28. package/.server/server/plugins/engine/components/GeospatialField.js +33 -9
  29. package/.server/server/plugins/engine/components/GeospatialField.js.map +1 -1
  30. package/.server/server/plugins/engine/components/LatLongField.d.ts +4 -0
  31. package/.server/server/plugins/engine/components/LocationFieldBase.js +7 -1
  32. package/.server/server/plugins/engine/components/LocationFieldBase.js.map +1 -1
  33. package/.server/server/plugins/engine/components/LocationFieldHelpers.d.ts +4 -0
  34. package/.server/server/plugins/engine/components/LocationFieldHelpers.js +9 -2
  35. package/.server/server/plugins/engine/components/LocationFieldHelpers.js.map +1 -1
  36. package/.server/server/plugins/engine/components/helpers/components.js +2 -1
  37. package/.server/server/plugins/engine/components/helpers/components.js.map +1 -1
  38. package/.server/server/plugins/engine/components/helpers/geospatial.d.ts +5 -0
  39. package/.server/server/plugins/engine/components/helpers/geospatial.js +25 -16
  40. package/.server/server/plugins/engine/components/helpers/geospatial.js.map +1 -1
  41. package/.server/server/plugins/engine/errors.d.ts +49 -0
  42. package/.server/server/plugins/engine/errors.js +75 -0
  43. package/.server/server/plugins/engine/errors.js.map +1 -0
  44. package/.server/server/plugins/engine/form-availability.d.ts +3 -2
  45. package/.server/server/plugins/engine/form-availability.js +3 -2
  46. package/.server/server/plugins/engine/form-availability.js.map +1 -1
  47. package/.server/server/plugins/engine/form-context.js +2 -2
  48. package/.server/server/plugins/engine/form-context.js.map +1 -1
  49. package/.server/server/plugins/engine/i18n/buildValidationMessages.d.ts +1 -1
  50. package/.server/server/plugins/engine/i18n/buildValidationMessages.js +30 -9
  51. package/.server/server/plugins/engine/i18n/buildValidationMessages.js.map +1 -1
  52. package/.server/server/plugins/engine/i18n/translations/cy.json +117 -11
  53. package/.server/server/plugins/engine/i18n/translations/en-GB.json +80 -11
  54. package/.server/server/plugins/engine/i18n/types.d.ts +1 -0
  55. package/.server/server/plugins/engine/i18n/types.js.map +1 -1
  56. package/.server/server/plugins/engine/models/FormModel.js +10 -2
  57. package/.server/server/plugins/engine/models/FormModel.js.map +1 -1
  58. package/.server/server/plugins/engine/models/unavailable-view-model.d.ts +11 -2
  59. package/.server/server/plugins/engine/models/unavailable-view-model.js +23 -4
  60. package/.server/server/plugins/engine/models/unavailable-view-model.js.map +1 -1
  61. package/.server/server/plugins/engine/pageControllers/helpers/pages.js +2 -1
  62. package/.server/server/plugins/engine/pageControllers/helpers/pages.js.map +1 -1
  63. package/.server/server/plugins/engine/pageControllers/validationOptions.d.ts +1 -1
  64. package/.server/server/plugins/engine/pageControllers/validationOptions.js +1 -1
  65. package/.server/server/plugins/engine/pageControllers/validationOptions.js.map +1 -1
  66. package/.server/server/plugins/engine/unavailable-response.js +5 -2
  67. package/.server/server/plugins/engine/unavailable-response.js.map +1 -1
  68. package/.server/server/plugins/engine/views/components/_location-field-base.html +2 -1
  69. package/.server/server/plugins/engine/views/components/geospatialfield.html +1 -0
  70. package/.server/server/plugins/engine/views/components/osgridreffield.html +3 -1
  71. package/.server/server/plugins/engine/views/unavailable.html +14 -11
  72. package/package.json +1 -1
  73. package/src/client/javascripts/geospatial-map.js +169 -47
  74. package/src/client/javascripts/location-map.js +50 -2
  75. package/src/client/javascripts/map-constants.js +3 -0
  76. package/src/client/javascripts/map.js +5 -0
  77. package/src/server/plugins/engine/__stubs__/definitions.ts +155 -0
  78. package/src/server/plugins/engine/components/CheckboxesField.ts +34 -13
  79. package/src/server/plugins/engine/components/EastingNorthingField.ts +1 -1
  80. package/src/server/plugins/engine/components/FileUploadField.ts +26 -6
  81. package/src/server/plugins/engine/components/GeospatialField.ts +44 -11
  82. package/src/server/plugins/engine/components/LocationFieldBase.ts +7 -1
  83. package/src/server/plugins/engine/components/LocationFieldHelpers.ts +9 -2
  84. package/src/server/plugins/engine/components/helpers/components.ts +2 -1
  85. package/src/server/plugins/engine/components/helpers/geospatial.ts +32 -22
  86. package/src/server/plugins/engine/errors.ts +78 -0
  87. package/src/server/plugins/engine/form-availability.ts +8 -2
  88. package/src/server/plugins/engine/form-context.ts +4 -2
  89. package/src/server/plugins/engine/i18n/buildValidationMessages.ts +15 -10
  90. package/src/server/plugins/engine/i18n/translations/cy.json +117 -11
  91. package/src/server/plugins/engine/i18n/translations/en-GB.json +80 -11
  92. package/src/server/plugins/engine/i18n/types.ts +1 -0
  93. package/src/server/plugins/engine/models/FormModel.ts +12 -2
  94. package/src/server/plugins/engine/models/unavailable-view-model.ts +26 -5
  95. package/src/server/plugins/engine/pageControllers/helpers/pages.ts +2 -1
  96. package/src/server/plugins/engine/pageControllers/validationOptions.ts +2 -2
  97. package/src/server/plugins/engine/unavailable-response.ts +6 -2
  98. package/src/server/plugins/engine/views/components/_location-field-base.html +2 -1
  99. package/src/server/plugins/engine/views/components/geospatialfield.html +1 -0
  100. package/src/server/plugins/engine/views/components/osgridreffield.html +3 -1
  101. package/src/server/plugins/engine/views/unavailable.html +14 -11
@@ -1,9 +1,15 @@
1
1
  /**
2
+ * Get the map texts for the given language code
3
+ * @param {LanguageCode} lang - the lanugae code
4
+ */
5
+ export function getTexts(lang?: LanguageCode): GeospatialLanguageTexts;
6
+ /**
7
+ * @param {GeospatialPanelTexts} texts
2
8
  * @param {boolean} allowPoint
3
9
  * @param {boolean} allowLine
4
10
  * @param {boolean} allowShape
5
11
  */
6
- export function getHelpPanelHtml(allowPoint: boolean, allowLine: boolean, allowShape: boolean): string;
12
+ export function getHelpPanelHtml(texts: GeospatialPanelTexts, allowPoint: boolean, allowLine: boolean, allowShape: boolean): string;
7
13
  /**
8
14
  * Extract and parses the GeoJSON from the textarea
9
15
  * @param {HTMLTextAreaElement} geospatialInput - the textarea containing the geojson
@@ -34,8 +40,9 @@ export function addFeatureToMap(feature: Feature, drawPlugin: any, map: Interact
34
40
  * @param {string} mapId - the ID of the map
35
41
  * @param {boolean} [disabled] - render the list with disabled links
36
42
  * @param {boolean} [readonly] - render the list in readonly mode
43
+ * @param {LanguageCode} [lang] - the language for the feature details
37
44
  */
38
- export function createFeaturesHTML(features: FeatureCollection, mapId: string, disabled?: boolean, readonly?: boolean): string;
45
+ export function createFeaturesHTML(features: FeatureCollection, mapId: string, disabled?: boolean, readonly?: boolean, lang?: LanguageCode): string;
39
46
  /**
40
47
  * Focus feature
41
48
  * @param {Feature} feature - the feature
@@ -49,8 +56,9 @@ export function focusFeature(feature: Feature, mapProvider: MapLibreMap): void;
49
56
  * @param {string} mapId - the ID of the map
50
57
  * @param {boolean} [disabled] - render the list with disabled links
51
58
  * @param {boolean} [readonly] - render the list item in readonly mode
59
+ * @param {LanguageCode} [lang] - the language for the feature details
52
60
  */
53
- export function createFeatureHTML(feature: Feature, index: number, mapId: string, disabled?: boolean, readonly?: boolean): string;
61
+ export function createFeatureHTML(feature: Feature, index: number, mapId: string, disabled?: boolean, readonly?: boolean, lang?: LanguageCode): string;
54
62
  /**
55
63
  * Factory closure to manage the UI
56
64
  * @param {GeoJSON} geojson - the features
@@ -59,8 +67,9 @@ export function createFeatureHTML(feature: Feature, index: number, mapId: string
59
67
  * @param {HTMLDivElement} listEl - where to render the feature list
60
68
  * @param {HTMLTextAreaElement} geospatialInput - the geospatial textarea
61
69
  * @param { UIManagerOptions | undefined } options - extra options such as allowable geometry types
70
+ * @param {LanguageCode} [lang] - the language for the feature details
62
71
  */
63
- export function getUIManager(geojson: GeoJSON, map: InteractiveMap, mapId: string, listEl: HTMLDivElement, geospatialInput: HTMLTextAreaElement, options: UIManagerOptions | undefined): {
72
+ export function getUIManager(geojson: GeoJSON, map: InteractiveMap, mapId: string, listEl: HTMLDivElement, geospatialInput: HTMLTextAreaElement, options: UIManagerOptions | undefined, lang?: LanguageCode): {
64
73
  renderList: RenderList;
65
74
  renderValue: RenderValue;
66
75
  listEl: HTMLDivElement;
@@ -68,6 +77,10 @@ export function getUIManager(geojson: GeoJSON, map: InteractiveMap, mapId: strin
68
77
  focusDescriptionInput: () => void;
69
78
  getAllowableGeometryTypes: () => string[];
70
79
  };
80
+ /**
81
+ * @type {Record<LanguageCode, GeospatialLanguageTexts>}
82
+ */
83
+ export const languageTexts: Record<LanguageCode, GeospatialLanguageTexts>;
71
84
  export type GeoJSON = {
72
85
  /**
73
86
  * - the GeoJSON type string
@@ -113,7 +126,7 @@ export type ResetActiveFeature = () => void;
113
126
  /**
114
127
  * Renders the features into the list
115
128
  */
116
- export type RenderList = (disabled?: boolean | undefined) => void;
129
+ export type RenderList = (disabled?: boolean | undefined, lang?: LanguageCode | undefined) => void;
117
130
  /**
118
131
  * Renders the features JSON into the hidden textarea
119
132
  */
@@ -192,7 +205,141 @@ export type UIManager = {
192
205
  */
193
206
  getAllowableGeometryTypes: GetAllowableGeometryTypes;
194
207
  };
208
+ export type GeometryTexts = {
209
+ /**
210
+ * - the label for a point feature in the list
211
+ */
212
+ point: string;
213
+ /**
214
+ * - the label for a line string feature in the list
215
+ */
216
+ line: string;
217
+ /**
218
+ * - the label for a polygon feature in the list
219
+ */
220
+ polygon: string;
221
+ };
222
+ export type GeospatialPanelTexts = {
223
+ /**
224
+ * - the label for the info panel
225
+ */
226
+ label: string;
227
+ /**
228
+ * - the lede intro text for the info panel
229
+ */
230
+ ledeIntro: string;
231
+ /**
232
+ * - the lede outro text for the info panel
233
+ */
234
+ ledeOutro: string;
235
+ /**
236
+ * - the label for the info panel line text
237
+ */
238
+ lineText: string;
239
+ /**
240
+ * - the label for the info panel shape text
241
+ */
242
+ shapeText: string;
243
+ /**
244
+ * - the text for bullet point 1 in the info panel
245
+ */
246
+ point1: string;
247
+ /**
248
+ * - the text for bullet point 2 in the info panel
249
+ */
250
+ point2: string;
251
+ /**
252
+ * - the text for bullet point 3 in the info panel
253
+ */
254
+ point3: string;
255
+ /**
256
+ * - the text for bullet point 4 in the info panel
257
+ */
258
+ point4: string;
259
+ /**
260
+ * - the label for the info panel line or shape text
261
+ */
262
+ lineOrShapeText: string;
263
+ /**
264
+ * - the label for the info panel types phrase point
265
+ */
266
+ typesPhrasePoint: string;
267
+ /**
268
+ * - the label for the info panel types phrase line
269
+ */
270
+ typesPhraseLine: string;
271
+ /**
272
+ * - the label for the info panel types phrase shape
273
+ */
274
+ typesPhraseShape: string;
275
+ /**
276
+ * - the label for the info panel types phrase "or"
277
+ */
278
+ typesPhraseOr: string;
279
+ };
280
+ export type GeospatialLanguageTexts = {
281
+ /**
282
+ * - the descriptions of the geometry types
283
+ */
284
+ typeDescriptions: GeometryTexts;
285
+ /**
286
+ * - texts for the info panel
287
+ */
288
+ helpPanel: GeospatialPanelTexts;
289
+ /**
290
+ * - the labels for the action buttons
291
+ */
292
+ buttons: GeometryTexts;
293
+ /**
294
+ * - the first part of the label for a feature in the list
295
+ */
296
+ itemLabel1: string;
297
+ /**
298
+ * - the second part of the label for a feature in the list
299
+ */
300
+ itemLabel2: string;
301
+ /**
302
+ * - the label for the "update" link for a feature in the list
303
+ */
304
+ itemUpdateLink: string;
305
+ /**
306
+ * - the label for the "delete" link for a feature in the list
307
+ */
308
+ itemDeleteLink: string;
309
+ /**
310
+ * - the label for the "focus" link for a feature in the list
311
+ */
312
+ itemFocusLink: string;
313
+ /**
314
+ * - visually hidden text to add context to action links
315
+ */
316
+ itemVisuallyHidden: string;
317
+ /**
318
+ * - labels for the details section of a feature in the list
319
+ */
320
+ details: {
321
+ summary: string;
322
+ type: string;
323
+ centroidGridReference: string;
324
+ firstPointGridReference: string;
325
+ detailedCoordinates: string;
326
+ };
327
+ };
328
+ export type LanguageManager = {
329
+ /**
330
+ * - the language for the interactive map
331
+ */
332
+ lang: LanguageCode;
333
+ /**
334
+ * - the descriptions of the geometry types
335
+ */
336
+ texts: GeospatialLanguageTexts;
337
+ };
195
338
  export type Context = {
339
+ /**
340
+ * - the language manager for the interactive map
341
+ */
342
+ languageManager: LanguageManager;
196
343
  /**
197
344
  * - the interactive map
198
345
  */
@@ -222,6 +369,7 @@ export type Context = {
222
369
  */
223
370
  drawPlugin: any;
224
371
  };
372
+ import type { LanguageCode } from '../../client/javascripts/map.js';
225
373
  import type { MapsEnvironmentConfig } from '../../client/javascripts/map.js';
226
374
  import type { Feature } from '../../server/plugins/engine/types.js';
227
375
  import type { InteractiveMap } from '../../client/javascripts/map.js';
@@ -3,13 +3,33 @@ import createDatasetsPlugin from '@defra/interactive-map/plugins/datasets';
3
3
  // @ts-expect-error - no types
4
4
  import createDrawPlugin from '@defra/interactive-map/plugins/draw-ml';
5
5
  import { bbox } from '@turf/bbox';
6
+ import { DEFAULT_LANG, ENGLISH_LANG, WELSH_LANG } from "./map-constants.js";
6
7
  import { EVENTS, createMap, defaultConfig, getCentroidGridRef, getCoordinateGridRef, getMapCountryLayers, getMapLayers } from "./map.js";
7
8
  import sssiDataset from "./sssi-dataset.js";
8
9
  import { formatDelimtedList } from "./utils.js";
10
+ import cy from "../../server/plugins/engine/i18n/translations/cy.json" with { type: 'json' };
11
+ import enGB from "../../server/plugins/engine/i18n/translations/en-GB.json" with { type: 'json' };
12
+ const englishTranslations = enGB.components.geospatialField.map;
13
+ const welshTranslations = cy.components.geospatialField.map;
14
+
15
+ /**
16
+ * @type {Record<LanguageCode, GeospatialLanguageTexts>}
17
+ */
18
+ export const languageTexts = {
19
+ [ENGLISH_LANG]: englishTranslations,
20
+ [WELSH_LANG]: welshTranslations
21
+ };
22
+
23
+ /**
24
+ * Get the map texts for the given language code
25
+ * @param {LanguageCode} lang - the lanugae code
26
+ */
27
+ export function getTexts(lang = DEFAULT_LANG) {
28
+ return languageTexts[lang];
29
+ }
9
30
  const helpPanelConfig = {
10
31
  focus: false,
11
32
  showLabel: true,
12
- label: 'How to use this map',
13
33
  mobile: {
14
34
  slot: 'drawer',
15
35
  open: true,
@@ -31,51 +51,70 @@ const helpPanelConfig = {
31
51
  };
32
52
 
33
53
  /**
54
+ * @param {GeospatialPanelTexts} texts
34
55
  * @param {boolean} allowLine
35
56
  * @param {boolean} allowShape
36
57
  */
37
- function getLineOrShapeText(allowLine, allowShape) {
58
+ function getLineOrShapeText(texts, allowLine, allowShape) {
38
59
  if (allowLine && allowShape) {
39
- return 'a line or shape';
60
+ return texts.lineOrShapeText;
40
61
  }
41
62
  if (allowLine) {
42
- return 'a line';
63
+ return texts.lineText;
43
64
  }
44
65
  if (allowShape) {
45
- return 'a shape';
66
+ return texts.shapeText;
46
67
  }
47
68
  return '';
48
69
  }
49
70
 
50
71
  /**
72
+ * @param {GeospatialPanelTexts} texts
51
73
  * @param {boolean} allowPoint
52
74
  * @param {boolean} allowLine
53
75
  * @param {boolean} allowShape
54
76
  */
55
- function getAllowedTypesPhrase(allowPoint, allowLine, allowShape) {
77
+ function getAllowedTypesPhrase(texts, allowPoint, allowLine, allowShape) {
56
78
  const items = [];
57
79
  if (allowPoint) {
58
- items.push('points');
80
+ items.push(texts.typesPhrasePoint);
59
81
  }
60
82
  if (allowLine) {
61
- items.push('lines');
83
+ items.push(texts.typesPhraseLine);
62
84
  }
63
85
  if (allowShape) {
64
- items.push('shapes');
86
+ items.push(texts.typesPhraseShape);
87
+ }
88
+ return formatDelimtedList(items, ',', texts.typesPhraseOr);
89
+ }
90
+
91
+ /**
92
+ * Gets the type description for a given feature
93
+ * @param {Feature} feature - the geojson feature
94
+ * @param {GeometryTexts} typeDescriptions
95
+ */
96
+ function getTypeDescription(feature, typeDescriptions) {
97
+ switch (feature.geometry.type) {
98
+ case 'Point':
99
+ return typeDescriptions.point;
100
+ case 'LineString':
101
+ return typeDescriptions.line;
102
+ case 'Polygon':
103
+ return typeDescriptions.polygon;
65
104
  }
66
- return formatDelimtedList(items, ',', 'or');
67
105
  }
68
106
 
69
107
  /**
108
+ * @param {GeospatialPanelTexts} texts
70
109
  * @param {boolean} allowPoint
71
110
  * @param {boolean} allowLine
72
111
  * @param {boolean} allowShape
73
112
  */
74
- export function getHelpPanelHtml(allowPoint, allowLine, allowShape) {
75
- const lineOrShapeText = getLineOrShapeText(allowLine, allowShape);
76
- const doneExtra = lineOrShapeText ? `<li>Double‑click, or select 'Done', when you have finished drawing ${lineOrShapeText}</li>` : '';
77
- const allowedTypesText = getAllowedTypesPhrase(allowPoint, allowLine, allowShape);
78
- return `<p class="govuk-body-s govuk-!-margin-bottom-2">You can add ${allowedTypesText} to the map.</p><ul class="govuk-list govuk-list--number govuk-body-s"><li>Search for a county, place or postcode</li><li>Use the + and - icons to zoom in and out</li>${doneExtra}<li>Give the location a name</li></ul>`;
113
+ export function getHelpPanelHtml(texts, allowPoint, allowLine, allowShape) {
114
+ const lineOrShapeText = getLineOrShapeText(texts, allowLine, allowShape);
115
+ const point3 = lineOrShapeText ? `<li>${texts.point3} ${lineOrShapeText}</li>` : '';
116
+ const allowedTypesText = getAllowedTypesPhrase(texts, allowPoint, allowLine, allowShape);
117
+ return `<p class="govuk-body-s govuk-!-margin-bottom-2">${texts.ledeIntro} ${allowedTypesText} ${texts.ledeOutro}</p><ul class="govuk-list govuk-list--number govuk-body-s"><li>${texts.point1}</li><li>${texts.point2}</li>${point3}<li>${texts.point4}</li></ul>`;
79
118
  }
80
119
  const lineFeatureProperties = {
81
120
  stroke: 'rgba(0, 11, 112, 1)',
@@ -87,15 +126,6 @@ const polygonFeatureProperties = {
87
126
  fill: 'rgba(255, 221, 0, 0.2)',
88
127
  strokeWidth: 2
89
128
  };
90
-
91
- /**
92
- * @type {Record<'Point' | 'LineString' | 'Polygon', string>}
93
- */
94
- const typeDescriptions = {
95
- Point: 'Point',
96
- LineString: 'Line',
97
- Polygon: 'Shape'
98
- };
99
129
  const POINT_SVG = '<path d="M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0" /><circle cx="12" cy="10" r="3" />';
100
130
  const POLYGON_SVG = '<path d="M19.5 7v10M4.5 7v10M7 19.5h10M7 4.5h10"/><path d="M22 18v3a1 1 0 0 1-1 1h-3a1 1 0 0 1-1-1v-3a1 1 0 0 1 1-1h3a1 1 0 0 1 1 1zm0-15v3a1 1 0 0 1-1 1h-3a1 1 0 0 1-1-1V3a1 1 0 0 1 1-1h3a1 1 0 0 1 1 1zM7 18v3a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1v-3a1 1 0 0 1 1-1h3a1 1 0 0 1 1 1zM7 3v3a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V3a1 1 0 0 1 1-1h3a1 1 0 0 1 1 1z"/>';
101
131
  const LINE_SVG = '<path d="M5.706 16.294L16.294 5.706"/><path d="M21 2v3c0 .549-.451 1-1 1h-3c-.549 0-1-.451-1-1V2c0-.549.451-1 1-1h3c.549 0 1 .451 1 1zM6 17v3c0 .549-.451 1-1 1H2c-.549 0-1-.451-1-1v-3c0-.549.451-1 1-1h3c.549 0 1 .451 1 1z"/>';
@@ -177,12 +207,20 @@ export function processGeospatial(config, geospatial, index) {
177
207
  const options = {
178
208
  geometryTypes
179
209
  };
180
- const uiManager = getUIManager(geojson, map, mapId, listEl, geospatialInput, options);
210
+ const lang = /** @type {LanguageCode} */
211
+ // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
212
+ geospatial.dataset.lang || DEFAULT_LANG;
213
+ const uiManager = getUIManager(geojson, map, mapId, listEl, geospatialInput, options, lang);
214
+ const languageManager = {
215
+ lang,
216
+ texts: getTexts(lang)
217
+ };
181
218
 
182
219
  /**
183
220
  * @type {Context}
184
221
  */
185
222
  const context = {
223
+ languageManager,
186
224
  map,
187
225
  featuresManager,
188
226
  activeFeatureManager,
@@ -227,10 +265,11 @@ export function addFeatureToMap(feature, drawPlugin, map) {
227
265
  * @param {string} mapId - the ID of the map
228
266
  * @param {boolean} [disabled] - render the list with disabled links
229
267
  * @param {boolean} [readonly] - render the list in readonly mode
268
+ * @param {LanguageCode} [lang] - the language for the feature details
230
269
  */
231
- export function createFeaturesHTML(features, mapId, disabled = false, readonly = false) {
270
+ export function createFeaturesHTML(features, mapId, disabled = false, readonly = false, lang = DEFAULT_LANG) {
232
271
  return `<dl class="govuk-summary-list">
233
- ${features.map((feature, index) => createFeatureHTML(feature, index, mapId, disabled, readonly)).join('\n')}
272
+ ${features.map((feature, index) => createFeatureHTML(feature, index, mapId, disabled, readonly, lang)).join('\n')}
234
273
  </dl>`;
235
274
  }
236
275
 
@@ -250,8 +289,10 @@ export function focusFeature(feature, mapProvider) {
250
289
  * @param {string} mapId - the ID of the map
251
290
  * @param {boolean} [disabled] - render the list with disabled links
252
291
  * @param {boolean} [readonly] - render the list item in readonly mode
292
+ * @param {LanguageCode} [lang] - the language for the feature details
253
293
  */
254
- export function createFeatureHTML(feature, index, mapId, disabled = false, readonly = false) {
294
+ export function createFeatureHTML(feature, index, mapId, disabled = false, readonly = false, lang = DEFAULT_LANG) {
295
+ const texts = getTexts(lang);
255
296
  const flattened = feature.geometry.coordinates.flat(2);
256
297
  const points = [];
257
298
  for (let i = 0; i < flattened.length; i += 2) {
@@ -263,25 +304,26 @@ export function createFeatureHTML(feature, index, mapId, disabled = false, reado
263
304
  // Change action link
264
305
  const changeAction = () => `<li class="govuk-summary-list__actions-list-item">
265
306
  <a class="govuk-link govuk-link--no-visited-state ${disabled ? 'govuk-link--disabled' : ''}" href="#${mapId}" data-action="edit" data-id="${feature.id}"
266
- data-type="${feature.geometry.type}">Update<span class="govuk-visually-hidden"> location</span></a>
307
+ data-type="${feature.geometry.type}">${texts.itemUpdateLink}<span class="govuk-visually-hidden"> ${texts.itemVisuallyHidden}</span></a>
267
308
  </li>`;
268
309
 
269
310
  // Delete action link
270
311
  const deleteAction = () => `<li class="govuk-summary-list__actions-list-item">
271
312
  <a class="govuk-link govuk-link--no-visited-state ${disabled ? 'govuk-link--disabled' : ''}" href="#" data-action="delete" data-id="${feature.id}"
272
- data-type="${feature.geometry.type}">Delete<span class="govuk-visually-hidden"> location</span></a>
313
+ data-type="${feature.geometry.type}">${texts.itemDeleteLink}<span class="govuk-visually-hidden"> ${texts.itemVisuallyHidden}</span></a>
273
314
  </li>`;
274
315
 
275
316
  // Focus action link
276
317
  const focusAction = () => `<li class="govuk-summary-list__actions-list-item">
277
- <a class="govuk-link govuk-link--no-visited-state" href="#${mapId}" data-action="focus" data-id="${feature.id}">Show<span class="govuk-visually-hidden"> location</span></a>
318
+ <a class="govuk-link govuk-link--no-visited-state" href="#${mapId}" data-action="focus" data-id="${feature.id}">${texts.itemFocusLink}<span class="govuk-visually-hidden"> ${texts.itemVisuallyHidden}</span></a>
278
319
  </li>`;
279
320
  const links = readonly ? focusAction() : `${changeAction()}${deleteAction()}`;
280
321
  const actions = `<ul class="govuk-summary-list__actions-list">${links}</ul>`;
322
+ const typeDescription = getTypeDescription(feature, texts.typeDescriptions);
281
323
  return `<div class="govuk-summary-list__row govuk-summary-list__row--no-border">
282
324
  <dt class="govuk-summary-list__key">
283
325
  <div class="govuk-form-group">
284
- <label class="govuk-label govuk-label--s" ${readonly ? '' : `for="description_${index}"`}>Location ${index + 1} description</label>
326
+ <label class="govuk-label govuk-label--s" ${readonly ? '' : `for="description_${index}"`}>${texts.itemLabel1} ${index + 1} ${texts.itemLabel2}</label>
285
327
  ${description}
286
328
  </div>
287
329
  </dt>
@@ -292,24 +334,24 @@ export function createFeatureHTML(feature, index, mapId, disabled = false, reado
292
334
  <div class="govuk-summary-list__row">
293
335
  <details class="govuk-details govuk-!-margin-bottom-2">
294
336
  <summary class="govuk-details__summary">
295
- <span class="govuk-details__summary-text">Coordinates</span>
337
+ <span class="govuk-details__summary-text">${texts.details.summary}</span>
296
338
  </summary>
297
339
  <div class="govuk-details__text">
298
340
  <dl class="govuk-summary-list">
299
341
  <div class="govuk-summary-list__row">
300
- <dt class="govuk-summary-list__key">Type</dt>
301
- <dd class="govuk-summary-list__value">${typeDescriptions[feature.geometry.type]}</dd>
342
+ <dt class="govuk-summary-list__key">${texts.details.type}</dt>
343
+ <dd class="govuk-summary-list__value">${typeDescription}</dd>
302
344
  </div>
303
345
  <div class="govuk-summary-list__row">
304
- <dt class="govuk-summary-list__key">Centre grid reference</dt>
346
+ <dt class="govuk-summary-list__key">${texts.details.centroidGridReference}</dt>
305
347
  <dd class="govuk-summary-list__value">${feature.properties.centroidGridReference}</dd>
306
348
  </div>
307
349
  <div class="govuk-summary-list__row">
308
- <dt class="govuk-summary-list__key">First point grid reference</dt>
350
+ <dt class="govuk-summary-list__key">${texts.details.firstPointGridReference}</dt>
309
351
  <dd class="govuk-summary-list__value">${feature.properties.coordinateGridReference}</dd>
310
352
  </div>
311
353
  <div class="govuk-summary-list__row">
312
- <dt class="govuk-summary-list__key">Detailed coordinates</dt>
354
+ <dt class="govuk-summary-list__key">${texts.details.detailedCoordinates}</dt>
313
355
  <dd class="govuk-summary-list__value">
314
356
  <ol class="govuk-list govuk-list--number">${coordinates}</ol>
315
357
  </dd>
@@ -464,11 +506,12 @@ function getFeaturesManager(geojson) {
464
506
  * @param {string} mapId - the ID of the map
465
507
  * @param {HTMLDivElement} listEl - where to render the feature list
466
508
  * @param {Function} renderValue - function that renders the features JSON into the hidden textarea
509
+ * @param {LanguageCode} [lang] - the language for the feature details
467
510
  * @returns {RenderList}
468
511
  */
469
- function getListRenderer(geojson, mapId, listEl, renderValue) {
512
+ function getListRenderer(geojson, mapId, listEl, renderValue, lang = DEFAULT_LANG) {
470
513
  return function renderList(disabled = false) {
471
- const html = createFeaturesHTML(geojson.features, mapId, disabled);
514
+ const html = createFeaturesHTML(geojson.features, mapId, disabled, false, lang);
472
515
  listEl.innerHTML = html;
473
516
  renderValue();
474
517
  };
@@ -494,8 +537,9 @@ function getValueRenderer(geojson, geospatialInput) {
494
537
  * @param {HTMLDivElement} listEl - where to render the feature list
495
538
  * @param {HTMLTextAreaElement} geospatialInput - the geospatial textarea
496
539
  * @param { UIManagerOptions | undefined } options - extra options such as allowable geometry types
540
+ * @param {LanguageCode} [lang] - the language for the feature details
497
541
  */
498
- export function getUIManager(geojson, map, mapId, listEl, geospatialInput, options) {
542
+ export function getUIManager(geojson, map, mapId, listEl, geospatialInput, options, lang = DEFAULT_LANG) {
499
543
  /**
500
544
  * Get a CSV list of geometry types the user can create
501
545
  * @returns {string[]}
@@ -534,7 +578,7 @@ export function getUIManager(geojson, map, mapId, listEl, geospatialInput, optio
534
578
  }
535
579
  }
536
580
  const renderValue = getValueRenderer(geojson, geospatialInput);
537
- const renderList = getListRenderer(geojson, mapId, listEl, renderValue);
581
+ const renderList = getListRenderer(geojson, mapId, listEl, renderValue, lang);
538
582
 
539
583
  /** @type {UIManager} */
540
584
  return {
@@ -612,16 +656,20 @@ function onMapReadyFactory(context) {
612
656
  const allowPoint = types.includes('point');
613
657
  const allowLine = types.includes('line');
614
658
  const allowShape = types.includes('shape');
659
+ const {
660
+ texts
661
+ } = context.languageManager;
615
662
 
616
663
  // Add info panel
617
664
  map.addPanel('info', {
618
665
  ...helpPanelConfig,
619
- html: getHelpPanelHtml(allowPoint, allowLine, allowShape)
666
+ label: texts.helpPanel.label,
667
+ html: getHelpPanelHtml(texts.helpPanel, allowPoint, allowLine, allowShape)
620
668
  });
621
669
  if (allowPoint) {
622
670
  map.addButton('btnAddPoint', {
623
671
  variant: 'tertiary',
624
- label: 'Add point',
672
+ label: texts.buttons.point,
625
673
  iconSvgContent: POINT_SVG,
626
674
  onClick: () => {
627
675
  resetActiveFeature();
@@ -643,7 +691,7 @@ function onMapReadyFactory(context) {
643
691
  if (allowShape) {
644
692
  map.addButton('btnAddPolygon', {
645
693
  variant: 'tertiary',
646
- label: 'Add shape',
694
+ label: texts.buttons.polygon,
647
695
  iconSvgContent: POLYGON_SVG,
648
696
  onClick: () => {
649
697
  resetActiveFeature();
@@ -665,7 +713,7 @@ function onMapReadyFactory(context) {
665
713
  if (allowLine) {
666
714
  map.addButton('btnAddLine', {
667
715
  variant: 'tertiary',
668
- label: 'Add line',
716
+ label: texts.buttons.line,
669
717
  iconSvgContent: LINE_SVG,
670
718
  onClick: () => {
671
719
  resetActiveFeature();
@@ -1138,6 +1186,7 @@ function onListElKeydownFactory() {
1138
1186
  * Renders the features into the list
1139
1187
  * @callback RenderList
1140
1188
  * @param {boolean} [disabled] - whether to render the list with disabled links
1189
+ * @param {LanguageCode} [lang] - the language for the feature details
1141
1190
  * @returns {void}
1142
1191
  */
1143
1192
 
@@ -1192,8 +1241,59 @@ function onListElKeydownFactory() {
1192
1241
  * @property {GetAllowableGeometryTypes} getAllowableGeometryTypes - function that returns the array of geometry types a user can create
1193
1242
  */
1194
1243
 
1244
+ /**
1245
+ * @typedef {object} GeometryTexts
1246
+ * @property {string} point - the label for a point feature in the list
1247
+ * @property {string} line - the label for a line string feature in the list
1248
+ * @property {string} polygon - the label for a polygon feature in the list
1249
+ */
1250
+
1251
+ /**
1252
+ * @typedef {object} GeospatialPanelTexts
1253
+ * @property {string} label - the label for the info panel
1254
+ * @property {string} ledeIntro - the lede intro text for the info panel
1255
+ * @property {string} ledeOutro - the lede outro text for the info panel
1256
+ * @property {string} lineText - the label for the info panel line text
1257
+ * @property {string} shapeText - the label for the info panel shape text
1258
+ * @property {string} point1 - the text for bullet point 1 in the info panel
1259
+ * @property {string} point2 - the text for bullet point 2 in the info panel
1260
+ * @property {string} point3 - the text for bullet point 3 in the info panel
1261
+ * @property {string} point4 - the text for bullet point 4 in the info panel
1262
+ * @property {string} lineOrShapeText - the label for the info panel line or shape text
1263
+ * @property {string} typesPhrasePoint - the label for the info panel types phrase point
1264
+ * @property {string} typesPhraseLine - the label for the info panel types phrase line
1265
+ * @property {string} typesPhraseShape - the label for the info panel types phrase shape
1266
+ * @property {string} typesPhraseOr - the label for the info panel types phrase "or"
1267
+ */
1268
+
1269
+ /**
1270
+ * @typedef {object} GeospatialLanguageTexts
1271
+ * @property {GeometryTexts} typeDescriptions - the descriptions of the geometry types
1272
+ * @property {GeospatialPanelTexts} helpPanel - texts for the info panel
1273
+ * @property {GeometryTexts} buttons - the labels for the action buttons
1274
+ * @property {string} itemLabel1 - the first part of the label for a feature in the list
1275
+ * @property {string} itemLabel2 - the second part of the label for a feature in the list
1276
+ * @property {string} itemUpdateLink - the label for the "update" link for a feature in the list
1277
+ * @property {string} itemDeleteLink - the label for the "delete" link for a feature in the list
1278
+ * @property {string} itemFocusLink - the label for the "focus" link for a feature in the list
1279
+ * @property {string} itemVisuallyHidden - visually hidden text to add context to action links
1280
+ * @property {object} details - labels for the details section of a feature in the list
1281
+ * @property {string} details.summary - label for the summary of a feature in the list
1282
+ * @property {string} details.type - label for the type of a feature in the list
1283
+ * @property {string} details.centroidGridReference - label for the centroid grid reference of a feature in the list
1284
+ * @property {string} details.firstPointGridReference - label for the first point grid reference of a feature in the list
1285
+ * @property {string} details.detailedCoordinates - label for the detailed coordinates of a feature in the list
1286
+ */
1287
+
1288
+ /**
1289
+ * @typedef {object} LanguageManager
1290
+ * @property {LanguageCode} lang - the language for the interactive map
1291
+ * @property {GeospatialLanguageTexts} texts - the descriptions of the geometry types
1292
+ */
1293
+
1195
1294
  /**
1196
1295
  * @typedef {object} Context
1296
+ * @property {LanguageManager} languageManager - the language manager for the interactive map
1197
1297
  * @property {InteractiveMap} map - the interactive map
1198
1298
  * @property {MapLibreMap} [mapProvider] - the interactive map provider
1199
1299
  * @property {FeaturesManager} featuresManager - the features manager
@@ -1204,6 +1304,7 @@ function onListElKeydownFactory() {
1204
1304
  */
1205
1305
 
1206
1306
  /**
1307
+ * @import { LanguageCode } from '../../client/javascripts/map.js'
1207
1308
  * @import { MapLibreMap, UIManagerOptions } from '../../client/javascripts/map.js'
1208
1309
  */
1209
1310
  //# sourceMappingURL=geospatial-map.js.map