@defra/forms-engine-plugin 5.0.0-alpha.28 → 5.0.0-alpha.29
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/37c964ca545c240f010a.mjs +2 -0
- package/.public/37c964ca545c240f010a.mjs.LICENSE.txt +4 -0
- package/.public/assets-manifest.json +3 -0
- package/.public/javascripts/shared.min.js +1 -1
- package/.public/javascripts/shared.min.js.LICENSE.txt +2 -0
- package/.public/javascripts/shared.min.js.map +1 -1
- package/.public/javascripts/vendor/@defra.min.js +1 -1
- package/.public/javascripts/vendor/@defra.min.js.map +1 -1
- package/.public/javascripts/vendor/maplibre-gl.min.js +1 -1
- package/.public/javascripts/vendor/maplibre-gl.min.js.LICENSE.txt +3 -3
- package/.public/javascripts/vendor/maplibre-gl.min.js.map +1 -1
- package/.public/stylesheets/application.min.css +1 -1
- package/.public/stylesheets/application.min.css.map +1 -1
- package/.server/client/javascripts/geospatial-map.js +3 -3
- package/.server/client/javascripts/geospatial-map.js.map +1 -1
- package/.server/client/javascripts/location-map.js +2 -2
- package/.server/client/javascripts/location-map.js.map +1 -1
- package/.server/client/javascripts/map.d.ts +5 -2
- package/.server/client/javascripts/map.js +17 -5
- package/.server/client/javascripts/map.js.map +1 -1
- package/.server/server/plugins/engine/components/AutocompleteField.d.ts +1 -2
- package/.server/server/plugins/engine/components/AutocompleteField.js +9 -4
- package/.server/server/plugins/engine/components/AutocompleteField.js.map +1 -1
- package/.server/server/plugins/engine/components/LocationFieldBase.js +11 -6
- package/.server/server/plugins/engine/components/LocationFieldBase.js.map +1 -1
- package/.server/server/plugins/engine/components/NumberField.js +14 -8
- package/.server/server/plugins/engine/components/NumberField.js.map +1 -1
- package/.server/server/plugins/engine/components/YesNoField.d.ts +1 -3
- package/.server/server/plugins/engine/components/YesNoField.js +9 -4
- package/.server/server/plugins/engine/components/YesNoField.js.map +1 -1
- package/.server/server/plugins/engine/components/helpers/index.d.ts +14 -1
- package/.server/server/plugins/engine/components/helpers/index.js +32 -0
- package/.server/server/plugins/engine/components/helpers/index.js.map +1 -1
- package/package.json +4 -4
- package/src/client/javascripts/geospatial-map.js +3 -3
- package/src/client/javascripts/location-map.js +2 -2
- package/src/client/javascripts/map.js +19 -8
- package/src/server/plugins/engine/components/AutocompleteField.ts +12 -5
- package/src/server/plugins/engine/components/LocationFieldBase.ts +18 -8
- package/src/server/plugins/engine/components/NumberField.ts +17 -13
- package/src/server/plugins/engine/components/YesNoField.ts +14 -4
- package/src/server/plugins/engine/components/helpers/index.ts +45 -1
|
@@ -126,10 +126,15 @@ export function getCentroidGridRef(feature) {
|
|
|
126
126
|
}
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
-
/**
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
129
|
+
/**
|
|
130
|
+
* Get the default config for a map
|
|
131
|
+
* @returns {InteractiveMapInitConfig}
|
|
132
|
+
*/
|
|
133
|
+
export const getDefaultConfig = () => {
|
|
134
|
+
return {
|
|
135
|
+
zoom: '6',
|
|
136
|
+
center: [DEFAULT_LONG, DEFAULT_LAT]
|
|
137
|
+
};
|
|
133
138
|
};
|
|
134
139
|
export const EVENTS = {
|
|
135
140
|
mapReady: 'map:ready',
|
|
@@ -165,6 +170,7 @@ export function initMaps(config = {}) {
|
|
|
165
170
|
const {
|
|
166
171
|
assetPath = '/assets',
|
|
167
172
|
apiPath = '/form/api',
|
|
173
|
+
workerPath = '/assets/interactive-map/maplibre-gl-worker.mjs',
|
|
168
174
|
data = defaultData
|
|
169
175
|
} = config;
|
|
170
176
|
const locations = document.querySelectorAll('.app-location-field');
|
|
@@ -193,6 +199,7 @@ export function initMaps(config = {}) {
|
|
|
193
199
|
processLocation({
|
|
194
200
|
assetPath,
|
|
195
201
|
apiPath,
|
|
202
|
+
workerPath,
|
|
196
203
|
data
|
|
197
204
|
}, location, index);
|
|
198
205
|
});
|
|
@@ -200,6 +207,7 @@ export function initMaps(config = {}) {
|
|
|
200
207
|
processGeospatial({
|
|
201
208
|
assetPath,
|
|
202
209
|
apiPath,
|
|
210
|
+
workerPath,
|
|
203
211
|
data
|
|
204
212
|
}, geospatial, index);
|
|
205
213
|
});
|
|
@@ -257,6 +265,7 @@ export function createMap(mapId, initConfig, mapsConfig) {
|
|
|
257
265
|
const {
|
|
258
266
|
assetPath,
|
|
259
267
|
apiPath,
|
|
268
|
+
workerPath,
|
|
260
269
|
data = defaultData
|
|
261
270
|
} = mapsConfig;
|
|
262
271
|
const logoAltText = 'Ordnance survey logo';
|
|
@@ -273,7 +282,9 @@ export function createMap(mapId, initConfig, mapsConfig) {
|
|
|
273
282
|
const map = new InteractiveMap(mapId, {
|
|
274
283
|
enableFullscreen: true,
|
|
275
284
|
autoColorScheme: false,
|
|
276
|
-
mapProvider: maplibreProvider(
|
|
285
|
+
mapProvider: maplibreProvider({
|
|
286
|
+
workerUrl: workerPath
|
|
287
|
+
}),
|
|
277
288
|
behaviour: 'inline',
|
|
278
289
|
minZoom: 6,
|
|
279
290
|
maxZoom: 18,
|
|
@@ -437,6 +448,7 @@ export function getMapCountryLayers(apiPath, country) {
|
|
|
437
448
|
* @typedef {object} MapsEnvironmentConfig
|
|
438
449
|
* @property {string} assetPath - the root asset path
|
|
439
450
|
* @property {string} apiPath - the root API path
|
|
451
|
+
* @property {string} workerPath - the maplibre worker path
|
|
440
452
|
* @property {TileData} data - the tile data config
|
|
441
453
|
*/
|
|
442
454
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"map.js","names":["InteractiveMap","createInteractPlugin","createMapStylesPlugin","createScaleBarPlugin","createSearchPlugin","maplibreProvider","centroid","OsGridRef","LatLon","processGeospatial","processLocation","DEFAULT_LAT","DEFAULT_LONG","COMPANY_SYMBOL_CODE","defaultData","VTS_OUTDOOR_URL","VTS_DARK_URL","VTS_BLACK_AND_WHITE_URL","VTS_AERIAL_URL","latLongToEastingNorthing","lat","long","point","toOsGrid","eastingNorthingToLatLong","easting","northing","latLong","toLatLon","latitude","longitude","latLongToOsGridRef","toString","osGridRefToLatLong","osGridRef","parse","getCoordinateGridRef","feature","geometry","type","coordinates","getCentroidGridRef","centre","defaultConfig","zoom","center","EVENTS","mapReady","interactMarkerChange","drawReady","drawCreated","drawEdited","drawCancelled","formSubmitFactory","buttons","onFormSubmit","e","submitter","HTMLButtonElement","includes","preventDefault","initMaps","config","assetPath","apiPath","data","locations","document","querySelectorAll","geospatials","length","form","closest","Array","from","addEventListener","forEach","location","index","geospatial","makeTileRequestTransformer","transformTileRequest","url","resourceType","startsWith","replace","window","origin","headers","encodeURIComponent","spritesPath","path","substring","createMap","mapId","initConfig","mapsConfig","logoAltText","interactPlugin","markerColor","outdoor","dark","interactionModes","multiSelect","map","enableFullscreen","autoColorScheme","mapProvider","behaviour","minZoom","maxZoom","containerHeight","enableZoomControls","transformRequest","plugins","mapStyles","id","label","thumbnail","logo","attribution","String","fromCodePoint","Date","getFullYear","backgroundColor","mapColorScheme","appColorScheme","osNamesURL","width","showMarker","units","centerMap","addMarker","flyTo","essential","getMapLayers","layers","trimmed","trim","split","getMapCountryLayers","country","datasets","push","geojson","showInKey","showInMenu","style","stroke","strokeWidth","fill"],"sources":["../../../src/client/javascripts/map.js"],"sourcesContent":["// @ts-expect-error - no types\nimport InteractiveMap from '@defra/interactive-map'\n// @ts-expect-error - no types\nimport createInteractPlugin from '@defra/interactive-map/plugins/interact'\n// @ts-expect-error - no types\nimport createMapStylesPlugin from '@defra/interactive-map/plugins/map-styles'\n// @ts-expect-error - no types\nimport createScaleBarPlugin from '@defra/interactive-map/plugins/scale-bar'\n// @ts-expect-error - no types\nimport createSearchPlugin from '@defra/interactive-map/plugins/search'\n// @ts-expect-error - no types\nimport maplibreProvider from '@defra/interactive-map/providers/maplibre'\nimport { centroid } from '@turf/centroid'\nimport OsGridRef, { LatLon } from 'geodesy/osgridref.js'\n\nimport { processGeospatial } from '~/src/client/javascripts/geospatial-map.js'\nimport { processLocation } from '~/src/client/javascripts/location-map.js'\n\n// Center of UK\nconst DEFAULT_LAT = 53.825564\nconst DEFAULT_LONG = -2.421975\nconst COMPANY_SYMBOL_CODE = 169\n\nconst defaultData = {\n VTS_OUTDOOR_URL: '/api/maps/vts/OS_VTS_3857_Outdoor.json',\n VTS_DARK_URL: '/api/maps/vts/OS_VTS_3857_Dark.json',\n VTS_BLACK_AND_WHITE_URL: '/api/maps/vts/OS_VTS_3857_Black_and_White.json',\n VTS_AERIAL_URL: '/api/maps/vts/esri-aerial.json'\n}\n\n/**\n * Converts lat long to easting and northing\n * @param {object} param\n * @param {number} param.lat\n * @param {number} param.long\n * @returns {{ easting: number, northing: number }}\n */\nexport function latLongToEastingNorthing({ lat, long }) {\n const point = new LatLon(lat, long)\n\n return point.toOsGrid()\n}\n\n/**\n * Converts easting and northing to lat long\n * @param {object} param\n * @param {number} param.easting\n * @param {number} param.northing\n * @returns {{ lat: number, long: number }}\n */\nexport function eastingNorthingToLatLong({ easting, northing }) {\n const point = new OsGridRef(easting, northing)\n const latLong = point.toLatLon()\n\n return { lat: latLong.latitude, long: latLong.longitude }\n}\n\n/**\n * Converts lat long to an ordnance survey grid reference\n * @param {object} param\n * @param {number} param.lat\n * @param {number} param.long\n * @returns {string}\n */\nexport function latLongToOsGridRef({ lat, long }) {\n const point = new LatLon(lat, long)\n\n return point.toOsGrid().toString()\n}\n\n/**\n * Converts an ordnance survey grid reference to lat long\n * @param {string} osGridRef\n * @returns {{ lat: number, long: number }}\n */\nexport function osGridRefToLatLong(osGridRef) {\n const point = OsGridRef.parse(osGridRef)\n const latLong = point.toLatLon()\n\n return { lat: latLong.latitude, long: latLong.longitude }\n}\n\n/**\n * Get the grid ref from the first coordinate of a long/lat feature\n * @param {Feature} feature\n */\nexport function getCoordinateGridRef(feature) {\n if (feature.geometry.type === 'Point') {\n const [long, lat] = feature.geometry.coordinates\n const point = new LatLon(lat, long)\n\n return point.toOsGrid().toString()\n } else if (feature.geometry.type === 'LineString') {\n const [long, lat] = feature.geometry.coordinates[0]\n const point = new LatLon(lat, long)\n\n return point.toOsGrid().toString()\n } else {\n const [long, lat] = feature.geometry.coordinates[0][0]\n const point = new LatLon(lat, long)\n\n return point.toOsGrid().toString()\n }\n}\n\n/**\n * Get the centroid grid ref from a long/lat feature\n * @param {Feature} feature\n */\nexport function getCentroidGridRef(feature) {\n if (feature.geometry.type === 'Point') {\n const [long, lat] = feature.geometry.coordinates\n const point = new LatLon(lat, long)\n\n return point.toOsGrid().toString()\n } else {\n const centre = centroid(feature)\n const [long, lat] = centre.geometry.coordinates\n const point = new LatLon(lat, long)\n\n return point.toOsGrid().toString()\n }\n}\n\n/** @type {InteractiveMapInitConfig} */\nexport const defaultConfig = {\n zoom: '6',\n center: [DEFAULT_LONG, DEFAULT_LAT]\n}\n\nexport const EVENTS = {\n mapReady: 'map:ready',\n interactMarkerChange: 'interact:markerchange',\n drawReady: 'draw:ready',\n drawCreated: 'draw:created',\n drawEdited: 'draw:edited',\n drawCancelled: 'draw:cancelled'\n}\n\n/**\n * Make a form submit handler that only allows submissions from allowed buttons\n * @param {HTMLButtonElement[]} buttons - the form buttons to allow submissions\n */\nexport function formSubmitFactory(buttons) {\n /**\n * The submit handler\n * @param {SubmitEvent} e\n */\n const onFormSubmit = function (e) {\n if (\n !(e.submitter instanceof HTMLButtonElement) ||\n !buttons.includes(e.submitter)\n ) {\n e.preventDefault()\n }\n }\n\n return onFormSubmit\n}\n\n/**\n * Initialise location maps\n * @param {Partial<MapsEnvironmentConfig>} config - the map configuration\n */\nexport function initMaps(config = {}) {\n const {\n assetPath = '/assets',\n apiPath = '/form/api',\n data = defaultData\n } = config\n const locations = document.querySelectorAll('.app-location-field')\n const geospatials = document.querySelectorAll('.app-geospatial-field')\n\n // TODO: Fix this in `interactive-map`\n // If there are location components on the page fix up the main form submit\n // handler so it doesn't fire when using the integrated map search feature\n if (locations.length) {\n const form = locations[0].closest('form')\n\n if (form === null) {\n return\n }\n\n const buttons = Array.from(form.querySelectorAll('button'))\n form.addEventListener('submit', formSubmitFactory(buttons), false)\n }\n\n if (geospatials.length) {\n const form = geospatials[0].closest('form')\n\n if (form === null) {\n return\n }\n\n const buttons = Array.from(form.querySelectorAll('button'))\n form.addEventListener('submit', formSubmitFactory(buttons), false)\n }\n\n locations.forEach((location, index) => {\n processLocation({ assetPath, apiPath, data }, location, index)\n })\n\n geospatials.forEach((geospatial, index) => {\n processGeospatial({ assetPath, apiPath, data }, geospatial, index)\n })\n}\n\n/**\n * OS API request proxy factory\n * @param {string} apiPath - the root API path\n */\nexport function makeTileRequestTransformer(apiPath) {\n /**\n * Proxy OS API requests via our server\n * @param {string} url - the request URL\n * @param {string} resourceType - the resource type\n */\n return function transformTileRequest(url, resourceType) {\n if (url.startsWith('https://api.os.uk')) {\n if (resourceType === 'Tile') {\n return {\n url: url.replace(\n 'https://api.os.uk/maps/vector/v1/vts',\n `${window.location.origin}${apiPath}`\n ),\n headers: {}\n }\n }\n\n if (resourceType !== 'Style') {\n return {\n url: `${apiPath}/map-proxy?url=${encodeURIComponent(url)}`,\n headers: {}\n }\n }\n }\n\n const spritesPath =\n 'https://raw.githubusercontent.com/OrdnanceSurvey/OS-Vector-Tile-API-Stylesheets/main'\n\n // Proxy sprite requests\n if (url.startsWith(spritesPath)) {\n const path = url.substring(spritesPath.length)\n return {\n url: `${apiPath}/maps/vts${path}`,\n headers: {}\n }\n }\n\n return { url, headers: {} }\n }\n}\n\n/**\n * Create a Defra map instance\n * @param {string} mapId - the map id\n * @param {InteractiveMapInitConfig} initConfig - the map initial configuration\n * @param {MapsEnvironmentConfig} mapsConfig - the map environment params\n */\nexport function createMap(mapId, initConfig, mapsConfig) {\n const { assetPath, apiPath, data = defaultData } = mapsConfig\n const logoAltText = 'Ordnance survey logo'\n const interactPlugin = createInteractPlugin({\n markerColor: { outdoor: '#ff0000', dark: '#00ff00' },\n interactionModes: ['placeMarker'],\n multiSelect: false\n })\n\n /** @type {InteractiveMap} */\n const map = new InteractiveMap(mapId, {\n enableFullscreen: true,\n autoColorScheme: false,\n mapProvider: maplibreProvider(),\n behaviour: 'inline',\n minZoom: 6,\n maxZoom: 18,\n containerHeight: '400px',\n enableZoomControls: true,\n transformRequest: makeTileRequestTransformer(apiPath),\n ...initConfig,\n plugins: [\n createMapStylesPlugin({\n mapStyles: [\n {\n id: 'outdoor',\n label: 'Outdoor',\n url: data.VTS_OUTDOOR_URL,\n thumbnail: `${assetPath}/interactive-map/assets/images/outdoor-map-thumb.jpg`,\n logo: `${assetPath}/interactive-map/assets/images/os-logo.svg`,\n logoAltText,\n attribution: `Contains OS data ${String.fromCodePoint(COMPANY_SYMBOL_CODE)} Crown copyright and database rights ${new Date().getFullYear()}`,\n backgroundColor: '#f5f5f0'\n },\n {\n id: 'dark',\n label: 'Dark',\n url: data.VTS_DARK_URL,\n mapColorScheme: 'dark',\n appColorScheme: 'dark',\n thumbnail: `${assetPath}/interactive-map/assets/images/dark-map-thumb.jpg`,\n logo: `${assetPath}/interactive-map/assets/images/os-logo-white.svg`,\n logoAltText,\n attribution: `Contains OS data ${String.fromCodePoint(COMPANY_SYMBOL_CODE)} Crown copyright and database rights ${new Date().getFullYear()}`\n },\n {\n id: 'black-and-white',\n label: 'Black/White',\n url: data.VTS_BLACK_AND_WHITE_URL,\n thumbnail: `${assetPath}/interactive-map/assets/images/black-and-white-map-thumb.jpg`,\n logo: `${assetPath}/interactive-map/assets/images/os-logo-black.svg`,\n logoAltText,\n attribution: `Contains OS data ${String.fromCodePoint(COMPANY_SYMBOL_CODE)} Crown copyright and database rights ${new Date().getFullYear()}`\n },\n {\n id: 'aerial',\n label: 'Aerial',\n url: data.VTS_AERIAL_URL,\n thumbnail: `${assetPath}/interactive-map/assets/images/aerial-map-thumb.jpg`,\n logo: `${assetPath}/interactive-map/assets/images/esri-logo.png`,\n logoAltText: 'Powered by Esri',\n attribution: `Tiles ${String.fromCodePoint(COMPANY_SYMBOL_CODE)} Esri — Source: Esri, Maxar, Earthstar Geographics, and the GIS User Community ${new Date().getFullYear()}`\n }\n ]\n }),\n interactPlugin,\n createSearchPlugin({\n osNamesURL: `${apiPath}/geocode-proxy?query={query}`,\n width: '300px',\n showMarker: false\n }),\n createScaleBarPlugin({\n units: 'metric'\n }),\n ...(initConfig.plugins ?? [])\n ]\n })\n\n return { map, interactPlugin }\n}\n\n/**\n * Updates the marker position and moves the map view port the new location\n * @param {InteractiveMap} map - the map component instance (of InteractiveMap)\n * @param {MapLibreMap} mapProvider - the map provider instance (of MapLibreMap)\n * @param {MapCenter} center - the point\n */\nexport function centerMap(map, mapProvider, center) {\n // Move the 'location' marker to the new point\n map.addMarker('location', center)\n\n // Pan & zoom the map to the new valid location\n mapProvider.flyTo({\n center,\n zoom: 14,\n essential: true\n })\n}\n\n/**\n * Parse CSV string layers\n * @param {string | undefined} layers\n * @returns {string[]}\n */\nexport function getMapLayers(layers) {\n const trimmed = layers?.trim()\n return trimmed ? trimmed.split(',') : []\n}\n\n/**\n * Adds the country layers to a datasets array\n * @param {string} apiPath\n * @param {string} [country]\n */\nexport function getMapCountryLayers(apiPath, country) {\n /** @type {any[]} */\n const datasets = []\n\n if (country) {\n // Add the country bounds to the datasets array to show the valid area on the map\n // and provide feedback to the user when they add features outside of the bounds.\n datasets.push(\n {\n id: 'invalid-area',\n label: 'Invalid areas',\n geojson: `${apiPath}/maps/countries.geojson?omit=${country}`,\n showInKey: false,\n showInMenu: false,\n style: {\n stroke: 'gray',\n strokeWidth: 1,\n fill: 'rgba(211,211,211,0.8)'\n }\n },\n {\n id: 'valid-area',\n label: 'Valid areas',\n geojson: `${apiPath}/maps/countries.geojson?only=${country}`,\n showInKey: false,\n showInMenu: false,\n style: {\n stroke: 'rgba(0,112,60,1)',\n strokeWidth: 1\n }\n }\n )\n }\n\n return datasets\n}\n\n/**\n * @typedef {object} InteractiveMap - an instance of a InteractiveMap\n * @property {Function} on - register callback listeners to map events\n * @property {Function} addPanel - adds a new panel to the map\n * @property {Function} addMarker - adds/updates a marker\n * @property {Function} removeMarker - removes a marker\n * @property {Function} addButton - adds/updates a button\n * @property {Function} toggleButtonState - toggle the state of a button\n */\n\n/**\n * @typedef {object} MapLibreMap\n * @property {Function} flyTo - pans/zooms to a new location\n * @property {Function} fitBounds - fits the my to the new bounds\n */\n\n/**\n * @typedef {[number, number]} MapCenter - Map center point as [long, lat]\n */\n\n/**\n * @typedef {object} InteractiveMapInitConfig - additional config that can be provided to InteractiveMap\n * @property {string} zoom - the zoom level of the map\n * @property {MapCenter} center - the center point of the map\n * @property {{ id: string, coords: MapCenter }[]} [markers] - the markers to add to the map\n * @property {any[]} [plugins] - additional plugins\n */\n\n/**\n * @typedef {object} TileData\n * @property {string} VTS_OUTDOOR_URL - the outdoor tile URL\n * @property {string} VTS_DARK_URL - the dark tile URL\n * @property {string} VTS_BLACK_AND_WHITE_URL - the black and white tile URL\n * @property {string} VTS_AERIAL_URL - the aerial tile URL\n */\n\n/**\n * @typedef {object} MapsEnvironmentConfig\n * @property {string} assetPath - the root asset path\n * @property {string} apiPath - the root API path\n * @property {TileData} data - the tile data config\n */\n\n/**\n * @typedef {object} UIManagerOptions\n * @property {string} [geometryTypes] - the CSV list of geometry types that a user can create\n */\n\n/**\n * @import { Feature } from '~/src/server/plugins/engine/types.js'\n */\n\n/**\n * Supported language codes\n * @typedef {('en-GB'|'cy')} LanguageCode\n */\n"],"mappings":"AAAA;AACA,OAAOA,cAAc,MAAM,wBAAwB;AACnD;AACA,OAAOC,oBAAoB,MAAM,yCAAyC;AAC1E;AACA,OAAOC,qBAAqB,MAAM,2CAA2C;AAC7E;AACA,OAAOC,oBAAoB,MAAM,0CAA0C;AAC3E;AACA,OAAOC,kBAAkB,MAAM,uCAAuC;AACtE;AACA,OAAOC,gBAAgB,MAAM,2CAA2C;AACxE,SAASC,QAAQ,QAAQ,gBAAgB;AACzC,OAAOC,SAAS,IAAIC,MAAM,QAAQ,sBAAsB;AAExD,SAASC,iBAAiB;AAC1B,SAASC,eAAe;;AAExB;AACA,MAAMC,WAAW,GAAG,SAAS;AAC7B,MAAMC,YAAY,GAAG,CAAC,QAAQ;AAC9B,MAAMC,mBAAmB,GAAG,GAAG;AAE/B,MAAMC,WAAW,GAAG;EAClBC,eAAe,EAAE,wCAAwC;EACzDC,YAAY,EAAE,qCAAqC;EACnDC,uBAAuB,EAAE,gDAAgD;EACzEC,cAAc,EAAE;AAClB,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,wBAAwBA,CAAC;EAAEC,GAAG;EAAEC;AAAK,CAAC,EAAE;EACtD,MAAMC,KAAK,GAAG,IAAId,MAAM,CAACY,GAAG,EAAEC,IAAI,CAAC;EAEnC,OAAOC,KAAK,CAACC,QAAQ,CAAC,CAAC;AACzB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,wBAAwBA,CAAC;EAAEC,OAAO;EAAEC;AAAS,CAAC,EAAE;EAC9D,MAAMJ,KAAK,GAAG,IAAIf,SAAS,CAACkB,OAAO,EAAEC,QAAQ,CAAC;EAC9C,MAAMC,OAAO,GAAGL,KAAK,CAACM,QAAQ,CAAC,CAAC;EAEhC,OAAO;IAAER,GAAG,EAAEO,OAAO,CAACE,QAAQ;IAAER,IAAI,EAAEM,OAAO,CAACG;EAAU,CAAC;AAC3D;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,kBAAkBA,CAAC;EAAEX,GAAG;EAAEC;AAAK,CAAC,EAAE;EAChD,MAAMC,KAAK,GAAG,IAAId,MAAM,CAACY,GAAG,EAAEC,IAAI,CAAC;EAEnC,OAAOC,KAAK,CAACC,QAAQ,CAAC,CAAC,CAACS,QAAQ,CAAC,CAAC;AACpC;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,kBAAkBA,CAACC,SAAS,EAAE;EAC5C,MAAMZ,KAAK,GAAGf,SAAS,CAAC4B,KAAK,CAACD,SAAS,CAAC;EACxC,MAAMP,OAAO,GAAGL,KAAK,CAACM,QAAQ,CAAC,CAAC;EAEhC,OAAO;IAAER,GAAG,EAAEO,OAAO,CAACE,QAAQ;IAAER,IAAI,EAAEM,OAAO,CAACG;EAAU,CAAC;AAC3D;;AAEA;AACA;AACA;AACA;AACA,OAAO,SAASM,oBAAoBA,CAACC,OAAO,EAAE;EAC5C,IAAIA,OAAO,CAACC,QAAQ,CAACC,IAAI,KAAK,OAAO,EAAE;IACrC,MAAM,CAAClB,IAAI,EAAED,GAAG,CAAC,GAAGiB,OAAO,CAACC,QAAQ,CAACE,WAAW;IAChD,MAAMlB,KAAK,GAAG,IAAId,MAAM,CAACY,GAAG,EAAEC,IAAI,CAAC;IAEnC,OAAOC,KAAK,CAACC,QAAQ,CAAC,CAAC,CAACS,QAAQ,CAAC,CAAC;EACpC,CAAC,MAAM,IAAIK,OAAO,CAACC,QAAQ,CAACC,IAAI,KAAK,YAAY,EAAE;IACjD,MAAM,CAAClB,IAAI,EAAED,GAAG,CAAC,GAAGiB,OAAO,CAACC,QAAQ,CAACE,WAAW,CAAC,CAAC,CAAC;IACnD,MAAMlB,KAAK,GAAG,IAAId,MAAM,CAACY,GAAG,EAAEC,IAAI,CAAC;IAEnC,OAAOC,KAAK,CAACC,QAAQ,CAAC,CAAC,CAACS,QAAQ,CAAC,CAAC;EACpC,CAAC,MAAM;IACL,MAAM,CAACX,IAAI,EAAED,GAAG,CAAC,GAAGiB,OAAO,CAACC,QAAQ,CAACE,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACtD,MAAMlB,KAAK,GAAG,IAAId,MAAM,CAACY,GAAG,EAAEC,IAAI,CAAC;IAEnC,OAAOC,KAAK,CAACC,QAAQ,CAAC,CAAC,CAACS,QAAQ,CAAC,CAAC;EACpC;AACF;;AAEA;AACA;AACA;AACA;AACA,OAAO,SAASS,kBAAkBA,CAACJ,OAAO,EAAE;EAC1C,IAAIA,OAAO,CAACC,QAAQ,CAACC,IAAI,KAAK,OAAO,EAAE;IACrC,MAAM,CAAClB,IAAI,EAAED,GAAG,CAAC,GAAGiB,OAAO,CAACC,QAAQ,CAACE,WAAW;IAChD,MAAMlB,KAAK,GAAG,IAAId,MAAM,CAACY,GAAG,EAAEC,IAAI,CAAC;IAEnC,OAAOC,KAAK,CAACC,QAAQ,CAAC,CAAC,CAACS,QAAQ,CAAC,CAAC;EACpC,CAAC,MAAM;IACL,MAAMU,MAAM,GAAGpC,QAAQ,CAAC+B,OAAO,CAAC;IAChC,MAAM,CAAChB,IAAI,EAAED,GAAG,CAAC,GAAGsB,MAAM,CAACJ,QAAQ,CAACE,WAAW;IAC/C,MAAMlB,KAAK,GAAG,IAAId,MAAM,CAACY,GAAG,EAAEC,IAAI,CAAC;IAEnC,OAAOC,KAAK,CAACC,QAAQ,CAAC,CAAC,CAACS,QAAQ,CAAC,CAAC;EACpC;AACF;;AAEA;AACA,OAAO,MAAMW,aAAa,GAAG;EAC3BC,IAAI,EAAE,GAAG;EACTC,MAAM,EAAE,CAACjC,YAAY,EAAED,WAAW;AACpC,CAAC;AAED,OAAO,MAAMmC,MAAM,GAAG;EACpBC,QAAQ,EAAE,WAAW;EACrBC,oBAAoB,EAAE,uBAAuB;EAC7CC,SAAS,EAAE,YAAY;EACvBC,WAAW,EAAE,cAAc;EAC3BC,UAAU,EAAE,aAAa;EACzBC,aAAa,EAAE;AACjB,CAAC;;AAED;AACA;AACA;AACA;AACA,OAAO,SAASC,iBAAiBA,CAACC,OAAO,EAAE;EACzC;AACF;AACA;AACA;EACE,MAAMC,YAAY,GAAG,SAAAA,CAAUC,CAAC,EAAE;IAChC,IACE,EAAEA,CAAC,CAACC,SAAS,YAAYC,iBAAiB,CAAC,IAC3C,CAACJ,OAAO,CAACK,QAAQ,CAACH,CAAC,CAACC,SAAS,CAAC,EAC9B;MACAD,CAAC,CAACI,cAAc,CAAC,CAAC;IACpB;EACF,CAAC;EAED,OAAOL,YAAY;AACrB;;AAEA;AACA;AACA;AACA;AACA,OAAO,SAASM,QAAQA,CAACC,MAAM,GAAG,CAAC,CAAC,EAAE;EACpC,MAAM;IACJC,SAAS,GAAG,SAAS;IACrBC,OAAO,GAAG,WAAW;IACrBC,IAAI,GAAGnD;EACT,CAAC,GAAGgD,MAAM;EACV,MAAMI,SAAS,GAAGC,QAAQ,CAACC,gBAAgB,CAAC,qBAAqB,CAAC;EAClE,MAAMC,WAAW,GAAGF,QAAQ,CAACC,gBAAgB,CAAC,uBAAuB,CAAC;;EAEtE;EACA;EACA;EACA,IAAIF,SAAS,CAACI,MAAM,EAAE;IACpB,MAAMC,IAAI,GAAGL,SAAS,CAAC,CAAC,CAAC,CAACM,OAAO,CAAC,MAAM,CAAC;IAEzC,IAAID,IAAI,KAAK,IAAI,EAAE;MACjB;IACF;IAEA,MAAMjB,OAAO,GAAGmB,KAAK,CAACC,IAAI,CAACH,IAAI,CAACH,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAC3DG,IAAI,CAACI,gBAAgB,CAAC,QAAQ,EAAEtB,iBAAiB,CAACC,OAAO,CAAC,EAAE,KAAK,CAAC;EACpE;EAEA,IAAIe,WAAW,CAACC,MAAM,EAAE;IACtB,MAAMC,IAAI,GAAGF,WAAW,CAAC,CAAC,CAAC,CAACG,OAAO,CAAC,MAAM,CAAC;IAE3C,IAAID,IAAI,KAAK,IAAI,EAAE;MACjB;IACF;IAEA,MAAMjB,OAAO,GAAGmB,KAAK,CAACC,IAAI,CAACH,IAAI,CAACH,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAC3DG,IAAI,CAACI,gBAAgB,CAAC,QAAQ,EAAEtB,iBAAiB,CAACC,OAAO,CAAC,EAAE,KAAK,CAAC;EACpE;EAEAY,SAAS,CAACU,OAAO,CAAC,CAACC,QAAQ,EAAEC,KAAK,KAAK;IACrCpE,eAAe,CAAC;MAAEqD,SAAS;MAAEC,OAAO;MAAEC;IAAK,CAAC,EAAEY,QAAQ,EAAEC,KAAK,CAAC;EAChE,CAAC,CAAC;EAEFT,WAAW,CAACO,OAAO,CAAC,CAACG,UAAU,EAAED,KAAK,KAAK;IACzCrE,iBAAiB,CAAC;MAAEsD,SAAS;MAAEC,OAAO;MAAEC;IAAK,CAAC,EAAEc,UAAU,EAAED,KAAK,CAAC;EACpE,CAAC,CAAC;AACJ;;AAEA;AACA;AACA;AACA;AACA,OAAO,SAASE,0BAA0BA,CAAChB,OAAO,EAAE;EAClD;AACF;AACA;AACA;AACA;EACE,OAAO,SAASiB,oBAAoBA,CAACC,GAAG,EAAEC,YAAY,EAAE;IACtD,IAAID,GAAG,CAACE,UAAU,CAAC,mBAAmB,CAAC,EAAE;MACvC,IAAID,YAAY,KAAK,MAAM,EAAE;QAC3B,OAAO;UACLD,GAAG,EAAEA,GAAG,CAACG,OAAO,CACd,sCAAsC,EACtC,GAAGC,MAAM,CAACT,QAAQ,CAACU,MAAM,GAAGvB,OAAO,EACrC,CAAC;UACDwB,OAAO,EAAE,CAAC;QACZ,CAAC;MACH;MAEA,IAAIL,YAAY,KAAK,OAAO,EAAE;QAC5B,OAAO;UACLD,GAAG,EAAE,GAAGlB,OAAO,kBAAkByB,kBAAkB,CAACP,GAAG,CAAC,EAAE;UAC1DM,OAAO,EAAE,CAAC;QACZ,CAAC;MACH;IACF;IAEA,MAAME,WAAW,GACf,sFAAsF;;IAExF;IACA,IAAIR,GAAG,CAACE,UAAU,CAACM,WAAW,CAAC,EAAE;MAC/B,MAAMC,IAAI,GAAGT,GAAG,CAACU,SAAS,CAACF,WAAW,CAACpB,MAAM,CAAC;MAC9C,OAAO;QACLY,GAAG,EAAE,GAAGlB,OAAO,YAAY2B,IAAI,EAAE;QACjCH,OAAO,EAAE,CAAC;MACZ,CAAC;IACH;IAEA,OAAO;MAAEN,GAAG;MAAEM,OAAO,EAAE,CAAC;IAAE,CAAC;EAC7B,CAAC;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASK,SAASA,CAACC,KAAK,EAAEC,UAAU,EAAEC,UAAU,EAAE;EACvD,MAAM;IAAEjC,SAAS;IAAEC,OAAO;IAAEC,IAAI,GAAGnD;EAAY,CAAC,GAAGkF,UAAU;EAC7D,MAAMC,WAAW,GAAG,sBAAsB;EAC1C,MAAMC,cAAc,GAAGjG,oBAAoB,CAAC;IAC1CkG,WAAW,EAAE;MAAEC,OAAO,EAAE,SAAS;MAAEC,IAAI,EAAE;IAAU,CAAC;IACpDC,gBAAgB,EAAE,CAAC,aAAa,CAAC;IACjCC,WAAW,EAAE;EACf,CAAC,CAAC;;EAEF;EACA,MAAMC,GAAG,GAAG,IAAIxG,cAAc,CAAC8F,KAAK,EAAE;IACpCW,gBAAgB,EAAE,IAAI;IACtBC,eAAe,EAAE,KAAK;IACtBC,WAAW,EAAEtG,gBAAgB,CAAC,CAAC;IAC/BuG,SAAS,EAAE,QAAQ;IACnBC,OAAO,EAAE,CAAC;IACVC,OAAO,EAAE,EAAE;IACXC,eAAe,EAAE,OAAO;IACxBC,kBAAkB,EAAE,IAAI;IACxBC,gBAAgB,EAAEjC,0BAA0B,CAAChB,OAAO,CAAC;IACrD,GAAG+B,UAAU;IACbmB,OAAO,EAAE,CACPhH,qBAAqB,CAAC;MACpBiH,SAAS,EAAE,CACT;QACEC,EAAE,EAAE,SAAS;QACbC,KAAK,EAAE,SAAS;QAChBnC,GAAG,EAAEjB,IAAI,CAAClD,eAAe;QACzBuG,SAAS,EAAE,GAAGvD,SAAS,sDAAsD;QAC7EwD,IAAI,EAAE,GAAGxD,SAAS,4CAA4C;QAC9DkC,WAAW;QACXuB,WAAW,EAAE,oBAAoBC,MAAM,CAACC,aAAa,CAAC7G,mBAAmB,CAAC,wCAAwC,IAAI8G,IAAI,CAAC,CAAC,CAACC,WAAW,CAAC,CAAC,EAAE;QAC5IC,eAAe,EAAE;MACnB,CAAC,EACD;QACET,EAAE,EAAE,MAAM;QACVC,KAAK,EAAE,MAAM;QACbnC,GAAG,EAAEjB,IAAI,CAACjD,YAAY;QACtB8G,cAAc,EAAE,MAAM;QACtBC,cAAc,EAAE,MAAM;QACtBT,SAAS,EAAE,GAAGvD,SAAS,mDAAmD;QAC1EwD,IAAI,EAAE,GAAGxD,SAAS,kDAAkD;QACpEkC,WAAW;QACXuB,WAAW,EAAE,oBAAoBC,MAAM,CAACC,aAAa,CAAC7G,mBAAmB,CAAC,wCAAwC,IAAI8G,IAAI,CAAC,CAAC,CAACC,WAAW,CAAC,CAAC;MAC5I,CAAC,EACD;QACER,EAAE,EAAE,iBAAiB;QACrBC,KAAK,EAAE,aAAa;QACpBnC,GAAG,EAAEjB,IAAI,CAAChD,uBAAuB;QACjCqG,SAAS,EAAE,GAAGvD,SAAS,8DAA8D;QACrFwD,IAAI,EAAE,GAAGxD,SAAS,kDAAkD;QACpEkC,WAAW;QACXuB,WAAW,EAAE,oBAAoBC,MAAM,CAACC,aAAa,CAAC7G,mBAAmB,CAAC,wCAAwC,IAAI8G,IAAI,CAAC,CAAC,CAACC,WAAW,CAAC,CAAC;MAC5I,CAAC,EACD;QACER,EAAE,EAAE,QAAQ;QACZC,KAAK,EAAE,QAAQ;QACfnC,GAAG,EAAEjB,IAAI,CAAC/C,cAAc;QACxBoG,SAAS,EAAE,GAAGvD,SAAS,qDAAqD;QAC5EwD,IAAI,EAAE,GAAGxD,SAAS,8CAA8C;QAChEkC,WAAW,EAAE,iBAAiB;QAC9BuB,WAAW,EAAE,SAASC,MAAM,CAACC,aAAa,CAAC7G,mBAAmB,CAAC,kFAAkF,IAAI8G,IAAI,CAAC,CAAC,CAACC,WAAW,CAAC,CAAC;MAC3K,CAAC;IAEL,CAAC,CAAC,EACF1B,cAAc,EACd9F,kBAAkB,CAAC;MACjB4H,UAAU,EAAE,GAAGhE,OAAO,8BAA8B;MACpDiE,KAAK,EAAE,OAAO;MACdC,UAAU,EAAE;IACd,CAAC,CAAC,EACF/H,oBAAoB,CAAC;MACnBgI,KAAK,EAAE;IACT,CAAC,CAAC,EACF,IAAIpC,UAAU,CAACmB,OAAO,IAAI,EAAE,CAAC;EAEjC,CAAC,CAAC;EAEF,OAAO;IAAEV,GAAG;IAAEN;EAAe,CAAC;AAChC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASkC,SAASA,CAAC5B,GAAG,EAAEG,WAAW,EAAE9D,MAAM,EAAE;EAClD;EACA2D,GAAG,CAAC6B,SAAS,CAAC,UAAU,EAAExF,MAAM,CAAC;;EAEjC;EACA8D,WAAW,CAAC2B,KAAK,CAAC;IAChBzF,MAAM;IACND,IAAI,EAAE,EAAE;IACR2F,SAAS,EAAE;EACb,CAAC,CAAC;AACJ;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,YAAYA,CAACC,MAAM,EAAE;EACnC,MAAMC,OAAO,GAAGD,MAAM,EAAEE,IAAI,CAAC,CAAC;EAC9B,OAAOD,OAAO,GAAGA,OAAO,CAACE,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE;AAC1C;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,mBAAmBA,CAAC7E,OAAO,EAAE8E,OAAO,EAAE;EACpD;EACA,MAAMC,QAAQ,GAAG,EAAE;EAEnB,IAAID,OAAO,EAAE;IACX;IACA;IACAC,QAAQ,CAACC,IAAI,CACX;MACE5B,EAAE,EAAE,cAAc;MAClBC,KAAK,EAAE,eAAe;MACtB4B,OAAO,EAAE,GAAGjF,OAAO,gCAAgC8E,OAAO,EAAE;MAC5DI,SAAS,EAAE,KAAK;MAChBC,UAAU,EAAE,KAAK;MACjBC,KAAK,EAAE;QACLC,MAAM,EAAE,MAAM;QACdC,WAAW,EAAE,CAAC;QACdC,IAAI,EAAE;MACR;IACF,CAAC,EACD;MACEnC,EAAE,EAAE,YAAY;MAChBC,KAAK,EAAE,aAAa;MACpB4B,OAAO,EAAE,GAAGjF,OAAO,gCAAgC8E,OAAO,EAAE;MAC5DI,SAAS,EAAE,KAAK;MAChBC,UAAU,EAAE,KAAK;MACjBC,KAAK,EAAE;QACLC,MAAM,EAAE,kBAAkB;QAC1BC,WAAW,EAAE;MACf;IACF,CACF,CAAC;EACH;EAEA,OAAOP,QAAQ;AACjB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"map.js","names":["InteractiveMap","createInteractPlugin","createMapStylesPlugin","createScaleBarPlugin","createSearchPlugin","maplibreProvider","centroid","OsGridRef","LatLon","processGeospatial","processLocation","DEFAULT_LAT","DEFAULT_LONG","COMPANY_SYMBOL_CODE","defaultData","VTS_OUTDOOR_URL","VTS_DARK_URL","VTS_BLACK_AND_WHITE_URL","VTS_AERIAL_URL","latLongToEastingNorthing","lat","long","point","toOsGrid","eastingNorthingToLatLong","easting","northing","latLong","toLatLon","latitude","longitude","latLongToOsGridRef","toString","osGridRefToLatLong","osGridRef","parse","getCoordinateGridRef","feature","geometry","type","coordinates","getCentroidGridRef","centre","getDefaultConfig","zoom","center","EVENTS","mapReady","interactMarkerChange","drawReady","drawCreated","drawEdited","drawCancelled","formSubmitFactory","buttons","onFormSubmit","e","submitter","HTMLButtonElement","includes","preventDefault","initMaps","config","assetPath","apiPath","workerPath","data","locations","document","querySelectorAll","geospatials","length","form","closest","Array","from","addEventListener","forEach","location","index","geospatial","makeTileRequestTransformer","transformTileRequest","url","resourceType","startsWith","replace","window","origin","headers","encodeURIComponent","spritesPath","path","substring","createMap","mapId","initConfig","mapsConfig","logoAltText","interactPlugin","markerColor","outdoor","dark","interactionModes","multiSelect","map","enableFullscreen","autoColorScheme","mapProvider","workerUrl","behaviour","minZoom","maxZoom","containerHeight","enableZoomControls","transformRequest","plugins","mapStyles","id","label","thumbnail","logo","attribution","String","fromCodePoint","Date","getFullYear","backgroundColor","mapColorScheme","appColorScheme","osNamesURL","width","showMarker","units","centerMap","addMarker","flyTo","essential","getMapLayers","layers","trimmed","trim","split","getMapCountryLayers","country","datasets","push","geojson","showInKey","showInMenu","style","stroke","strokeWidth","fill"],"sources":["../../../src/client/javascripts/map.js"],"sourcesContent":["// @ts-expect-error - no types\nimport InteractiveMap from '@defra/interactive-map'\n// @ts-expect-error - no types\nimport createInteractPlugin from '@defra/interactive-map/plugins/interact'\n// @ts-expect-error - no types\nimport createMapStylesPlugin from '@defra/interactive-map/plugins/map-styles'\n// @ts-expect-error - no types\nimport createScaleBarPlugin from '@defra/interactive-map/plugins/scale-bar'\n// @ts-expect-error - no types\nimport createSearchPlugin from '@defra/interactive-map/plugins/search'\n// @ts-expect-error - no types\nimport maplibreProvider from '@defra/interactive-map/providers/maplibre'\nimport { centroid } from '@turf/centroid'\nimport OsGridRef, { LatLon } from 'geodesy/osgridref.js'\n\nimport { processGeospatial } from '~/src/client/javascripts/geospatial-map.js'\nimport { processLocation } from '~/src/client/javascripts/location-map.js'\n\n// Center of UK\nconst DEFAULT_LAT = 53.825564\nconst DEFAULT_LONG = -2.421975\nconst COMPANY_SYMBOL_CODE = 169\n\nconst defaultData = {\n VTS_OUTDOOR_URL: '/api/maps/vts/OS_VTS_3857_Outdoor.json',\n VTS_DARK_URL: '/api/maps/vts/OS_VTS_3857_Dark.json',\n VTS_BLACK_AND_WHITE_URL: '/api/maps/vts/OS_VTS_3857_Black_and_White.json',\n VTS_AERIAL_URL: '/api/maps/vts/esri-aerial.json'\n}\n\n/**\n * Converts lat long to easting and northing\n * @param {object} param\n * @param {number} param.lat\n * @param {number} param.long\n * @returns {{ easting: number, northing: number }}\n */\nexport function latLongToEastingNorthing({ lat, long }) {\n const point = new LatLon(lat, long)\n\n return point.toOsGrid()\n}\n\n/**\n * Converts easting and northing to lat long\n * @param {object} param\n * @param {number} param.easting\n * @param {number} param.northing\n * @returns {{ lat: number, long: number }}\n */\nexport function eastingNorthingToLatLong({ easting, northing }) {\n const point = new OsGridRef(easting, northing)\n const latLong = point.toLatLon()\n\n return { lat: latLong.latitude, long: latLong.longitude }\n}\n\n/**\n * Converts lat long to an ordnance survey grid reference\n * @param {object} param\n * @param {number} param.lat\n * @param {number} param.long\n * @returns {string}\n */\nexport function latLongToOsGridRef({ lat, long }) {\n const point = new LatLon(lat, long)\n\n return point.toOsGrid().toString()\n}\n\n/**\n * Converts an ordnance survey grid reference to lat long\n * @param {string} osGridRef\n * @returns {{ lat: number, long: number }}\n */\nexport function osGridRefToLatLong(osGridRef) {\n const point = OsGridRef.parse(osGridRef)\n const latLong = point.toLatLon()\n\n return { lat: latLong.latitude, long: latLong.longitude }\n}\n\n/**\n * Get the grid ref from the first coordinate of a long/lat feature\n * @param {Feature} feature\n */\nexport function getCoordinateGridRef(feature) {\n if (feature.geometry.type === 'Point') {\n const [long, lat] = feature.geometry.coordinates\n const point = new LatLon(lat, long)\n\n return point.toOsGrid().toString()\n } else if (feature.geometry.type === 'LineString') {\n const [long, lat] = feature.geometry.coordinates[0]\n const point = new LatLon(lat, long)\n\n return point.toOsGrid().toString()\n } else {\n const [long, lat] = feature.geometry.coordinates[0][0]\n const point = new LatLon(lat, long)\n\n return point.toOsGrid().toString()\n }\n}\n\n/**\n * Get the centroid grid ref from a long/lat feature\n * @param {Feature} feature\n */\nexport function getCentroidGridRef(feature) {\n if (feature.geometry.type === 'Point') {\n const [long, lat] = feature.geometry.coordinates\n const point = new LatLon(lat, long)\n\n return point.toOsGrid().toString()\n } else {\n const centre = centroid(feature)\n const [long, lat] = centre.geometry.coordinates\n const point = new LatLon(lat, long)\n\n return point.toOsGrid().toString()\n }\n}\n\n/**\n * Get the default config for a map\n * @returns {InteractiveMapInitConfig}\n */\nexport const getDefaultConfig = () => {\n return {\n zoom: '6',\n center: [DEFAULT_LONG, DEFAULT_LAT]\n }\n}\n\nexport const EVENTS = {\n mapReady: 'map:ready',\n interactMarkerChange: 'interact:markerchange',\n drawReady: 'draw:ready',\n drawCreated: 'draw:created',\n drawEdited: 'draw:edited',\n drawCancelled: 'draw:cancelled'\n}\n\n/**\n * Make a form submit handler that only allows submissions from allowed buttons\n * @param {HTMLButtonElement[]} buttons - the form buttons to allow submissions\n */\nexport function formSubmitFactory(buttons) {\n /**\n * The submit handler\n * @param {SubmitEvent} e\n */\n const onFormSubmit = function (e) {\n if (\n !(e.submitter instanceof HTMLButtonElement) ||\n !buttons.includes(e.submitter)\n ) {\n e.preventDefault()\n }\n }\n\n return onFormSubmit\n}\n\n/**\n * Initialise location maps\n * @param {Partial<MapsEnvironmentConfig>} config - the map configuration\n */\nexport function initMaps(config = {}) {\n const {\n assetPath = '/assets',\n apiPath = '/form/api',\n workerPath = '/assets/interactive-map/maplibre-gl-worker.mjs',\n data = defaultData\n } = config\n const locations = document.querySelectorAll('.app-location-field')\n const geospatials = document.querySelectorAll('.app-geospatial-field')\n\n // TODO: Fix this in `interactive-map`\n // If there are location components on the page fix up the main form submit\n // handler so it doesn't fire when using the integrated map search feature\n if (locations.length) {\n const form = locations[0].closest('form')\n\n if (form === null) {\n return\n }\n\n const buttons = Array.from(form.querySelectorAll('button'))\n form.addEventListener('submit', formSubmitFactory(buttons), false)\n }\n\n if (geospatials.length) {\n const form = geospatials[0].closest('form')\n\n if (form === null) {\n return\n }\n\n const buttons = Array.from(form.querySelectorAll('button'))\n form.addEventListener('submit', formSubmitFactory(buttons), false)\n }\n\n locations.forEach((location, index) => {\n processLocation({ assetPath, apiPath, workerPath, data }, location, index)\n })\n\n geospatials.forEach((geospatial, index) => {\n processGeospatial(\n { assetPath, apiPath, workerPath, data },\n geospatial,\n index\n )\n })\n}\n\n/**\n * OS API request proxy factory\n * @param {string} apiPath - the root API path\n */\nexport function makeTileRequestTransformer(apiPath) {\n /**\n * Proxy OS API requests via our server\n * @param {string} url - the request URL\n * @param {string} resourceType - the resource type\n */\n return function transformTileRequest(url, resourceType) {\n if (url.startsWith('https://api.os.uk')) {\n if (resourceType === 'Tile') {\n return {\n url: url.replace(\n 'https://api.os.uk/maps/vector/v1/vts',\n `${window.location.origin}${apiPath}`\n ),\n headers: {}\n }\n }\n\n if (resourceType !== 'Style') {\n return {\n url: `${apiPath}/map-proxy?url=${encodeURIComponent(url)}`,\n headers: {}\n }\n }\n }\n\n const spritesPath =\n 'https://raw.githubusercontent.com/OrdnanceSurvey/OS-Vector-Tile-API-Stylesheets/main'\n\n // Proxy sprite requests\n if (url.startsWith(spritesPath)) {\n const path = url.substring(spritesPath.length)\n return {\n url: `${apiPath}/maps/vts${path}`,\n headers: {}\n }\n }\n\n return { url, headers: {} }\n }\n}\n\n/**\n * Create a Defra map instance\n * @param {string} mapId - the map id\n * @param {InteractiveMapInitConfig} initConfig - the map initial configuration\n * @param {MapsEnvironmentConfig} mapsConfig - the map environment params\n */\nexport function createMap(mapId, initConfig, mapsConfig) {\n const { assetPath, apiPath, workerPath, data = defaultData } = mapsConfig\n const logoAltText = 'Ordnance survey logo'\n const interactPlugin = createInteractPlugin({\n markerColor: { outdoor: '#ff0000', dark: '#00ff00' },\n interactionModes: ['placeMarker'],\n multiSelect: false\n })\n\n /** @type {InteractiveMap} */\n const map = new InteractiveMap(mapId, {\n enableFullscreen: true,\n autoColorScheme: false,\n mapProvider: maplibreProvider({ workerUrl: workerPath }),\n behaviour: 'inline',\n minZoom: 6,\n maxZoom: 18,\n containerHeight: '400px',\n enableZoomControls: true,\n transformRequest: makeTileRequestTransformer(apiPath),\n ...initConfig,\n plugins: [\n createMapStylesPlugin({\n mapStyles: [\n {\n id: 'outdoor',\n label: 'Outdoor',\n url: data.VTS_OUTDOOR_URL,\n thumbnail: `${assetPath}/interactive-map/assets/images/outdoor-map-thumb.jpg`,\n logo: `${assetPath}/interactive-map/assets/images/os-logo.svg`,\n logoAltText,\n attribution: `Contains OS data ${String.fromCodePoint(COMPANY_SYMBOL_CODE)} Crown copyright and database rights ${new Date().getFullYear()}`,\n backgroundColor: '#f5f5f0'\n },\n {\n id: 'dark',\n label: 'Dark',\n url: data.VTS_DARK_URL,\n mapColorScheme: 'dark',\n appColorScheme: 'dark',\n thumbnail: `${assetPath}/interactive-map/assets/images/dark-map-thumb.jpg`,\n logo: `${assetPath}/interactive-map/assets/images/os-logo-white.svg`,\n logoAltText,\n attribution: `Contains OS data ${String.fromCodePoint(COMPANY_SYMBOL_CODE)} Crown copyright and database rights ${new Date().getFullYear()}`\n },\n {\n id: 'black-and-white',\n label: 'Black/White',\n url: data.VTS_BLACK_AND_WHITE_URL,\n thumbnail: `${assetPath}/interactive-map/assets/images/black-and-white-map-thumb.jpg`,\n logo: `${assetPath}/interactive-map/assets/images/os-logo-black.svg`,\n logoAltText,\n attribution: `Contains OS data ${String.fromCodePoint(COMPANY_SYMBOL_CODE)} Crown copyright and database rights ${new Date().getFullYear()}`\n },\n {\n id: 'aerial',\n label: 'Aerial',\n url: data.VTS_AERIAL_URL,\n thumbnail: `${assetPath}/interactive-map/assets/images/aerial-map-thumb.jpg`,\n logo: `${assetPath}/interactive-map/assets/images/esri-logo.png`,\n logoAltText: 'Powered by Esri',\n attribution: `Tiles ${String.fromCodePoint(COMPANY_SYMBOL_CODE)} Esri — Source: Esri, Maxar, Earthstar Geographics, and the GIS User Community ${new Date().getFullYear()}`\n }\n ]\n }),\n interactPlugin,\n createSearchPlugin({\n osNamesURL: `${apiPath}/geocode-proxy?query={query}`,\n width: '300px',\n showMarker: false\n }),\n createScaleBarPlugin({\n units: 'metric'\n }),\n ...(initConfig.plugins ?? [])\n ]\n })\n\n return { map, interactPlugin }\n}\n\n/**\n * Updates the marker position and moves the map view port the new location\n * @param {InteractiveMap} map - the map component instance (of InteractiveMap)\n * @param {MapLibreMap} mapProvider - the map provider instance (of MapLibreMap)\n * @param {MapCenter} center - the point\n */\nexport function centerMap(map, mapProvider, center) {\n // Move the 'location' marker to the new point\n map.addMarker('location', center)\n\n // Pan & zoom the map to the new valid location\n mapProvider.flyTo({\n center,\n zoom: 14,\n essential: true\n })\n}\n\n/**\n * Parse CSV string layers\n * @param {string | undefined} layers\n * @returns {string[]}\n */\nexport function getMapLayers(layers) {\n const trimmed = layers?.trim()\n return trimmed ? trimmed.split(',') : []\n}\n\n/**\n * Adds the country layers to a datasets array\n * @param {string} apiPath\n * @param {string} [country]\n */\nexport function getMapCountryLayers(apiPath, country) {\n /** @type {any[]} */\n const datasets = []\n\n if (country) {\n // Add the country bounds to the datasets array to show the valid area on the map\n // and provide feedback to the user when they add features outside of the bounds.\n datasets.push(\n {\n id: 'invalid-area',\n label: 'Invalid areas',\n geojson: `${apiPath}/maps/countries.geojson?omit=${country}`,\n showInKey: false,\n showInMenu: false,\n style: {\n stroke: 'gray',\n strokeWidth: 1,\n fill: 'rgba(211,211,211,0.8)'\n }\n },\n {\n id: 'valid-area',\n label: 'Valid areas',\n geojson: `${apiPath}/maps/countries.geojson?only=${country}`,\n showInKey: false,\n showInMenu: false,\n style: {\n stroke: 'rgba(0,112,60,1)',\n strokeWidth: 1\n }\n }\n )\n }\n\n return datasets\n}\n\n/**\n * @typedef {object} InteractiveMap - an instance of a InteractiveMap\n * @property {Function} on - register callback listeners to map events\n * @property {Function} addPanel - adds a new panel to the map\n * @property {Function} addMarker - adds/updates a marker\n * @property {Function} removeMarker - removes a marker\n * @property {Function} addButton - adds/updates a button\n * @property {Function} toggleButtonState - toggle the state of a button\n */\n\n/**\n * @typedef {object} MapLibreMap\n * @property {Function} flyTo - pans/zooms to a new location\n * @property {Function} fitBounds - fits the my to the new bounds\n */\n\n/**\n * @typedef {[number, number]} MapCenter - Map center point as [long, lat]\n */\n\n/**\n * @typedef {object} InteractiveMapInitConfig - additional config that can be provided to InteractiveMap\n * @property {string} zoom - the zoom level of the map\n * @property {MapCenter} center - the center point of the map\n * @property {{ id: string, coords: MapCenter }[]} [markers] - the markers to add to the map\n * @property {any[]} [plugins] - additional plugins\n */\n\n/**\n * @typedef {object} TileData\n * @property {string} VTS_OUTDOOR_URL - the outdoor tile URL\n * @property {string} VTS_DARK_URL - the dark tile URL\n * @property {string} VTS_BLACK_AND_WHITE_URL - the black and white tile URL\n * @property {string} VTS_AERIAL_URL - the aerial tile URL\n */\n\n/**\n * @typedef {object} MapsEnvironmentConfig\n * @property {string} assetPath - the root asset path\n * @property {string} apiPath - the root API path\n * @property {string} workerPath - the maplibre worker path\n * @property {TileData} data - the tile data config\n */\n\n/**\n * @typedef {object} UIManagerOptions\n * @property {string} [geometryTypes] - the CSV list of geometry types that a user can create\n */\n\n/**\n * @import { Feature } from '~/src/server/plugins/engine/types.js'\n */\n\n/**\n * Supported language codes\n * @typedef {('en-GB'|'cy')} LanguageCode\n */\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { type AutocompleteFieldComponent } from '@defra/forms-model';
|
|
2
|
-
import { type LanguageMessages } from 'joi';
|
|
3
2
|
import { SelectField } from '../../../../server/plugins/engine/components/SelectField.js';
|
|
4
3
|
import { type RenderContext } from '../../../../server/plugins/engine/components/types.js';
|
|
5
4
|
import { type Translator } from '../../../../server/plugins/engine/types/index.js';
|
|
@@ -57,6 +56,6 @@ export declare class AutocompleteField extends SelectField {
|
|
|
57
56
|
};
|
|
58
57
|
};
|
|
59
58
|
getValidationMessagesOverride(translator: Translator): {
|
|
60
|
-
[x: string]: LanguageMessages;
|
|
59
|
+
[x: string]: import("joi").LanguageMessages;
|
|
61
60
|
};
|
|
62
61
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { SelectField } from "./SelectField.js";
|
|
2
|
+
import { withCustomValidationOverrides } from "./helpers/index.js";
|
|
2
3
|
import { buildValidationMessages } from "../i18n/buildValidationMessages.js";
|
|
3
4
|
import { messageTemplate } from "../pageControllers/validationOptions.js";
|
|
4
5
|
export class AutocompleteField extends SelectField {
|
|
@@ -35,14 +36,18 @@ export class AutocompleteField extends SelectField {
|
|
|
35
36
|
};
|
|
36
37
|
}
|
|
37
38
|
getValidationMessagesOverride(translator) {
|
|
39
|
+
const {
|
|
40
|
+
customValidationMessages
|
|
41
|
+
} = this.options;
|
|
38
42
|
const {
|
|
39
43
|
t
|
|
40
44
|
} = translator;
|
|
45
|
+
const defaults = {
|
|
46
|
+
'any.required': buildValidationMessages(t).objectRequired,
|
|
47
|
+
'any.only': buildValidationMessages(t).objectRequired
|
|
48
|
+
};
|
|
41
49
|
return {
|
|
42
|
-
[this.name]:
|
|
43
|
-
'any.required': buildValidationMessages(t).objectRequired,
|
|
44
|
-
'any.only': buildValidationMessages(t).objectRequired
|
|
45
|
-
}
|
|
50
|
+
[this.name]: withCustomValidationOverrides(defaults, undefined, customValidationMessages)
|
|
46
51
|
};
|
|
47
52
|
}
|
|
48
53
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AutocompleteField.js","names":["SelectField","buildValidationMessages","messageTemplate","AutocompleteField","constructor","def","props","options","formSchema","required","messages","customValidationMessages","getViewModel","context","viewModel","formGroup","attributes","getValidationMessagesOverride","translator","t","
|
|
1
|
+
{"version":3,"file":"AutocompleteField.js","names":["SelectField","withCustomValidationOverrides","buildValidationMessages","messageTemplate","AutocompleteField","constructor","def","props","options","formSchema","required","messages","customValidationMessages","getViewModel","context","viewModel","formGroup","attributes","getValidationMessagesOverride","translator","t","defaults","objectRequired","name","undefined"],"sources":["../../../../../src/server/plugins/engine/components/AutocompleteField.ts"],"sourcesContent":["import { type AutocompleteFieldComponent } from '@defra/forms-model'\n\nimport { SelectField } from '~/src/server/plugins/engine/components/SelectField.js'\nimport { withCustomValidationOverrides } from '~/src/server/plugins/engine/components/helpers/index.js'\nimport { type RenderContext } from '~/src/server/plugins/engine/components/types.js'\nimport { buildValidationMessages } from '~/src/server/plugins/engine/i18n/buildValidationMessages.js'\nimport { messageTemplate } from '~/src/server/plugins/engine/pageControllers/validationOptions.js'\nimport { type Translator } from '~/src/server/plugins/engine/types/index.js'\n\nexport class AutocompleteField extends SelectField {\n declare options: AutocompleteFieldComponent['options']\n\n constructor(\n def: AutocompleteFieldComponent,\n props: ConstructorParameters<typeof SelectField>[1]\n ) {\n super(def, props)\n\n const { options } = def\n let { formSchema } = this\n\n if (options.required !== false) {\n const messages = options.customValidationMessages\n\n formSchema = formSchema.messages({\n 'any.only':\n messages?.['any.only'] ?? (messageTemplate.required as string),\n 'any.required':\n messages?.['any.required'] ?? (messageTemplate.required as string)\n })\n }\n\n this.options = options\n this.formSchema = formSchema\n }\n\n getViewModel(context: RenderContext) {\n const viewModel = super.getViewModel(context)\n let { formGroup } = viewModel\n\n formGroup ??= {}\n formGroup.attributes = {\n 'data-module': 'govuk-accessible-autocomplete'\n }\n\n return {\n ...viewModel,\n formGroup\n }\n }\n\n getValidationMessagesOverride(translator: Translator) {\n const { customValidationMessages } = this.options\n const { t } = translator\n const defaults = {\n 'any.required': buildValidationMessages(t).objectRequired,\n 'any.only': buildValidationMessages(t).objectRequired\n }\n\n return {\n [this.name]: withCustomValidationOverrides(\n defaults,\n undefined,\n customValidationMessages\n )\n }\n }\n}\n"],"mappings":"AAEA,SAASA,WAAW;AACpB,SAASC,6BAA6B;AAEtC,SAASC,uBAAuB;AAChC,SAASC,eAAe;AAGxB,OAAO,MAAMC,iBAAiB,SAASJ,WAAW,CAAC;EAGjDK,WAAWA,CACTC,GAA+B,EAC/BC,KAAmD,EACnD;IACA,KAAK,CAACD,GAAG,EAAEC,KAAK,CAAC;IAEjB,MAAM;MAAEC;IAAQ,CAAC,GAAGF,GAAG;IACvB,IAAI;MAAEG;IAAW,CAAC,GAAG,IAAI;IAEzB,IAAID,OAAO,CAACE,QAAQ,KAAK,KAAK,EAAE;MAC9B,MAAMC,QAAQ,GAAGH,OAAO,CAACI,wBAAwB;MAEjDH,UAAU,GAAGA,UAAU,CAACE,QAAQ,CAAC;QAC/B,UAAU,EACRA,QAAQ,GAAG,UAAU,CAAC,IAAKR,eAAe,CAACO,QAAmB;QAChE,cAAc,EACZC,QAAQ,GAAG,cAAc,CAAC,IAAKR,eAAe,CAACO;MACnD,CAAC,CAAC;IACJ;IAEA,IAAI,CAACF,OAAO,GAAGA,OAAO;IACtB,IAAI,CAACC,UAAU,GAAGA,UAAU;EAC9B;EAEAI,YAAYA,CAACC,OAAsB,EAAE;IACnC,MAAMC,SAAS,GAAG,KAAK,CAACF,YAAY,CAACC,OAAO,CAAC;IAC7C,IAAI;MAAEE;IAAU,CAAC,GAAGD,SAAS;IAE7BC,SAAS,KAAK,CAAC,CAAC;IAChBA,SAAS,CAACC,UAAU,GAAG;MACrB,aAAa,EAAE;IACjB,CAAC;IAED,OAAO;MACL,GAAGF,SAAS;MACZC;IACF,CAAC;EACH;EAEAE,6BAA6BA,CAACC,UAAsB,EAAE;IACpD,MAAM;MAAEP;IAAyB,CAAC,GAAG,IAAI,CAACJ,OAAO;IACjD,MAAM;MAAEY;IAAE,CAAC,GAAGD,UAAU;IACxB,MAAME,QAAQ,GAAG;MACf,cAAc,EAAEnB,uBAAuB,CAACkB,CAAC,CAAC,CAACE,cAAc;MACzD,UAAU,EAAEpB,uBAAuB,CAACkB,CAAC,CAAC,CAACE;IACzC,CAAC;IAED,OAAO;MACL,CAAC,IAAI,CAACC,IAAI,GAAGtB,6BAA6B,CACxCoB,QAAQ,EACRG,SAAS,EACTZ,wBACF;IACF,CAAC;EACH;AACF","ignoreList":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import joi from 'joi';
|
|
2
2
|
import { FormComponent, isFormValue } from "./FormComponent.js";
|
|
3
|
-
import { addClassOptionIfNone } from "./helpers/index.js";
|
|
3
|
+
import { addClassOptionIfNone, withCustomValidationOverrides } from "./helpers/index.js";
|
|
4
4
|
import { buildValidationMessages } from "../i18n/buildValidationMessages.js";
|
|
5
5
|
import { messageTemplate } from "../pageControllers/validationOptions.js";
|
|
6
6
|
/**
|
|
@@ -71,16 +71,21 @@ export class LocationFieldBase extends FormComponent {
|
|
|
71
71
|
return viewModel;
|
|
72
72
|
}
|
|
73
73
|
getValidationMessagesOverride(translator) {
|
|
74
|
+
const {
|
|
75
|
+
customValidationMessage,
|
|
76
|
+
customValidationMessages
|
|
77
|
+
} = this.options;
|
|
74
78
|
const {
|
|
75
79
|
t
|
|
76
80
|
} = translator;
|
|
77
81
|
const config = this.getValidationConfig(translator);
|
|
82
|
+
const defaults = {
|
|
83
|
+
'any.required': config.requiredMessage ?? buildValidationMessages(t).objectRequired,
|
|
84
|
+
'string.empty': config.requiredMessage ?? buildValidationMessages(t).objectRequired,
|
|
85
|
+
'string.pattern.base': config.patternErrorMessage
|
|
86
|
+
};
|
|
78
87
|
return {
|
|
79
|
-
[this.name]:
|
|
80
|
-
'any.required': config.requiredMessage ?? buildValidationMessages(t).objectRequired,
|
|
81
|
-
'string.empty': config.requiredMessage ?? buildValidationMessages(t).objectRequired,
|
|
82
|
-
'string.pattern.base': config.patternErrorMessage
|
|
83
|
-
}
|
|
88
|
+
[this.name]: withCustomValidationOverrides(defaults, customValidationMessage, customValidationMessages)
|
|
84
89
|
};
|
|
85
90
|
}
|
|
86
91
|
getAllPossibleErrors() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LocationFieldBase.js","names":["joi","FormComponent","isFormValue","addClassOptionIfNone","buildValidationMessages","messageTemplate","LocationFieldBase","instructionText","constructor","def","props","options","locationOptions","config","getValidationConfig","undefined","requiredMessage","required","messages","patternErrorMessage","formSchema","string","trim","label","pattern","allow","customValidationMessage","message","messageKeys","reduce","acc","key","customValidationMessages","default","stateSchema","getFormValueFromState","state","name","getFormValue","value","isValue","isText","getViewModel","context","viewModel","Object","assign","lang","translator","language","tComponent","getValidationMessagesOverride","t","objectRequired","getAllPossibleErrors","baseErrors","type","template","getErrorTemplates","advancedSettingsErrors"],"sources":["../../../../../src/server/plugins/engine/components/LocationFieldBase.ts"],"sourcesContent":["import { type FormComponentsDef } from '@defra/forms-model'\nimport joi, {\n type JoiExpression,\n type LanguageMessages,\n type StringSchema\n} from 'joi'\n\nimport {\n FormComponent,\n isFormValue\n} from '~/src/server/plugins/engine/components/FormComponent.js'\nimport {
|
|
1
|
+
{"version":3,"file":"LocationFieldBase.js","names":["joi","FormComponent","isFormValue","addClassOptionIfNone","withCustomValidationOverrides","buildValidationMessages","messageTemplate","LocationFieldBase","instructionText","constructor","def","props","options","locationOptions","config","getValidationConfig","undefined","requiredMessage","required","messages","patternErrorMessage","formSchema","string","trim","label","pattern","allow","customValidationMessage","message","messageKeys","reduce","acc","key","customValidationMessages","default","stateSchema","getFormValueFromState","state","name","getFormValue","value","isValue","isText","getViewModel","context","viewModel","Object","assign","lang","translator","language","tComponent","getValidationMessagesOverride","t","defaults","objectRequired","getAllPossibleErrors","baseErrors","type","template","getErrorTemplates","advancedSettingsErrors"],"sources":["../../../../../src/server/plugins/engine/components/LocationFieldBase.ts"],"sourcesContent":["import { type FormComponentsDef } from '@defra/forms-model'\nimport joi, {\n type JoiExpression,\n type LanguageMessages,\n type StringSchema\n} from 'joi'\n\nimport {\n FormComponent,\n isFormValue\n} from '~/src/server/plugins/engine/components/FormComponent.js'\nimport {\n addClassOptionIfNone,\n withCustomValidationOverrides\n} from '~/src/server/plugins/engine/components/helpers/index.js'\nimport { type RenderContext } from '~/src/server/plugins/engine/components/types.js'\nimport { buildValidationMessages } from '~/src/server/plugins/engine/i18n/buildValidationMessages.js'\nimport { messageTemplate } from '~/src/server/plugins/engine/pageControllers/validationOptions.js'\nimport { type Translator } from '~/src/server/plugins/engine/types/index.js'\nimport {\n type ErrorMessageTemplateList,\n type FormState,\n type FormStateValue,\n type FormSubmissionState\n} from '~/src/server/plugins/engine/types.js'\n\ninterface LocationFieldOptions {\n instructionText?: string\n required?: boolean\n customValidationMessage?: string\n customValidationMessages?: LanguageMessages\n classes?: string\n}\n\ninterface ValidationConfig {\n pattern: RegExp\n patternErrorMessage: JoiExpression\n requiredMessage?: JoiExpression\n}\n\n/**\n * Abstract base class for location-based field components\n */\nexport abstract class LocationFieldBase extends FormComponent {\n declare options: LocationFieldOptions\n declare formSchema: StringSchema\n declare stateSchema: StringSchema\n instructionText?: string\n\n protected abstract getValidationConfig(\n translator: Translator | undefined\n ): ValidationConfig\n protected abstract getErrorTemplates(): {\n type: string\n template: JoiExpression\n }[]\n\n constructor(\n def: FormComponentsDef,\n props: ConstructorParameters<typeof FormComponent>[1]\n ) {\n super(def, props)\n\n const { options } = def\n const locationOptions = options as LocationFieldOptions\n this.instructionText = locationOptions.instructionText\n\n addClassOptionIfNone(locationOptions, 'govuk-input--width-10')\n\n const config = this.getValidationConfig(undefined)\n const requiredMessage = config.requiredMessage ?? messageTemplate.required\n\n const messages = {\n 'any.required': requiredMessage,\n 'string.empty': requiredMessage,\n 'string.pattern.base': config.patternErrorMessage\n } as LanguageMessages\n\n let formSchema = joi\n .string()\n .trim()\n .label(this.label)\n .required()\n .pattern(config.pattern)\n .messages(messages)\n\n if (locationOptions.required === false) {\n formSchema = formSchema.allow('')\n }\n\n if (locationOptions.customValidationMessage) {\n const message = locationOptions.customValidationMessage\n const messageKeys = [\n 'any.required',\n 'string.empty',\n 'string.pattern.base'\n ]\n\n const messages = messageKeys.reduce<LanguageMessages>((acc, key) => {\n acc[key] = message\n return acc\n }, {})\n\n formSchema = formSchema.messages(messages)\n } else if (locationOptions.customValidationMessages) {\n formSchema = formSchema.messages(locationOptions.customValidationMessages)\n }\n\n this.formSchema = formSchema.default('')\n this.stateSchema = formSchema.default(null).allow(null)\n this.options = locationOptions\n }\n\n getFormValueFromState(state: FormSubmissionState) {\n const { name } = this\n return this.getFormValue(state[name])\n }\n\n getFormValue(value?: FormStateValue | FormState) {\n return this.isValue(value) ? value : undefined\n }\n\n isValue(value?: FormStateValue | FormState): value is string {\n return LocationFieldBase.isText(value)\n }\n\n getViewModel(context: RenderContext) {\n const viewModel = super.getViewModel(context)\n\n Object.assign(viewModel, {\n lang: context.translator.language\n })\n\n if (this.instructionText) {\n const { tComponent } = context.translator\n return {\n ...viewModel,\n instructionText:\n tComponent(this.def, 'instructionText') || this.instructionText\n }\n }\n\n return viewModel\n }\n\n getValidationMessagesOverride(translator: Translator) {\n const { customValidationMessage, customValidationMessages } = this.options\n const { t } = translator\n const config = this.getValidationConfig(translator)\n const defaults = {\n 'any.required':\n config.requiredMessage ?? buildValidationMessages(t).objectRequired,\n 'string.empty':\n config.requiredMessage ?? buildValidationMessages(t).objectRequired,\n 'string.pattern.base': config.patternErrorMessage\n }\n\n return {\n [this.name]: withCustomValidationOverrides(\n defaults,\n customValidationMessage,\n customValidationMessages\n )\n }\n }\n\n getAllPossibleErrors(): ErrorMessageTemplateList {\n const config = this.getValidationConfig(undefined)\n\n return {\n baseErrors: [\n {\n type: 'required',\n template: config.requiredMessage ?? messageTemplate.required\n },\n ...this.getErrorTemplates()\n ],\n advancedSettingsErrors: []\n }\n }\n\n static isText(value?: FormStateValue | FormState): value is string {\n return isFormValue(value) && typeof value === 'string'\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import joi from 'joi';
|
|
2
2
|
import { FormComponent, isFormValue } from "./FormComponent.js";
|
|
3
|
+
import { withCustomValidationOverrides } from "./helpers/index.js";
|
|
3
4
|
import { buildValidationMessages } from "../i18n/buildValidationMessages.js";
|
|
4
5
|
import { messageTemplate } from "../pageControllers/validationOptions.js";
|
|
5
6
|
export class NumberField extends FormComponent {
|
|
@@ -99,18 +100,23 @@ export class NumberField extends FormComponent {
|
|
|
99
100
|
return NumberField.isNumber(value);
|
|
100
101
|
}
|
|
101
102
|
getValidationMessagesOverride(translator) {
|
|
103
|
+
const {
|
|
104
|
+
customValidationMessage,
|
|
105
|
+
customValidationMessages
|
|
106
|
+
} = this.options;
|
|
102
107
|
const {
|
|
103
108
|
t
|
|
104
109
|
} = translator;
|
|
110
|
+
const defaults = {
|
|
111
|
+
'any.required': buildValidationMessages(t).objectRequired,
|
|
112
|
+
'number.base': buildValidationMessages(t).objectMissing,
|
|
113
|
+
'number.precision': buildValidationMessages(t).numberPrecision,
|
|
114
|
+
'number.integer': buildValidationMessages(t).numberInteger,
|
|
115
|
+
'number.min': buildValidationMessages(t).numberMin,
|
|
116
|
+
'number.max': buildValidationMessages(t).numberMax
|
|
117
|
+
};
|
|
105
118
|
return {
|
|
106
|
-
[this.name]:
|
|
107
|
-
'any.required': buildValidationMessages(t).objectRequired,
|
|
108
|
-
'number.base': buildValidationMessages(t).objectMissing,
|
|
109
|
-
'number.precision': buildValidationMessages(t).numberPrecision,
|
|
110
|
-
'number.integer': buildValidationMessages(t).numberInteger,
|
|
111
|
-
'number.min': buildValidationMessages(t).numberMin,
|
|
112
|
-
'number.max': buildValidationMessages(t).numberMax
|
|
113
|
-
}
|
|
119
|
+
[this.name]: withCustomValidationOverrides(defaults, customValidationMessage, customValidationMessages)
|
|
114
120
|
};
|
|
115
121
|
}
|
|
116
122
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NumberField.js","names":["joi","FormComponent","isFormValue","buildValidationMessages","messageTemplate","NumberField","constructor","def","props","options","schema","formSchema","number","custom","getValidatorPrecision","label","required","allow","messages","customValidationMessages","empty","min","max","precision","integer","customValidationMessage","message","default","stateSchema","getFormValueFromState","state","name","getFormValue","value","isValue","undefined","getViewModel","context","viewModel","attributes","prefix","suffix","inputmode","text","isNumber","getValidationMessagesOverride","translator","t","objectRequired","objectMissing","numberPrecision","numberInteger","numberMin","numberMax","getAllPossibleErrors","baseErrors","type","template","advancedSettingsErrors","component","validator","helpers","limit","validationSchema","prefs","convert","attempt","error"],"sources":["../../../../../src/server/plugins/engine/components/NumberField.ts"],"sourcesContent":["import { type NumberFieldComponent } from '@defra/forms-model'\nimport joi, {\n type CustomValidator,\n type LanguageMessages,\n type NumberSchema\n} from 'joi'\n\nimport {\n FormComponent,\n isFormValue\n} from '~/src/server/plugins/engine/components/FormComponent.js'\nimport { type RenderContext } from '~/src/server/plugins/engine/components/types.js'\nimport { buildValidationMessages } from '~/src/server/plugins/engine/i18n/buildValidationMessages.js'\nimport { messageTemplate } from '~/src/server/plugins/engine/pageControllers/validationOptions.js'\nimport { type Translator } from '~/src/server/plugins/engine/types/index.js'\nimport {\n type ErrorMessageTemplateList,\n type FormState,\n type FormStateValue,\n type FormSubmissionState\n} from '~/src/server/plugins/engine/types.js'\n\nexport class NumberField extends FormComponent {\n declare options: NumberFieldComponent['options']\n declare schema: NumberFieldComponent['schema']\n declare formSchema: NumberSchema\n declare stateSchema: NumberSchema\n\n constructor(\n def: NumberFieldComponent,\n props: ConstructorParameters<typeof FormComponent>[1]\n ) {\n super(def, props)\n\n const { options, schema } = def\n\n let formSchema = joi\n .number()\n .custom(getValidatorPrecision(this))\n .label(this.label)\n .required()\n\n if (options.required === false) {\n formSchema = formSchema.allow('')\n } else {\n const messages = options.customValidationMessages\n\n formSchema = formSchema.empty('').messages({\n 'any.required':\n messages?.['any.required'] ?? (messageTemplate.required as string)\n })\n }\n\n if (typeof schema.min === 'number') {\n formSchema = formSchema.min(schema.min)\n }\n\n if (typeof schema.max === 'number') {\n formSchema = formSchema.max(schema.max)\n }\n\n if (typeof schema.precision === 'number' && schema.precision <= 0) {\n formSchema = formSchema.integer()\n }\n\n if (options.customValidationMessage) {\n const message = options.customValidationMessage\n\n formSchema = formSchema.messages({\n 'any.required': message,\n 'number.base': message,\n 'number.precision': message,\n 'number.integer': message,\n 'number.min': message,\n 'number.max': message\n })\n } else if (options.customValidationMessages) {\n formSchema = formSchema.messages(options.customValidationMessages)\n }\n\n this.formSchema = formSchema.default('')\n this.stateSchema = formSchema.default(null).allow(null)\n this.options = options\n this.schema = schema\n }\n\n getFormValueFromState(state: FormSubmissionState) {\n const { name } = this\n return this.getFormValue(state[name])\n }\n\n getFormValue(value?: FormStateValue | FormState) {\n return this.isValue(value) ? value : undefined\n }\n\n getViewModel(context: RenderContext) {\n const { options, schema } = this\n\n const viewModel = super.getViewModel(context)\n let { attributes, prefix, suffix, value } = viewModel\n\n if (typeof schema.precision === 'undefined' || schema.precision <= 0) {\n // If precision isn't provided or provided and\n // less than or equal to 0, use numeric inputmode\n attributes.inputmode = 'numeric'\n }\n\n if (options.prefix) {\n prefix = {\n text: options.prefix\n }\n }\n\n if (options.suffix) {\n suffix = {\n text: options.suffix\n }\n }\n\n // Allow any `toString()`-able value so non-numeric\n // values are shown alongside their error messages\n if (!isFormValue(value)) {\n value = undefined\n }\n\n return {\n ...viewModel,\n attributes,\n prefix,\n suffix,\n value\n }\n }\n\n isValue(value?: FormStateValue | FormState) {\n return NumberField.isNumber(value)\n }\n\n getValidationMessagesOverride(translator: Translator) {\n const { t } = translator\n return {\n [this.name]: {\n 'any.required': buildValidationMessages(t).objectRequired,\n 'number.base': buildValidationMessages(t).objectMissing,\n 'number.precision': buildValidationMessages(t).numberPrecision,\n 'number.integer': buildValidationMessages(t).numberInteger,\n 'number.min': buildValidationMessages(t).numberMin,\n 'number.max': buildValidationMessages(t).numberMax\n } as LanguageMessages\n }\n }\n\n /**\n * For error preview page that shows all possible errors on a component\n */\n getAllPossibleErrors(): ErrorMessageTemplateList {\n return NumberField.getAllPossibleErrors()\n }\n\n /**\n * Static version of getAllPossibleErrors that doesn't require a component instance.\n */\n static getAllPossibleErrors(): ErrorMessageTemplateList {\n return {\n baseErrors: [\n { type: 'required', template: messageTemplate.required },\n { type: 'numberInteger', template: messageTemplate.numberInteger }\n ],\n advancedSettingsErrors: [\n { type: 'numberMin', template: messageTemplate.numberMin },\n { type: 'numberMax', template: messageTemplate.numberMax },\n { type: 'numberPrecision', template: messageTemplate.numberPrecision }\n ]\n }\n }\n\n static isNumber(value?: FormStateValue | FormState): value is number {\n return typeof value === 'number'\n }\n}\n\nexport function getValidatorPrecision(component: NumberField) {\n const validator: CustomValidator = (value: number, helpers) => {\n const { options, schema } = component\n\n const { customValidationMessage: custom } = options\n const { precision: limit } = schema\n\n if (!limit || limit <= 0) {\n return value\n }\n\n const validationSchema = joi\n .number()\n .precision(limit)\n .prefs({ convert: false })\n\n try {\n return joi.attempt(value, validationSchema)\n } catch {\n return custom\n ? helpers.message({ custom }, { limit })\n : helpers.error('number.precision', { limit })\n }\n }\n\n return validator\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"NumberField.js","names":["joi","FormComponent","isFormValue","withCustomValidationOverrides","buildValidationMessages","messageTemplate","NumberField","constructor","def","props","options","schema","formSchema","number","custom","getValidatorPrecision","label","required","allow","messages","customValidationMessages","empty","min","max","precision","integer","customValidationMessage","message","default","stateSchema","getFormValueFromState","state","name","getFormValue","value","isValue","undefined","getViewModel","context","viewModel","attributes","prefix","suffix","inputmode","text","isNumber","getValidationMessagesOverride","translator","t","defaults","objectRequired","objectMissing","numberPrecision","numberInteger","numberMin","numberMax","getAllPossibleErrors","baseErrors","type","template","advancedSettingsErrors","component","validator","helpers","limit","validationSchema","prefs","convert","attempt","error"],"sources":["../../../../../src/server/plugins/engine/components/NumberField.ts"],"sourcesContent":["import { type NumberFieldComponent } from '@defra/forms-model'\nimport joi, { type CustomValidator, type NumberSchema } from 'joi'\n\nimport {\n FormComponent,\n isFormValue\n} from '~/src/server/plugins/engine/components/FormComponent.js'\nimport { withCustomValidationOverrides } from '~/src/server/plugins/engine/components/helpers/index.js'\nimport { type RenderContext } from '~/src/server/plugins/engine/components/types.js'\nimport { buildValidationMessages } from '~/src/server/plugins/engine/i18n/buildValidationMessages.js'\nimport { messageTemplate } from '~/src/server/plugins/engine/pageControllers/validationOptions.js'\nimport { type Translator } from '~/src/server/plugins/engine/types/index.js'\nimport {\n type ErrorMessageTemplateList,\n type FormState,\n type FormStateValue,\n type FormSubmissionState\n} from '~/src/server/plugins/engine/types.js'\n\nexport class NumberField extends FormComponent {\n declare options: NumberFieldComponent['options']\n declare schema: NumberFieldComponent['schema']\n declare formSchema: NumberSchema\n declare stateSchema: NumberSchema\n\n constructor(\n def: NumberFieldComponent,\n props: ConstructorParameters<typeof FormComponent>[1]\n ) {\n super(def, props)\n\n const { options, schema } = def\n\n let formSchema = joi\n .number()\n .custom(getValidatorPrecision(this))\n .label(this.label)\n .required()\n\n if (options.required === false) {\n formSchema = formSchema.allow('')\n } else {\n const messages = options.customValidationMessages\n\n formSchema = formSchema.empty('').messages({\n 'any.required':\n messages?.['any.required'] ?? (messageTemplate.required as string)\n })\n }\n\n if (typeof schema.min === 'number') {\n formSchema = formSchema.min(schema.min)\n }\n\n if (typeof schema.max === 'number') {\n formSchema = formSchema.max(schema.max)\n }\n\n if (typeof schema.precision === 'number' && schema.precision <= 0) {\n formSchema = formSchema.integer()\n }\n\n if (options.customValidationMessage) {\n const message = options.customValidationMessage\n\n formSchema = formSchema.messages({\n 'any.required': message,\n 'number.base': message,\n 'number.precision': message,\n 'number.integer': message,\n 'number.min': message,\n 'number.max': message\n })\n } else if (options.customValidationMessages) {\n formSchema = formSchema.messages(options.customValidationMessages)\n }\n\n this.formSchema = formSchema.default('')\n this.stateSchema = formSchema.default(null).allow(null)\n this.options = options\n this.schema = schema\n }\n\n getFormValueFromState(state: FormSubmissionState) {\n const { name } = this\n return this.getFormValue(state[name])\n }\n\n getFormValue(value?: FormStateValue | FormState) {\n return this.isValue(value) ? value : undefined\n }\n\n getViewModel(context: RenderContext) {\n const { options, schema } = this\n\n const viewModel = super.getViewModel(context)\n let { attributes, prefix, suffix, value } = viewModel\n\n if (typeof schema.precision === 'undefined' || schema.precision <= 0) {\n // If precision isn't provided or provided and\n // less than or equal to 0, use numeric inputmode\n attributes.inputmode = 'numeric'\n }\n\n if (options.prefix) {\n prefix = {\n text: options.prefix\n }\n }\n\n if (options.suffix) {\n suffix = {\n text: options.suffix\n }\n }\n\n // Allow any `toString()`-able value so non-numeric\n // values are shown alongside their error messages\n if (!isFormValue(value)) {\n value = undefined\n }\n\n return {\n ...viewModel,\n attributes,\n prefix,\n suffix,\n value\n }\n }\n\n isValue(value?: FormStateValue | FormState) {\n return NumberField.isNumber(value)\n }\n\n getValidationMessagesOverride(translator: Translator) {\n const { customValidationMessage, customValidationMessages } = this.options\n const { t } = translator\n const defaults = {\n 'any.required': buildValidationMessages(t).objectRequired,\n 'number.base': buildValidationMessages(t).objectMissing,\n 'number.precision': buildValidationMessages(t).numberPrecision,\n 'number.integer': buildValidationMessages(t).numberInteger,\n 'number.min': buildValidationMessages(t).numberMin,\n 'number.max': buildValidationMessages(t).numberMax\n }\n\n return {\n [this.name]: withCustomValidationOverrides(\n defaults,\n customValidationMessage,\n customValidationMessages\n )\n }\n }\n\n /**\n * For error preview page that shows all possible errors on a component\n */\n getAllPossibleErrors(): ErrorMessageTemplateList {\n return NumberField.getAllPossibleErrors()\n }\n\n /**\n * Static version of getAllPossibleErrors that doesn't require a component instance.\n */\n static getAllPossibleErrors(): ErrorMessageTemplateList {\n return {\n baseErrors: [\n { type: 'required', template: messageTemplate.required },\n { type: 'numberInteger', template: messageTemplate.numberInteger }\n ],\n advancedSettingsErrors: [\n { type: 'numberMin', template: messageTemplate.numberMin },\n { type: 'numberMax', template: messageTemplate.numberMax },\n { type: 'numberPrecision', template: messageTemplate.numberPrecision }\n ]\n }\n }\n\n static isNumber(value?: FormStateValue | FormState): value is number {\n return typeof value === 'number'\n }\n}\n\nexport function getValidatorPrecision(component: NumberField) {\n const validator: CustomValidator = (value: number, helpers) => {\n const { options, schema } = component\n\n const { customValidationMessage: custom } = options\n const { precision: limit } = schema\n\n if (!limit || limit <= 0) {\n return value\n }\n\n const validationSchema = joi\n .number()\n .precision(limit)\n .prefs({ convert: false })\n\n try {\n return joi.attempt(value, validationSchema)\n } catch {\n return custom\n ? helpers.message({ custom }, { limit })\n : helpers.error('number.precision', { limit })\n }\n }\n\n return validator\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -10,9 +10,7 @@ export declare class YesNoField extends SelectionControlField {
|
|
|
10
10
|
options: YesNoFieldComponent['options'];
|
|
11
11
|
constructor(def: YesNoFieldComponent, props: ConstructorParameters<typeof SelectionControlField>[1]);
|
|
12
12
|
getValidationMessagesOverride(translator: Translator): {
|
|
13
|
-
[x: string]:
|
|
14
|
-
'any.required': string;
|
|
15
|
-
};
|
|
13
|
+
[x: string]: import("joi").LanguageMessages;
|
|
16
14
|
};
|
|
17
15
|
/**
|
|
18
16
|
* For error preview page that shows all possible errors on a component
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { SchemaVersion, yesNoListId, yesNoListName } from '@defra/forms-model';
|
|
2
2
|
import { SelectionControlField } from "./SelectionControlField.js";
|
|
3
|
-
import { addClassOptionIfNone } from "./helpers/index.js";
|
|
3
|
+
import { addClassOptionIfNone, withCustomValidationOverrides } from "./helpers/index.js";
|
|
4
4
|
import { buildValidationMessages } from "../i18n/buildValidationMessages.js";
|
|
5
5
|
import { messageTemplate } from "../pageControllers/validationOptions.js";
|
|
6
6
|
/**
|
|
@@ -39,13 +39,18 @@ export class YesNoField extends SelectionControlField {
|
|
|
39
39
|
this.options = options;
|
|
40
40
|
}
|
|
41
41
|
getValidationMessagesOverride(translator) {
|
|
42
|
+
const {
|
|
43
|
+
customValidationMessage,
|
|
44
|
+
customValidationMessages
|
|
45
|
+
} = this.options;
|
|
42
46
|
const {
|
|
43
47
|
selectYesNoRequired
|
|
44
48
|
} = buildValidationMessages(translator.t);
|
|
49
|
+
const defaults = {
|
|
50
|
+
'any.required': selectYesNoRequired
|
|
51
|
+
};
|
|
45
52
|
return {
|
|
46
|
-
[this.name]:
|
|
47
|
-
'any.required': selectYesNoRequired
|
|
48
|
-
}
|
|
53
|
+
[this.name]: withCustomValidationOverrides(defaults, customValidationMessage, customValidationMessages)
|
|
49
54
|
};
|
|
50
55
|
}
|
|
51
56
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"YesNoField.js","names":["SchemaVersion","yesNoListId","yesNoListName","SelectionControlField","addClassOptionIfNone","buildValidationMessages","messageTemplate","YesNoField","constructor","def","props","list","model","schemaVersion","V1","options","formSchema","required","optional","customValidationMessage","message","messages","customValidationMessages","selectYesNoRequired","getValidationMessagesOverride","translator","t","name","getAllPossibleErrors","baseErrors","type","template","advancedSettingsErrors"],"sources":["../../../../../src/server/plugins/engine/components/YesNoField.ts"],"sourcesContent":["import {\n SchemaVersion,\n yesNoListId,\n yesNoListName,\n type YesNoFieldComponent\n} from '@defra/forms-model'\n\nimport { SelectionControlField } from '~/src/server/plugins/engine/components/SelectionControlField.js'\nimport {
|
|
1
|
+
{"version":3,"file":"YesNoField.js","names":["SchemaVersion","yesNoListId","yesNoListName","SelectionControlField","addClassOptionIfNone","withCustomValidationOverrides","buildValidationMessages","messageTemplate","YesNoField","constructor","def","props","list","model","schemaVersion","V1","options","formSchema","required","optional","customValidationMessage","message","messages","customValidationMessages","selectYesNoRequired","getValidationMessagesOverride","translator","t","defaults","name","getAllPossibleErrors","baseErrors","type","template","advancedSettingsErrors"],"sources":["../../../../../src/server/plugins/engine/components/YesNoField.ts"],"sourcesContent":["import {\n SchemaVersion,\n yesNoListId,\n yesNoListName,\n type YesNoFieldComponent\n} from '@defra/forms-model'\n\nimport { SelectionControlField } from '~/src/server/plugins/engine/components/SelectionControlField.js'\nimport {\n addClassOptionIfNone,\n withCustomValidationOverrides\n} from '~/src/server/plugins/engine/components/helpers/index.js'\nimport { buildValidationMessages } from '~/src/server/plugins/engine/i18n/buildValidationMessages.js'\nimport { type Translator } from '~/src/server/plugins/engine/i18n/types.js'\nimport { messageTemplate } from '~/src/server/plugins/engine/pageControllers/validationOptions.js'\nimport { type ErrorMessageTemplateList } from '~/src/server/plugins/engine/types.js'\n\n/**\n * @description\n * YesNoField is a radiosField with predefined values.\n */\nexport class YesNoField extends SelectionControlField {\n declare options: YesNoFieldComponent['options']\n\n constructor(\n def: YesNoFieldComponent,\n props: ConstructorParameters<typeof SelectionControlField>[1]\n ) {\n super(\n {\n ...def,\n list:\n props.model.schemaVersion === SchemaVersion.V1\n ? yesNoListName\n : yesNoListId\n },\n props\n )\n\n const { options } = def\n let { formSchema } = this\n\n addClassOptionIfNone(options, 'govuk-radios--inline')\n\n if (options.required === false) {\n formSchema = formSchema.optional()\n }\n\n if (options.customValidationMessage) {\n const message = options.customValidationMessage\n\n formSchema = formSchema.messages({\n 'any.required': message\n })\n } else if (options.customValidationMessages) {\n formSchema = formSchema.messages(options.customValidationMessages)\n } else {\n formSchema = formSchema.messages({\n 'any.required': messageTemplate.selectYesNoRequired\n })\n }\n\n this.formSchema = formSchema\n this.options = options\n }\n\n getValidationMessagesOverride(translator: Translator) {\n const { customValidationMessage, customValidationMessages } = this.options\n const { selectYesNoRequired } = buildValidationMessages(translator.t)\n const defaults = {\n 'any.required': selectYesNoRequired\n }\n\n return {\n [this.name]: withCustomValidationOverrides(\n defaults,\n customValidationMessage,\n customValidationMessages\n )\n }\n }\n\n /**\n * For error preview page that shows all possible errors on a component\n */\n getAllPossibleErrors(): ErrorMessageTemplateList {\n return YesNoField.getAllPossibleErrors()\n }\n\n /**\n * Static version of getAllPossibleErrors that doesn't require a component instance.\n */\n static getAllPossibleErrors(): ErrorMessageTemplateList {\n return {\n baseErrors: [\n {\n type: 'selectYesNoRequired',\n template: messageTemplate.selectYesNoRequired\n }\n ],\n advancedSettingsErrors: []\n }\n }\n}\n"],"mappings":"AAAA,SACEA,aAAa,EACbC,WAAW,EACXC,aAAa,QAER,oBAAoB;AAE3B,SAASC,qBAAqB;AAC9B,SACEC,oBAAoB,EACpBC,6BAA6B;AAE/B,SAASC,uBAAuB;AAEhC,SAASC,eAAe;AAGxB;AACA;AACA;AACA;AACA,OAAO,MAAMC,UAAU,SAASL,qBAAqB,CAAC;EAGpDM,WAAWA,CACTC,GAAwB,EACxBC,KAA6D,EAC7D;IACA,KAAK,CACH;MACE,GAAGD,GAAG;MACNE,IAAI,EACFD,KAAK,CAACE,KAAK,CAACC,aAAa,KAAKd,aAAa,CAACe,EAAE,GAC1Cb,aAAa,GACbD;IACR,CAAC,EACDU,KACF,CAAC;IAED,MAAM;MAAEK;IAAQ,CAAC,GAAGN,GAAG;IACvB,IAAI;MAAEO;IAAW,CAAC,GAAG,IAAI;IAEzBb,oBAAoB,CAACY,OAAO,EAAE,sBAAsB,CAAC;IAErD,IAAIA,OAAO,CAACE,QAAQ,KAAK,KAAK,EAAE;MAC9BD,UAAU,GAAGA,UAAU,CAACE,QAAQ,CAAC,CAAC;IACpC;IAEA,IAAIH,OAAO,CAACI,uBAAuB,EAAE;MACnC,MAAMC,OAAO,GAAGL,OAAO,CAACI,uBAAuB;MAE/CH,UAAU,GAAGA,UAAU,CAACK,QAAQ,CAAC;QAC/B,cAAc,EAAED;MAClB,CAAC,CAAC;IACJ,CAAC,MAAM,IAAIL,OAAO,CAACO,wBAAwB,EAAE;MAC3CN,UAAU,GAAGA,UAAU,CAACK,QAAQ,CAACN,OAAO,CAACO,wBAAwB,CAAC;IACpE,CAAC,MAAM;MACLN,UAAU,GAAGA,UAAU,CAACK,QAAQ,CAAC;QAC/B,cAAc,EAAEf,eAAe,CAACiB;MAClC,CAAC,CAAC;IACJ;IAEA,IAAI,CAACP,UAAU,GAAGA,UAAU;IAC5B,IAAI,CAACD,OAAO,GAAGA,OAAO;EACxB;EAEAS,6BAA6BA,CAACC,UAAsB,EAAE;IACpD,MAAM;MAAEN,uBAAuB;MAAEG;IAAyB,CAAC,GAAG,IAAI,CAACP,OAAO;IAC1E,MAAM;MAAEQ;IAAoB,CAAC,GAAGlB,uBAAuB,CAACoB,UAAU,CAACC,CAAC,CAAC;IACrE,MAAMC,QAAQ,GAAG;MACf,cAAc,EAAEJ;IAClB,CAAC;IAED,OAAO;MACL,CAAC,IAAI,CAACK,IAAI,GAAGxB,6BAA6B,CACxCuB,QAAQ,EACRR,uBAAuB,EACvBG,wBACF;IACF,CAAC;EACH;;EAEA;AACF;AACA;EACEO,oBAAoBA,CAAA,EAA6B;IAC/C,OAAOtB,UAAU,CAACsB,oBAAoB,CAAC,CAAC;EAC1C;;EAEA;AACF;AACA;EACE,OAAOA,oBAAoBA,CAAA,EAA6B;IACtD,OAAO;MACLC,UAAU,EAAE,CACV;QACEC,IAAI,EAAE,qBAAqB;QAC3BC,QAAQ,EAAE1B,eAAe,CAACiB;MAC5B,CAAC,CACF;MACDU,sBAAsB,EAAE;IAC1B,CAAC;EACH;AACF","ignoreList":[]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type ComponentDef } from '@defra/forms-model';
|
|
2
|
-
import { type JoiExpression, type ReferenceOptions } from 'joi';
|
|
2
|
+
import { type JoiExpression, type LanguageMessages, type ReferenceOptions } from 'joi';
|
|
3
3
|
import { type Translator } from '../../../../../server/plugins/engine/i18n/types.js';
|
|
4
4
|
/**
|
|
5
5
|
* Prevent Markdown formatting
|
|
@@ -25,9 +25,22 @@ export declare const lowerFirstExpressionOptions: ReferenceOptions;
|
|
|
25
25
|
* Used for error messages in location field components
|
|
26
26
|
*/
|
|
27
27
|
export declare const createLowerFirstExpression: (template: string) => JoiExpression;
|
|
28
|
+
/**
|
|
29
|
+
* Joi's own LanguageMessages type only allows string values, but
|
|
30
|
+
* buildValidationMessages() returns JoiExpression for templated messages,
|
|
31
|
+
* which Joi accepts at runtime. This type covers both.
|
|
32
|
+
*/
|
|
33
|
+
type TranslatedValidationMessages = Record<string, string | JoiExpression>;
|
|
34
|
+
/**
|
|
35
|
+
* Keep the form author's custom validation message for any key they set,
|
|
36
|
+
* so translated defaults only fill in the keys the author left blank.
|
|
37
|
+
* A single customValidationMessage covers every key in the schema.
|
|
38
|
+
*/
|
|
39
|
+
export declare function withCustomValidationOverrides(defaults: TranslatedValidationMessages, customValidationMessage?: string, customValidationMessages?: LanguageMessages): LanguageMessages;
|
|
28
40
|
/**
|
|
29
41
|
* Translate a component label, in precedence order of errorDescription, then shortDesciption, then title
|
|
30
42
|
* @param {ComponentDef} component
|
|
31
43
|
* @param {Translator} translator
|
|
32
44
|
*/
|
|
33
45
|
export declare function getTranslatedLabel(component: ComponentDef, translator: Translator): string;
|
|
46
|
+
export {};
|
|
@@ -39,6 +39,38 @@ export const lowerFirstExpressionOptions = {
|
|
|
39
39
|
*/
|
|
40
40
|
export const createLowerFirstExpression = template => joi.expression(template, lowerFirstExpressionOptions);
|
|
41
41
|
|
|
42
|
+
/**
|
|
43
|
+
* Joi's own LanguageMessages type only allows string values, but
|
|
44
|
+
* buildValidationMessages() returns JoiExpression for templated messages,
|
|
45
|
+
* which Joi accepts at runtime. This type covers both.
|
|
46
|
+
*/
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Keep the form author's custom validation message for any key they set,
|
|
50
|
+
* so translated defaults only fill in the keys the author left blank.
|
|
51
|
+
* A single customValidationMessage covers every key in the schema.
|
|
52
|
+
*/
|
|
53
|
+
export function withCustomValidationOverrides(defaults, customValidationMessage, customValidationMessages) {
|
|
54
|
+
const messages = {};
|
|
55
|
+
|
|
56
|
+
// A global override for all messages is the value for all scenarios
|
|
57
|
+
if (customValidationMessage) {
|
|
58
|
+
for (const key of Object.keys(defaults)) {
|
|
59
|
+
messages[key] = customValidationMessage;
|
|
60
|
+
}
|
|
61
|
+
return messages;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// A default only fills a key that the user has not configured
|
|
65
|
+
const authorKeys = Object.keys(customValidationMessages ?? {});
|
|
66
|
+
for (const [key, message] of Object.entries(defaults)) {
|
|
67
|
+
if (!authorKeys.includes(key)) {
|
|
68
|
+
messages[key] = message;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return messages;
|
|
72
|
+
}
|
|
73
|
+
|
|
42
74
|
/**
|
|
43
75
|
* Translate a component label, in precedence order of errorDescription, then shortDesciption, then title
|
|
44
76
|
* @param {ComponentDef} component
|