diff --git a/package-lock.json b/package-lock.json index 1d373d8be..b5308787c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,6 +28,7 @@ "ibantools": "^3.3.0", "immer": "^9.0.6", "leaflet": "^1.9.4", + "leaflet-draw": "^1.0.4", "leaflet-geosearch": "^3.8.0", "leaflet-gesture-handling": "^1.2.2", "microscope-sass": "^2.0.0", @@ -36,6 +37,7 @@ "react-formio": "^4.3.0", "react-intl": "^6.4.4", "react-leaflet": "4.2.1", + "react-leaflet-draw": "^0.20.4", "react-modal": "3.16.1", "react-number-format": "5.2.2", "react-router-dom": "^6.11.2", @@ -19567,6 +19569,12 @@ "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz", "integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==" }, + "node_modules/leaflet-draw": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/leaflet-draw/-/leaflet-draw-1.0.4.tgz", + "integrity": "sha512-rsQ6saQO5ST5Aj6XRFylr5zvarWgzWnrg46zQ1MEOEIHsppdC/8hnN8qMoFvACsPvTioAuysya/TVtog15tyAQ==", + "license": "MIT" + }, "node_modules/leaflet-geosearch": { "version": "3.11.1", "resolved": "https://registry.npmjs.org/leaflet-geosearch/-/leaflet-geosearch-3.11.1.tgz", @@ -23377,6 +23385,23 @@ "react-dom": "^18.0.0" } }, + "node_modules/react-leaflet-draw": { + "version": "0.20.4", + "resolved": "https://registry.npmjs.org/react-leaflet-draw/-/react-leaflet-draw-0.20.4.tgz", + "integrity": "sha512-u5JHdow2Z9G2AveyUEOTWHXhdhzXdEVQifkNfSaVbEn0gvD+2xW03TQN444zVqovDBvIrBcVWo1VajL4zgl6yg==", + "license": "ISC", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "lodash-es": "^4.17.15" + }, + "peerDependencies": { + "leaflet": "^1.8.0", + "leaflet-draw": "^1.0.4", + "prop-types": "^15.5.2", + "react": "^18.0.0", + "react-leaflet": "^4.0.0" + } + }, "node_modules/react-lifecycles-compat": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", diff --git a/package.json b/package.json index cdba8c6f5..28969b34d 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,7 @@ "ibantools": "^3.3.0", "immer": "^9.0.6", "leaflet": "^1.9.4", + "leaflet-draw": "^1.0.4", "leaflet-geosearch": "^3.8.0", "leaflet-gesture-handling": "^1.2.2", "microscope-sass": "^2.0.0", @@ -51,6 +52,7 @@ "react-formio": "^4.3.0", "react-intl": "^6.4.4", "react-leaflet": "4.2.1", + "react-leaflet-draw": "^0.20.4", "react-modal": "3.16.1", "react-number-format": "5.2.2", "react-router-dom": "^6.11.2", diff --git a/src/components/FormStepSummary/ComponentValueDisplay.jsx b/src/components/FormStepSummary/ComponentValueDisplay.jsx index 2b491424c..8cddb82b4 100644 --- a/src/components/FormStepSummary/ComponentValueDisplay.jsx +++ b/src/components/FormStepSummary/ComponentValueDisplay.jsx @@ -189,7 +189,7 @@ const MapDisplay = ({component, value}) => { return ; } - return ; + return ; }; const CoSignDisplay = ({value}) => { diff --git a/src/components/Map/Map.stories.jsx b/src/components/Map/Map.stories.jsx index 76b75272d..b9d9f8029 100644 --- a/src/components/Map/Map.stories.jsx +++ b/src/components/Map/Map.stories.jsx @@ -1,4 +1,5 @@ -import {userEvent, within} from '@storybook/test'; +import {expect, fn, userEvent, waitFor, within} from '@storybook/test'; +import {useState} from 'react'; import {ConfigDecorator} from 'story-utils/decorators'; @@ -11,12 +12,33 @@ const withMapLayout = Story => ( ); +const StorybookLeafletMap = props => { + const [geoJson, setGeoJson] = useState(props?.geoJsonFeature); + const handleGeoJsonChange = args => { + if (props?.onGeoJsonFeatureSet) { + props?.onGeoJsonFeatureSet(args); + } + setGeoJson(args); + }; + return ( + + ); +}; + export default { title: 'Private API / Map', component: LeafletMap, decorators: [withMapLayout, ConfigDecorator], + render: StorybookLeafletMap, args: { - markerCoordinates: [52.1326332, 5.291266], + geoJsonFeature: { + type: 'Feature', + properties: {}, + geometry: { + type: 'Point', + coordinates: [5.291266, 52.1326332], + }, + }, defaultCenter: [52.1326332, 5.291266], defaultZoomLevel: 12, disabled: false, @@ -31,10 +53,17 @@ export default { export const Map = {}; export const MapWithAddressSearch = { - play: async ({canvasElement}) => { + args: { + onGeoJsonFeatureSet: fn(), + }, + play: async ({canvasElement, args}) => { const canvas = within(canvasElement); - const button = await canvas.findByLabelText('Zoeken'); - await userEvent.click(button); + + await waitFor(async () => { + const button = await canvas.findByLabelText('Zoeken'); + await userEvent.click(button); + expect(await canvas.findByPlaceholderText('Zoek adres')).toBeVisible(); + }); const searchField = await canvas.findByPlaceholderText('Zoek adres'); const searchBox = within(searchField.parentNode); @@ -42,6 +71,18 @@ export const MapWithAddressSearch = { const searchResult = await searchBox.findByText('Utrecht, Utrecht, Utrecht'); await userEvent.click(searchResult); + await waitFor(async () => { + // A marker is placed on the search result + expect(args.onGeoJsonFeatureSet).toBeCalledWith({ + type: 'Feature', + properties: {}, + geometry: { + type: 'Point', + // To make sure that this test doesn't magically fail, just expect any 2 values + coordinates: [expect.anything(), expect.anything()], + }, + }); + }); }, }; @@ -59,3 +100,49 @@ export const MapWithAerialPhotoBackground = { 'https://service.pdok.nl/hwh/luchtfotorgb/wmts/v1_0/Actueel_orthoHR/EPSG:28992/{z}/{x}/{y}.png', }, }; + +export const MapWithInteractions = { + args: { + interactions: { + polygon: true, + polyline: true, + marker: true, + }, + onGeoJsonFeatureSet: fn(), + }, + parameters: { + msw: { + handlers: [mockAddressSearchGet, mockLatLngSearchEmptyGet], + }, + }, + play: async ({canvasElement, step, args}) => { + const canvas = within(canvasElement); + const map = canvasElement.querySelector('.leaflet-pane.leaflet-map-pane'); + + await step('All interactions are available', async () => { + expect(await canvas.findByTitle('Draw a marker')).toBeVisible(); + expect(await canvas.findByTitle('Draw a polygon')).toBeVisible(); + expect(await canvas.findByTitle('Draw a polyline')).toBeVisible(); + }); + + await step('Draw a marker', async () => { + const markerButton = await canvas.findByTitle('Draw a marker'); + await userEvent.click(markerButton); + + await userEvent.click(map, {x: 100, y: 100}); + + expect(await canvas.findByRole('button', {name: 'Marker'})).toBeVisible(); + expect(args.onGeoJsonFeatureSet).toBeCalledWith({ + type: 'Feature', + properties: {}, + geometry: { + type: 'Point', + // Expect that the coordinates array contains 2 items. + // We cannot pin it to specific values, because they can differentiate. + // To make sure that this test doesn't magically fail, just expect any 2 values + coordinates: [expect.anything(), expect.anything()], + }, + }); + }); + }, +}; diff --git a/src/components/Map/index.jsx b/src/components/Map/index.jsx index 35adf77ae..fcc909b44 100644 --- a/src/components/Map/index.jsx +++ b/src/components/Map/index.jsx @@ -1,47 +1,30 @@ +import * as Leaflet from 'leaflet'; import {GeoSearchControl} from 'leaflet-geosearch'; -import isEqual from 'lodash/isEqual'; import PropTypes from 'prop-types'; -import {useCallback, useContext, useEffect} from 'react'; -import {defineMessages, useIntl} from 'react-intl'; -import {MapContainer, Marker, TileLayer, useMap, useMapEvent} from 'react-leaflet'; +import {useContext, useEffect, useRef} from 'react'; +import {useIntl} from 'react-intl'; +import {FeatureGroup, MapContainer, TileLayer, useMap} from 'react-leaflet'; +import {EditControl} from 'react-leaflet-draw'; import {useGeolocation} from 'react-use'; import {ConfigContext} from 'Context'; -import {CRS_RD, DEFAULT_LAT_LNG, DEFAULT_ZOOM, TILE_LAYER_RD} from 'map/constants'; +import { + CRS_RD, + DEFAULT_INTERACTIONS, + DEFAULT_LAT_LNG, + DEFAULT_ZOOM, + TILE_LAYER_RD, +} from 'map/constants'; import {getBEMClassName} from 'utils'; import NearestAddress from './NearestAddress'; +import './map.scss'; import OpenFormsProvider from './provider'; - -const searchControlMessages = defineMessages({ - buttonLabel: { - description: "The leaflet map's search button areaLabel text.", - defaultMessage: 'Map component search button', - }, - searchLabel: { - description: "The leaflet map's input fields placeholder message.", - defaultMessage: 'Enter address, please', - }, - notFound: { - description: "The leaflet map's location not found message.", - defaultMessage: 'Sorry, that address could not be found.', - }, -}); - -const leafletGestureHandlingText = defineMessages({ - touch: { - description: 'Gesturehandeling phone touch message.', - defaultMessage: 'Use two fingers to move the map', - }, - scroll: { - description: 'Gesturehandeling pc scroll message.', - defaultMessage: 'Use ctrl + scroll to zoom the map', - }, - scrollMac: { - description: 'Gesturehandeling mac scroll message.', - defaultMessage: 'Use \u2318 + scroll to zoom the map', - }, -}); +import { + applyLeafletTranslations, + leafletGestureHandlingText, + searchControlMessages, +} from './translations'; const useDefaultCoordinates = () => { // FIXME: can't call hooks conditionally @@ -60,27 +43,64 @@ const useDefaultCoordinates = () => { return [latitude, longitude]; }; +const getCoordinates = geoJsonFeature => { + if (!geoJsonFeature) { + return null; + } + + const center = Leaflet.geoJSON(geoJsonFeature).getBounds().getCenter(); + return [center.lat, center.lng]; +}; + const LeaftletMap = ({ - markerCoordinates, - onMarkerSet, + geoJsonFeature, + onGeoJsonFeatureSet, defaultCenter = DEFAULT_LAT_LNG, defaultZoomLevel = DEFAULT_ZOOM, disabled = false, + interactions = DEFAULT_INTERACTIONS, tileLayerUrl = TILE_LAYER_RD.url, }) => { + const featureGroupRef = useRef(); const intl = useIntl(); const defaultCoordinates = useDefaultCoordinates(); - const coordinates = markerCoordinates || defaultCoordinates; - - const onWrapperMarkerSet = coordinates => { - const coordinatesChanged = !isEqual(markerCoordinates, coordinates); - if (!coordinatesChanged) return; - onMarkerSet(coordinates); - }; + const geoJsonCoordinates = getCoordinates(geoJsonFeature); + const coordinates = geoJsonCoordinates ?? defaultCoordinates; const modifiers = disabled ? ['disabled'] : []; const className = getBEMClassName('leaflet-map', modifiers); + applyLeafletTranslations(intl); + + const onFeatureCreate = event => { + updateGeoJsonFeature(event.layer); + }; + + const onFeatureDelete = () => { + // The value `null` is needed to make sure that Formio actually updates the value. + // node_modules/formiojs/components/_classes/component/Component.js:2528 + onGeoJsonFeatureSet(null); + }; + + const onSearchMarkerSet = event => { + updateGeoJsonFeature(event.marker); + }; + + const updateGeoJsonFeature = newFeatureLayer => { + if (featureGroupRef.current) { + const newFeatureLayerId = newFeatureLayer._leaflet_id; + const layers = featureGroupRef.current?.getLayers(); + // Limit the amount of features to 1, by removing the previous layer + if (layers.length > 1) { + const oldLayerId = layers + .map(layer => layer._leaflet_id) + .filter(layerId => layerId !== newFeatureLayerId); + featureGroupRef.current?.removeLayer(oldLayerId[0]); + } + } + onGeoJsonFeatureSet(newFeatureLayer.toGeoJSON()); + }; + return ( <> - {coordinates ? ( - <> - - - - ) : null} - - {disabled ? : } + + {!disabled && ( + + )} + + {coordinates && } + {!disabled && ( + + )} + {disabled && } - {markerCoordinates && markerCoordinates.length && ( - + {geoJsonCoordinates && geoJsonCoordinates.length && ( + )} ); }; LeaftletMap.propTypes = { - markerCoordinates: PropTypes.arrayOf(PropTypes.number), - onMarkerSet: PropTypes.func, + geoJsonFeature: PropTypes.shape({ + type: PropTypes.oneOf(['Feature']).isRequired, + properties: PropTypes.object, + geometry: PropTypes.oneOfType([ + PropTypes.shape({ + type: PropTypes.oneOf(['Point']).isRequired, + coordinates: PropTypes.arrayOf(PropTypes.number).isRequired, + }), + PropTypes.shape({ + type: PropTypes.oneOf(['LineString']).isRequired, + coordinates: PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.number)).isRequired, + }), + PropTypes.shape({ + type: PropTypes.oneOf(['Polygon']).isRequired, + coordinates: PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.number))) + .isRequired, + }), + ]).isRequired, + }), + onGeoJsonFeatureSet: PropTypes.func, + interactions: PropTypes.shape({ + polyline: PropTypes.bool, + polygon: PropTypes.bool, + marker: PropTypes.bool, + }), disabled: PropTypes.bool, tileLayerUrl: PropTypes.string, }; @@ -172,15 +232,6 @@ const SearchControl = ({onMarkerSet, options}) => { const buttonLabel = intl.formatMessage(searchControlMessages.buttonLabel); - const setMarker = useCallback( - result => { - if (result.location) { - onMarkerSet([result.location.y, result.location.x]); - } - }, - [onMarkerSet] - ); - useEffect(() => { const provider = new OpenFormsProvider(baseUrl); const searchControl = new GeoSearchControl({ @@ -199,15 +250,15 @@ const SearchControl = ({onMarkerSet, options}) => { searchControl.button.setAttribute('aria-label', buttonLabel); map.addControl(searchControl); - map.on('geosearch/showlocation', setMarker); + map.on('geosearch/showlocation', onMarkerSet); return () => { - map.off('geosearch/showlocation', setMarker); + map.off('geosearch/showlocation', onMarkerSet); map.removeControl(searchControl); }; }, [ map, - setMarker, + onMarkerSet, baseUrl, showMarker, showPopup, @@ -239,24 +290,6 @@ SearchControl.propTypes = { }), }; -const MarkerWrapper = ({position, onMarkerSet, ...props}) => { - const shouldSetMarker = !!(position && position.length === 2); - - useEffect(() => { - if (!shouldSetMarker) return; - if (!onMarkerSet) return; - onMarkerSet(position); - }); - - // only render a marker if we explicitly have a marker - return shouldSetMarker ? : null; -}; - -MarkerWrapper.propTypes = { - position: PropTypes.arrayOf(PropTypes.number), - onMarkerSet: PropTypes.func, -}; - const DisabledMapControls = () => { const map = useMap(); useEffect(() => { @@ -271,16 +304,4 @@ const DisabledMapControls = () => { return null; }; -const CaptureClick = ({setMarker}) => { - useMapEvent('click', event => { - const newLatLng = [event.latlng.lat, event.latlng.lng]; - setMarker(newLatLng); - }); - return null; -}; - -CaptureClick.propTypes = { - setMarker: PropTypes.func.isRequired, -}; - export default LeaftletMap; diff --git a/src/components/Map/map.scss b/src/components/Map/map.scss new file mode 100644 index 000000000..d02b5593c --- /dev/null +++ b/src/components/Map/map.scss @@ -0,0 +1,26 @@ +@import 'leaflet/dist/leaflet.css'; +@import 'leaflet-draw/dist/leaflet.draw.css'; + +.leaflet-draw-actions { + margin-top: -1px; + border: 2px solid rgba(0, 0, 0, 0.2); + border-radius: 4px; + + // Make sure all action bars are the same height + a, + &.leaflet-draw-actions-top a, + &.leaflet-draw-actions-bottom a { + height: 30px; + line-height: 30px; + } + + a { + background-color: #fff; + border-color: #ccc; + + &:hover, + &:focus { + background-color: #f4f4f4; + } + } +} diff --git a/src/components/Map/translations.js b/src/components/Map/translations.js new file mode 100644 index 000000000..3aec19e8c --- /dev/null +++ b/src/components/Map/translations.js @@ -0,0 +1,202 @@ +import * as Leaflet from 'leaflet'; +import {defineMessages} from 'react-intl'; + +const searchControlMessages = defineMessages({ + buttonLabel: { + description: "The leaflet map's search button areaLabel text.", + defaultMessage: 'Map component search button', + }, + searchLabel: { + description: "The leaflet map's input fields placeholder message.", + defaultMessage: 'Enter address, please', + }, + notFound: { + description: "The leaflet map's location not found message.", + defaultMessage: 'Sorry, that address could not be found.', + }, +}); + +const leafletGestureHandlingText = defineMessages({ + touch: { + description: 'Gesturehandeling phone touch message.', + defaultMessage: 'Use two fingers to move the map', + }, + scroll: { + description: 'Gesturehandeling pc scroll message.', + defaultMessage: 'Use ctrl + scroll to zoom the map', + }, + scrollMac: { + description: 'Gesturehandeling mac scroll message.', + defaultMessage: 'Use \u2318 + scroll to zoom the map', + }, +}); + +const leafletEditToolbarMessages = defineMessages({ + saveText: { + description: 'Edit toolbar save message.', + defaultMessage: 'Save', + }, + saveTitle: { + description: 'Edit toolbar save tooltip.', + defaultMessage: 'Save changes', + }, + cancelText: { + description: 'Edit toolbar cancel message.', + defaultMessage: 'Cancel', + }, + cancelTitle: { + description: 'Edit toolbar cancel tooltip.', + defaultMessage: 'Cancel changes', + }, + clearAllText: { + description: 'Edit toolbar clearAll message.', + defaultMessage: 'Remove all', + }, + clearAllTitle: { + description: 'Edit toolbar clearAll tooltip.', + defaultMessage: 'Remove all shapes', + }, + remove: { + description: 'Edit toolbar remove button tooltip.', + defaultMessage: 'Remove shapes', + }, + removeDisabled: { + description: 'Edit toolbar remove button disabled tooltip.', + defaultMessage: 'No shapes to remove', + }, +}); + +const leafletDrawToolbarMessages = defineMessages({ + actionsText: { + description: 'Draw toolbar cancel button message.', + defaultMessage: 'Cancel', + }, + actionsTitle: { + description: 'Draw toolbar cancel button tooltip.', + defaultMessage: 'Cancel drawing', + }, + finishText: { + description: 'Draw toolbar finish button message.', + defaultMessage: 'Finish', + }, + finishTitle: { + description: 'Draw toolbar finish button tooltip.', + defaultMessage: 'Finish drawing', + }, + undoText: { + description: 'Draw toolbar undo button message.', + defaultMessage: 'Remove last point', + }, + undoTitle: { + description: 'Draw toolbar undo button tooltip.', + defaultMessage: 'Remove last drawn point', + }, + polyline: { + description: 'Draw toolbar polyline button tooltip.', + defaultMessage: 'Line', + }, + polygon: { + description: 'Draw toolbar polygon button tooltip.', + defaultMessage: 'Shape (polygon)', + }, + marker: { + description: 'Draw toolbar marker button tooltip.', + defaultMessage: 'Marker', + }, +}); + +const leafletDrawHandlerMessages = defineMessages({ + markerTooltipStart: { + description: 'Draw handler marker tooltip start.', + defaultMessage: 'Click map to place marker', + }, + polylineTooltipStart: { + description: 'Draw handler polyline tooltip start.', + defaultMessage: 'Click to start drawing line', + }, + polylineTooltipContinue: { + description: 'Draw handler polyline tooltip continue.', + defaultMessage: 'Click to continue drawing line', + }, + polylineTooltipEnd: { + description: 'Draw handler polyline tooltip end.', + defaultMessage: 'Click last point to finish line', + }, + polygonTooltipStart: { + description: 'Draw handler polygon tooltip start.', + defaultMessage: 'Click to start drawing shape', + }, + polygonTooltipContinue: { + description: 'Draw handler polygon tooltip continue.', + defaultMessage: 'Click to continue drawing shape', + }, + polygonTooltipEnd: { + description: 'Draw handler polygon tooltip end.', + defaultMessage: 'Click first point to finish shape', + }, +}); + +const applyLeafletTranslations = intl => { + // We have to do the translations via Leaflet + // https://github.com/alex3165/react-leaflet-draw/issues/179 + Leaflet.drawLocal.edit.toolbar = { + actions: { + save: { + text: intl.formatMessage(leafletEditToolbarMessages.saveText), + title: intl.formatMessage(leafletEditToolbarMessages.saveTitle), + }, + cancel: { + text: intl.formatMessage(leafletEditToolbarMessages.cancelText), + title: intl.formatMessage(leafletEditToolbarMessages.cancelTitle), + }, + clearAll: { + text: intl.formatMessage(leafletEditToolbarMessages.clearAllText), + title: intl.formatMessage(leafletEditToolbarMessages.clearAllTitle), + }, + }, + buttons: { + remove: intl.formatMessage(leafletEditToolbarMessages.remove), + removeDisabled: intl.formatMessage(leafletEditToolbarMessages.removeDisabled), + }, + }; + Leaflet.drawLocal.draw.toolbar = { + actions: { + text: intl.formatMessage(leafletDrawToolbarMessages.actionsText), + title: intl.formatMessage(leafletDrawToolbarMessages.actionsTitle), + }, + finish: { + text: intl.formatMessage(leafletDrawToolbarMessages.finishText), + title: intl.formatMessage(leafletDrawToolbarMessages.finishTitle), + }, + undo: { + text: intl.formatMessage(leafletDrawToolbarMessages.undoText), + title: intl.formatMessage(leafletDrawToolbarMessages.undoTitle), + }, + buttons: { + polyline: intl.formatMessage(leafletDrawToolbarMessages.polyline), + polygon: intl.formatMessage(leafletDrawToolbarMessages.polygon), + marker: intl.formatMessage(leafletDrawToolbarMessages.marker), + }, + }; + Leaflet.drawLocal.draw.handlers.marker = { + tooltip: { + start: intl.formatMessage(leafletDrawHandlerMessages.markerTooltipStart), + }, + }; + Leaflet.drawLocal.draw.handlers.polyline = { + tooltip: { + start: intl.formatMessage(leafletDrawHandlerMessages.polylineTooltipStart), + cont: intl.formatMessage(leafletDrawHandlerMessages.polylineTooltipContinue), + end: intl.formatMessage(leafletDrawHandlerMessages.polylineTooltipEnd), + }, + }; + Leaflet.drawLocal.draw.handlers.polygon = { + tooltip: { + start: intl.formatMessage(leafletDrawHandlerMessages.polygonTooltipStart), + cont: intl.formatMessage(leafletDrawHandlerMessages.polygonTooltipContinue), + end: intl.formatMessage(leafletDrawHandlerMessages.polygonTooltipEnd), + }, + }; +}; + +export {searchControlMessages, leafletGestureHandlingText, applyLeafletTranslations}; diff --git a/src/formio/components/Map.jsx b/src/formio/components/Map.jsx index 0e75ac9ff..f633972db 100644 --- a/src/formio/components/Map.jsx +++ b/src/formio/components/Map.jsx @@ -44,7 +44,7 @@ export default class Map extends Field { } get emptyValue() { - return ''; + return undefined; } /** @@ -90,8 +90,8 @@ export default class Map extends Field { super.destroy(); } - onMarkerSet(newLatLng) { - this.setValue(newLatLng, {modified: true}); + onGeoJsonSet(newGeoJson) { + this.setValue(newGeoJson, {modified: true}); } renderReact() { @@ -99,7 +99,7 @@ export default class Map extends Field { const {lat = defaultLat, lng = defaultLon} = this.component?.initialCenter || {}; const defaultCenter = [lat, lng]; - const markerCoordinates = this.getValue(); + const geoJsonFeature = this.getValue(); const container = this.refs.mapContainer; const zoom = this.component.defaultZoom; @@ -110,10 +110,11 @@ export default class Map extends Field { @@ -122,6 +123,11 @@ export default class Map extends Field { } setValue(value, flags = {}) { + if (value === null) { + // The `resetValue` flag is needed to allow the setting of `undefined` or `null` values. + // node_modules/formiojs/components/_classes/component/Component.js:2526 + flags.resetValue = true; + } const changed = super.setValue(value, flags); // re-render if the value is set, which may be because of existing submission data changed && this.renderReact(); diff --git a/src/i18n/compiled/en.json b/src/i18n/compiled/en.json index 69d4d9e5d..a8d22545c 100644 --- a/src/i18n/compiled/en.json +++ b/src/i18n/compiled/en.json @@ -43,12 +43,30 @@ "value": "." } ], + "+KBbXH": [ + { + "type": 0, + "value": "Click to start drawing shape" + } + ], + "+W79Dr": [ + { + "type": 0, + "value": "Click to continue drawing line" + } + ], "+uwsgF": [ { "type": 0, "value": "Location and time" } ], + "/yX9Xl": [ + { + "type": 0, + "value": "Cancel drawing" + } + ], "0j8tMq": [ { "type": 0, @@ -81,6 +99,12 @@ "value": "Something went wrong while presenting the login option. Please contact the municipality." } ], + "2D6ubj": [ + { + "type": 0, + "value": "Line" + } + ], "2HHJrq": [ { "type": 0, @@ -117,6 +141,12 @@ "value": "Loading..." } ], + "4ZOmtU": [ + { + "type": 0, + "value": "Save changes" + } + ], "4gPdgK": [ { "type": 0, @@ -129,6 +159,12 @@ "value": "Verify" } ], + "4ui8R+": [ + { + "type": 0, + "value": "Click last point to finish line" + } + ], "5uh2hS": [ { "type": 0, @@ -155,6 +191,12 @@ "value": "Check and co-sign submission" } ], + "62SBjV": [ + { + "type": 0, + "value": "Shape (polygon)" + } + ], "6GNK65": [ { "type": 0, @@ -449,6 +491,12 @@ "value": "provider" } ], + "B/W1uC": [ + { + "type": 0, + "value": "Remove shapes" + } + ], "BL1Ehr": [ { "type": 0, @@ -479,6 +527,12 @@ "value": "This form is currently undergoing maintenance and can not be accessed at the moment." } ], + "D6TdPW": [ + { + "type": 0, + "value": "Click map to place marker" + } + ], "DBTNgI": [ { "type": 0, @@ -665,6 +719,18 @@ "value": "Inloggen bij deze organisatie is niet gelukt. Probeert u het later nog een keer. Lukt het nog steeds niet? Log in bij Mijn DigiD. Zo controleert u of uw DigiD goed werkt. Mogelijk is er een storing bij de organisatie waar u inlogt." } ], + "HY6Irs": [ + { + "type": 0, + "value": "Cancel changes" + } + ], + "HgLr1F": [ + { + "type": 0, + "value": "Cancel" + } + ], "HhcSoc": [ { "type": 0, @@ -677,6 +743,12 @@ "value": "Invalid input." } ], + "Hkq6NE": [ + { + "type": 0, + "value": "Finish drawing" + } + ], "I6ok5N": [ { "type": 0, @@ -973,6 +1045,12 @@ "value": "Payment" } ], + "N2sZnS": [ + { + "type": 0, + "value": "Save" + } + ], "OnfuIr": [ { "options": { @@ -1005,6 +1083,12 @@ "value": "withAsterisk" } ], + "Op4orj": [ + { + "type": 0, + "value": "No shapes to remove" + } + ], "P194bo": [ { "type": 0, @@ -1031,6 +1115,12 @@ "value": "Invalid input." } ], + "Q6/Lj7": [ + { + "type": 0, + "value": "Remove last drawn point" + } + ], "QPdaOi": [ { "type": 0, @@ -1223,6 +1313,12 @@ "value": "." } ], + "U5+FHP": [ + { + "type": 0, + "value": "Cancel" + } + ], "UyEKdQ": [ { "type": 0, @@ -1297,6 +1393,12 @@ "value": "." } ], + "Y3jHZm": [ + { + "type": 0, + "value": "Remove last point" + } + ], "YcC4PD": [ { "type": 0, @@ -1423,6 +1525,12 @@ "value": "Contact details" } ], + "bRtoG6": [ + { + "type": 0, + "value": "Remove all" + } + ], "bgfiRG": [ { "type": 0, @@ -1465,6 +1573,12 @@ "value": "Back to form start" } ], + "dNGw+S": [ + { + "type": 0, + "value": "Click to continue drawing shape" + } + ], "eAmrdi": [ { "type": 0, @@ -1483,6 +1597,12 @@ "value": "Processing..." } ], + "fJVa0u": [ + { + "type": 0, + "value": "Marker" + } + ], "fWjfVm": [ { "type": 0, @@ -2075,6 +2195,12 @@ "value": "Find address" } ], + "sYb+eZ": [ + { + "type": 0, + "value": "Remove all shapes" + } + ], "senRv3": [ { "type": 0, @@ -2215,12 +2341,24 @@ "value": "Amount" } ], + "vfKvuS": [ + { + "type": 0, + "value": "Click first point to finish shape" + } + ], "wwsWUp": [ { "type": 0, "value": "How do you rate this form?" } ], + "xh+7Vv": [ + { + "type": 0, + "value": "Finish" + } + ], "y31iyC": [ { "type": 0, @@ -2247,6 +2385,12 @@ "value": "Return to main website" } ], + "zpHAro": [ + { + "type": 0, + "value": "Click to start drawing line" + } + ], "zvoXSU": [ { "type": 0, diff --git a/src/i18n/compiled/nl.json b/src/i18n/compiled/nl.json index a57a85100..d1524570a 100644 --- a/src/i18n/compiled/nl.json +++ b/src/i18n/compiled/nl.json @@ -43,12 +43,30 @@ "value": " actief." } ], + "+KBbXH": [ + { + "type": 0, + "value": "Klik om een veelhoek (polygoon) te tekenen" + } + ], + "+W79Dr": [ + { + "type": 0, + "value": "Klik om verder te tekenen" + } + ], "+uwsgF": [ { "type": 0, "value": "Afspraakdetails" } ], + "/yX9Xl": [ + { + "type": 0, + "value": "Tekeningen annuleren" + } + ], "0j8tMq": [ { "type": 0, @@ -81,6 +99,12 @@ "value": "Er is iets fout gegaan bij het presenteren van de inlogopties. Neem alstublieft contact met ons op." } ], + "2D6ubj": [ + { + "type": 0, + "value": "Lijn" + } + ], "2HHJrq": [ { "type": 0, @@ -117,6 +141,12 @@ "value": "Opties ophalen..." } ], + "4ZOmtU": [ + { + "type": 0, + "value": "Wijzigingen opslaan" + } + ], "4gPdgK": [ { "type": 0, @@ -129,6 +159,12 @@ "value": "Bevestigen" } ], + "4ui8R+": [ + { + "type": 0, + "value": "Klik het laatste punt om de lijn te voltooien" + } + ], "5uh2hS": [ { "type": 0, @@ -155,6 +191,12 @@ "value": "Controle en medeondertekenen inzending" } ], + "62SBjV": [ + { + "type": 0, + "value": "Veelhoek (polygoon)" + } + ], "6GNK65": [ { "type": 0, @@ -449,6 +491,12 @@ "value": "provider" } ], + "B/W1uC": [ + { + "type": 0, + "value": "Verwijder vormen" + } + ], "BL1Ehr": [ { "type": 0, @@ -479,6 +527,12 @@ "value": "Dit formulier is momenteel in onderhoud en daardoor tijdelijk niet beschikbaar." } ], + "D6TdPW": [ + { + "type": 0, + "value": "Klik op de kaart om een pin/punt te plaatsen" + } + ], "DBTNgI": [ { "type": 0, @@ -665,6 +719,18 @@ "value": "Inloggen bij deze organisatie is niet gelukt. Probeert u het later nog een keer. Lukt het nog steeds niet? Log in bij Mijn DigiD. Zo controleert u of uw DigiD goed werkt. Mogelijk is er een storing bij de organisatie waar u inlogt." } ], + "HY6Irs": [ + { + "type": 0, + "value": "Wijzigingen annuleren" + } + ], + "HgLr1F": [ + { + "type": 0, + "value": "Annuleer" + } + ], "HhcSoc": [ { "type": 0, @@ -677,6 +743,12 @@ "value": "Ongeldige invoer." } ], + "Hkq6NE": [ + { + "type": 0, + "value": "Tekening voltooien" + } + ], "I6ok5N": [ { "type": 0, @@ -973,6 +1045,12 @@ "value": "Betalen" } ], + "N2sZnS": [ + { + "type": 0, + "value": "Opslaan" + } + ], "OnfuIr": [ { "options": { @@ -1005,6 +1083,12 @@ "value": "withAsterisk" } ], + "Op4orj": [ + { + "type": 0, + "value": "Geen vormen om te verwijderen" + } + ], "P194bo": [ { "type": 0, @@ -1031,6 +1115,12 @@ "value": "Ongeldige invoer." } ], + "Q6/Lj7": [ + { + "type": 0, + "value": "Verwijder het laatst getekende punt" + } + ], "QPdaOi": [ { "type": 0, @@ -1223,6 +1313,12 @@ "value": " lang zijn." } ], + "U5+FHP": [ + { + "type": 0, + "value": "Annuleer" + } + ], "UyEKdQ": [ { "type": 0, @@ -1297,6 +1393,12 @@ "value": " zijn." } ], + "Y3jHZm": [ + { + "type": 0, + "value": "Verwijder laatste punt" + } + ], "YcC4PD": [ { "type": 0, @@ -1427,6 +1529,12 @@ "value": "Je gegevens" } ], + "bRtoG6": [ + { + "type": 0, + "value": "Verwijder alles" + } + ], "bgfiRG": [ { "type": 0, @@ -1469,6 +1577,12 @@ "value": "Terug naar begin" } ], + "dNGw+S": [ + { + "type": 0, + "value": "Klik om verder te tekenen" + } + ], "eAmrdi": [ { "type": 0, @@ -1487,6 +1601,12 @@ "value": "Bezig..." } ], + "fJVa0u": [ + { + "type": 0, + "value": "Pin/punt" + } + ], "fWjfVm": [ { "type": 0, @@ -2079,6 +2199,12 @@ "value": "Zoek adres" } ], + "sYb+eZ": [ + { + "type": 0, + "value": "Verwijder alle vormen van de kaart" + } + ], "senRv3": [ { "type": 0, @@ -2219,12 +2345,24 @@ "value": "Aantal personen" } ], + "vfKvuS": [ + { + "type": 0, + "value": "Klik op het eerste punt, om de veelhoek te voltooien" + } + ], "wwsWUp": [ { "type": 0, "value": "Wat vind je van dit formulier?" } ], + "xh+7Vv": [ + { + "type": 0, + "value": "Voltooi" + } + ], "y31iyC": [ { "type": 0, @@ -2251,6 +2389,12 @@ "value": "Terug naar de website" } ], + "zpHAro": [ + { + "type": 0, + "value": "Klik om een lijk te tekenen" + } + ], "zvoXSU": [ { "type": 0, diff --git a/src/i18n/messages/en.json b/src/i18n/messages/en.json index 965f9c360..c075c5ed0 100644 --- a/src/i18n/messages/en.json +++ b/src/i18n/messages/en.json @@ -9,11 +9,26 @@ "description": "Form save modal body text", "originalDefault": "Enter your email address to get an email to resume the form at a later date. This can be done on any device where you open the link. The link remains valid for {numberOfDays, plural, one {1 day} other {{numberOfDays} days}}." }, + "+KBbXH": { + "defaultMessage": "Click to start drawing shape", + "description": "Draw handler polygon tooltip start.", + "originalDefault": "Click to start drawing shape" + }, + "+W79Dr": { + "defaultMessage": "Click to continue drawing line", + "description": "Draw handler polyline tooltip continue.", + "originalDefault": "Click to continue drawing line" + }, "+uwsgF": { "defaultMessage": "Location and time", "description": "Appointments navbar title for 'location and time' step", "originalDefault": "Location and time" }, + "/yX9Xl": { + "defaultMessage": "Cancel drawing", + "description": "Draw toolbar cancel button tooltip.", + "originalDefault": "Cancel drawing" + }, "0j8tMq": { "defaultMessage": "Log out", "description": "Log out button text", @@ -29,6 +44,11 @@ "description": "Co-sign auth option not available on form", "originalDefault": "Something went wrong while presenting the login option. Please contact the municipality." }, + "2D6ubj": { + "defaultMessage": "Line", + "description": "Draw toolbar polyline button tooltip.", + "originalDefault": "Line" + }, "2HHJrq": { "defaultMessage": "Invalid function arguments", "description": "ZOD 'invalid_arguments' error message", @@ -59,6 +79,11 @@ "description": "(Async) select options loading message", "originalDefault": "Loading..." }, + "4ZOmtU": { + "defaultMessage": "Save changes", + "description": "Edit toolbar save tooltip.", + "originalDefault": "Save changes" + }, "4gPdgK": { "defaultMessage": "Bad", "description": "GovMetric rating text", @@ -69,6 +94,11 @@ "description": "Email verification: verify code button text", "originalDefault": "Verify" }, + "4ui8R+": { + "defaultMessage": "Click last point to finish line", + "description": "Draw handler polyline tooltip end.", + "originalDefault": "Click last point to finish line" + }, "5uh2hS": { "defaultMessage": "Appointment cancellation failed", "description": "Appointment cancellation error message", @@ -84,6 +114,11 @@ "description": "Check overview and co-sign", "originalDefault": "Check and co-sign submission" }, + "62SBjV": { + "defaultMessage": "Shape (polygon)", + "description": "Draw toolbar polygon button tooltip.", + "originalDefault": "Shape (polygon)" + }, "6GNK65": { "defaultMessage": "There was an authentication and/or permission problem.", "description": "Authentication error message", @@ -214,6 +249,11 @@ "description": "Login button label", "originalDefault": "Login with {provider}" }, + "B/W1uC": { + "defaultMessage": "Remove shapes", + "description": "Edit toolbar remove button tooltip.", + "originalDefault": "Remove shapes" + }, "BL1Ehr": { "defaultMessage": "Invalid.", "description": "ZOD 'invalid_string' error message, regex validation", @@ -239,6 +279,11 @@ "description": "Maintenance mode message", "originalDefault": "This form is currently undergoing maintenance and can not be accessed at the moment." }, + "D6TdPW": { + "defaultMessage": "Click map to place marker", + "description": "Draw handler marker tooltip start.", + "originalDefault": "Click map to place marker" + }, "DBTNgI": { "defaultMessage": "d", "description": "Placeholder for day part of a date", @@ -364,6 +409,16 @@ "description": "DigiD error message. MUST BE THIS EXACT STRING!", "originalDefault": "Inloggen bij deze organisatie is niet gelukt. Probeert u het later nog een keer. Lukt het nog steeds niet? Log in bij Mijn DigiD. Zo controleert u of uw DigiD goed werkt. Mogelijk is er een storing bij de organisatie waar u inlogt." }, + "HY6Irs": { + "defaultMessage": "Cancel changes", + "description": "Edit toolbar cancel tooltip.", + "originalDefault": "Cancel changes" + }, + "HgLr1F": { + "defaultMessage": "Cancel", + "description": "Draw toolbar cancel button message.", + "originalDefault": "Cancel" + }, "HhcSoc": { "defaultMessage": "Save and resume later", "description": "Form save modal title", @@ -374,6 +429,11 @@ "description": "ZOD 'too_big' error message, generic", "originalDefault": "Invalid input." }, + "Hkq6NE": { + "defaultMessage": "Finish drawing", + "description": "Draw toolbar finish button tooltip.", + "originalDefault": "Finish drawing" + }, "I6ok5N": { "defaultMessage": "Invalid {validation, select, email {email} url {url} datetime {date and time} ip {IP address} other {validation} }.", "description": "ZOD 'invalid_string' error message, validation other than regex", @@ -484,11 +544,21 @@ "description": "Payment page title", "originalDefault": "Payment" }, + "N2sZnS": { + "defaultMessage": "Save", + "description": "Edit toolbar save message.", + "originalDefault": "Save" + }, "OnfuIr": { "defaultMessage": "{withAsterisk, select, true {} other { (not required)}}", "description": "Form field label, field not required", "originalDefault": "{withAsterisk, select, true {} other { (not required)}}" }, + "Op4orj": { + "defaultMessage": "No shapes to remove", + "description": "Edit toolbar remove button disabled tooltip.", + "originalDefault": "No shapes to remove" + }, "P194bo": { "defaultMessage": "Invalid input: must start with \"{startsWith}\".", "description": "ZOD 'invalid_string' error message, with startsWith", @@ -504,6 +574,11 @@ "description": "ZOD 'too_small' error message, generic", "originalDefault": "Invalid input." }, + "Q6/Lj7": { + "defaultMessage": "Remove last drawn point", + "description": "Draw toolbar undo button tooltip.", + "originalDefault": "Remove last drawn point" + }, "QPdaOi": { "defaultMessage": "No results found", "description": "Select 'no options' message", @@ -574,6 +649,11 @@ "description": "ZOD 'too_small' error message, for strings", "originalDefault": "String must contain {exact, select, true {exactly} other {{inclusive, select, true {at least} other {more than}}} } {minimum, plural, one {{minimum} character} other {{minimum} characters}}." }, + "U5+FHP": { + "defaultMessage": "Cancel", + "description": "Edit toolbar cancel message.", + "originalDefault": "Cancel" + }, "UyEKdQ": { "defaultMessage": "Product {number}/{total}", "description": "Appointments: single product label/header", @@ -619,6 +699,11 @@ "description": "ZOD 'too_big' error message, for dates", "originalDefault": "Date must be smaller than or equal to {maximum}." }, + "Y3jHZm": { + "defaultMessage": "Remove last point", + "description": "Draw toolbar undo button message.", + "originalDefault": "Remove last point" + }, "YcC4PD": { "defaultMessage": "Choose language", "description": "Language selection heading", @@ -669,6 +754,11 @@ "description": "Appointments: contact details step title", "originalDefault": "Contact details" }, + "bRtoG6": { + "defaultMessage": "Remove all", + "description": "Edit toolbar clearAll message.", + "originalDefault": "Remove all" + }, "bgfiRG": { "defaultMessage": "You've started the payment process.", "description": "payment started status", @@ -704,6 +794,11 @@ "description": "return to form start link after 403", "originalDefault": "Back to form start" }, + "dNGw+S": { + "defaultMessage": "Click to continue drawing shape", + "description": "Draw handler polygon tooltip continue.", + "originalDefault": "Click to continue drawing shape" + }, "eAmrdi": { "defaultMessage": "Loading...", "description": "Loading content text", @@ -719,6 +814,11 @@ "description": "Checking background processing status title", "originalDefault": "Processing..." }, + "fJVa0u": { + "defaultMessage": "Marker", + "description": "Draw toolbar marker button tooltip.", + "originalDefault": "Marker" + }, "fWjfVm": { "defaultMessage": "Please hold on while we're processing your submission.", "description": "Checking background processing status body", @@ -989,6 +1089,11 @@ "description": "The leaflet map's input fields placeholder message.", "originalDefault": "Enter address, please" }, + "sYb+eZ": { + "defaultMessage": "Remove all shapes", + "description": "Edit toolbar clearAll tooltip.", + "originalDefault": "Remove all shapes" + }, "senRv3": { "defaultMessage": "You're about to cancel your appointment on {date} at {time}. Please fill out your email address for verification purposes.", "description": "Appointment cancellation body text", @@ -1039,11 +1144,21 @@ "description": "Appointments: product amount field label", "originalDefault": "Amount" }, + "vfKvuS": { + "defaultMessage": "Click first point to finish shape", + "description": "Draw handler polygon tooltip end.", + "originalDefault": "Click first point to finish shape" + }, "wwsWUp": { "defaultMessage": "How do you rate this form?", "description": "GovMetric snippet header", "originalDefault": "How do you rate this form?" }, + "xh+7Vv": { + "defaultMessage": "Finish", + "description": "Draw toolbar finish button message.", + "originalDefault": "Finish" + }, "y31iyC": { "defaultMessage": "Invalid literal value, expected {expected}.", "description": "ZOD 'invalid_literal' error message", @@ -1059,6 +1174,11 @@ "description": "Back to main website link title", "originalDefault": "Return to main website" }, + "zpHAro": { + "defaultMessage": "Click to start drawing line", + "description": "Draw handler polyline tooltip start.", + "originalDefault": "Click to start drawing line" + }, "zvoXSU": { "defaultMessage": "Nearest address:
", "description": "Reverse geocoded address result display", diff --git a/src/i18n/messages/nl.json b/src/i18n/messages/nl.json index 4ef35f536..b2e835870 100644 --- a/src/i18n/messages/nl.json +++ b/src/i18n/messages/nl.json @@ -9,11 +9,26 @@ "description": "Form save modal body text", "originalDefault": "Enter your email address to get an email to resume the form at a later date. This can be done on any device where you open the link. The link remains valid for {numberOfDays, plural, one {1 day} other {{numberOfDays} days}}." }, + "+KBbXH": { + "defaultMessage": "Klik om een veelhoek (polygoon) te tekenen", + "description": "Draw handler polygon tooltip start.", + "originalDefault": "Click to start drawing shape" + }, + "+W79Dr": { + "defaultMessage": "Klik om verder te tekenen", + "description": "Draw handler polyline tooltip continue.", + "originalDefault": "Click to continue drawing line" + }, "+uwsgF": { "defaultMessage": "Afspraakdetails", "description": "Appointments navbar title for 'location and time' step", "originalDefault": "Location and time" }, + "/yX9Xl": { + "defaultMessage": "Tekeningen annuleren", + "description": "Draw toolbar cancel button tooltip.", + "originalDefault": "Cancel drawing" + }, "0j8tMq": { "defaultMessage": "Uitloggen", "description": "Log out button text", @@ -29,6 +44,11 @@ "description": "Co-sign auth option not available on form", "originalDefault": "Something went wrong while presenting the login option. Please contact the municipality." }, + "2D6ubj": { + "defaultMessage": "Lijn", + "description": "Draw toolbar polyline button tooltip.", + "originalDefault": "Line" + }, "2HHJrq": { "defaultMessage": "Ongeldige functie-argumenten", "description": "ZOD 'invalid_arguments' error message", @@ -59,6 +79,11 @@ "description": "(Async) select options loading message", "originalDefault": "Loading..." }, + "4ZOmtU": { + "defaultMessage": "Wijzigingen opslaan", + "description": "Edit toolbar save tooltip.", + "originalDefault": "Save changes" + }, "4gPdgK": { "defaultMessage": "Slecht", "description": "GovMetric rating text", @@ -69,6 +94,11 @@ "description": "Email verification: verify code button text", "originalDefault": "Verify" }, + "4ui8R+": { + "defaultMessage": "Klik het laatste punt om de lijn te voltooien", + "description": "Draw handler polyline tooltip end.", + "originalDefault": "Click last point to finish line" + }, "5uh2hS": { "defaultMessage": "Afspraak annuleren mislukt", "description": "Appointment cancellation error message", @@ -84,6 +114,11 @@ "description": "Check overview and co-sign", "originalDefault": "Check and co-sign submission" }, + "62SBjV": { + "defaultMessage": "Veelhoek (polygoon)", + "description": "Draw toolbar polygon button tooltip.", + "originalDefault": "Shape (polygon)" + }, "6GNK65": { "defaultMessage": "Je moet ingelogd zijn voor deze actie.", "description": "Authentication error message", @@ -216,6 +251,11 @@ "description": "Login button label", "originalDefault": "Login with {provider}" }, + "B/W1uC": { + "defaultMessage": "Verwijder vormen", + "description": "Edit toolbar remove button tooltip.", + "originalDefault": "Remove shapes" + }, "BL1Ehr": { "defaultMessage": "Ongeldig.", "description": "ZOD 'invalid_string' error message, regex validation", @@ -241,6 +281,11 @@ "description": "Maintenance mode message", "originalDefault": "This form is currently undergoing maintenance and can not be accessed at the moment." }, + "D6TdPW": { + "defaultMessage": "Klik op de kaart om een pin/punt te plaatsen", + "description": "Draw handler marker tooltip start.", + "originalDefault": "Click map to place marker" + }, "DBTNgI": { "defaultMessage": "d", "description": "Placeholder for day part of a date", @@ -369,6 +414,16 @@ "isTranslated": true, "originalDefault": "Inloggen bij deze organisatie is niet gelukt. Probeert u het later nog een keer. Lukt het nog steeds niet? Log in bij Mijn DigiD. Zo controleert u of uw DigiD goed werkt. Mogelijk is er een storing bij de organisatie waar u inlogt." }, + "HY6Irs": { + "defaultMessage": "Wijzigingen annuleren", + "description": "Edit toolbar cancel tooltip.", + "originalDefault": "Cancel changes" + }, + "HgLr1F": { + "defaultMessage": "Annuleer", + "description": "Draw toolbar cancel button message.", + "originalDefault": "Cancel" + }, "HhcSoc": { "defaultMessage": "Opslaan en later verdergaan", "description": "Form save modal title", @@ -379,6 +434,11 @@ "description": "ZOD 'too_big' error message, generic", "originalDefault": "Invalid input." }, + "Hkq6NE": { + "defaultMessage": "Tekening voltooien", + "description": "Draw toolbar finish button tooltip.", + "originalDefault": "Finish drawing" + }, "I6ok5N": { "defaultMessage": "Ongeldig{validation, select, email { e-mailadres} url {e URL} datetime {e datumtijd} ip { IP address} other { validation} }.", "description": "ZOD 'invalid_string' error message, validation other than regex", @@ -491,11 +551,21 @@ "description": "Payment page title", "originalDefault": "Payment" }, + "N2sZnS": { + "defaultMessage": "Opslaan", + "description": "Edit toolbar save message.", + "originalDefault": "Save" + }, "OnfuIr": { "defaultMessage": "{withAsterisk, select, true {} other { (niet verplicht)}}", "description": "Form field label, field not required", "originalDefault": "{withAsterisk, select, true {} other { (not required)}}" }, + "Op4orj": { + "defaultMessage": "Geen vormen om te verwijderen", + "description": "Edit toolbar remove button disabled tooltip.", + "originalDefault": "No shapes to remove" + }, "P194bo": { "defaultMessage": "De ingevoerde waarde moet beginnen met \"{startsWith}\".", "description": "ZOD 'invalid_string' error message, with startsWith", @@ -511,6 +581,11 @@ "description": "ZOD 'too_small' error message, generic", "originalDefault": "Invalid input." }, + "Q6/Lj7": { + "defaultMessage": "Verwijder het laatst getekende punt", + "description": "Draw toolbar undo button tooltip.", + "originalDefault": "Remove last drawn point" + }, "QPdaOi": { "defaultMessage": "Geen beschikbare keuzes", "description": "Select 'no options' message", @@ -581,6 +656,11 @@ "description": "ZOD 'too_small' error message, for strings", "originalDefault": "String must contain {exact, select, true {exactly} other {{inclusive, select, true {at least} other {more than}}} } {minimum, plural, one {{minimum} character} other {{minimum} characters}}." }, + "U5+FHP": { + "defaultMessage": "Annuleer", + "description": "Edit toolbar cancel message.", + "originalDefault": "Cancel" + }, "UyEKdQ": { "defaultMessage": "Product {number}/{total}", "description": "Appointments: single product label/header", @@ -627,6 +707,11 @@ "description": "ZOD 'too_big' error message, for dates", "originalDefault": "Date must be smaller than or equal to {maximum}." }, + "Y3jHZm": { + "defaultMessage": "Verwijder laatste punt", + "description": "Draw toolbar undo button message.", + "originalDefault": "Remove last point" + }, "YcC4PD": { "defaultMessage": "Taal kiezen", "description": "Language selection heading", @@ -678,6 +763,11 @@ "description": "Appointments: contact details step title", "originalDefault": "Contact details" }, + "bRtoG6": { + "defaultMessage": "Verwijder alles", + "description": "Edit toolbar clearAll message.", + "originalDefault": "Remove all" + }, "bgfiRG": { "defaultMessage": "Je hebt de betaling gestart.", "description": "payment started status", @@ -713,6 +803,11 @@ "description": "return to form start link after 403", "originalDefault": "Back to form start" }, + "dNGw+S": { + "defaultMessage": "Klik om verder te tekenen", + "description": "Draw handler polygon tooltip continue.", + "originalDefault": "Click to continue drawing shape" + }, "eAmrdi": { "defaultMessage": "Laden...", "description": "Loading content text", @@ -728,6 +823,11 @@ "description": "Checking background processing status title", "originalDefault": "Processing..." }, + "fJVa0u": { + "defaultMessage": "Pin/punt", + "description": "Draw toolbar marker button tooltip.", + "originalDefault": "Marker" + }, "fWjfVm": { "defaultMessage": "Een moment geduld alstublieft. De inzending wordt verwerkt.", "description": "Checking background processing status body", @@ -1001,6 +1101,11 @@ "description": "The leaflet map's input fields placeholder message.", "originalDefault": "Enter address, please" }, + "sYb+eZ": { + "defaultMessage": "Verwijder alle vormen van de kaart", + "description": "Edit toolbar clearAll tooltip.", + "originalDefault": "Remove all shapes" + }, "senRv3": { "defaultMessage": "Je staat op het punt je afspraak op {date} om {time} te annuleren. Vul je e-mailadres in ter controle.", "description": "Appointment cancellation body text", @@ -1051,11 +1156,21 @@ "description": "Appointments: product amount field label", "originalDefault": "Amount" }, + "vfKvuS": { + "defaultMessage": "Klik op het eerste punt, om de veelhoek te voltooien", + "description": "Draw handler polygon tooltip end.", + "originalDefault": "Click first point to finish shape" + }, "wwsWUp": { "defaultMessage": "Wat vind je van dit formulier?", "description": "GovMetric snippet header", "originalDefault": "How do you rate this form?" }, + "xh+7Vv": { + "defaultMessage": "Voltooi", + "description": "Draw toolbar finish button message.", + "originalDefault": "Finish" + }, "y31iyC": { "defaultMessage": "Ongeldige letterlijke waarde, verwachtte {expected}.", "description": "ZOD 'invalid_literal' error message", @@ -1071,6 +1186,11 @@ "description": "Back to main website link title", "originalDefault": "Return to main website" }, + "zpHAro": { + "defaultMessage": "Klik om een lijk te tekenen", + "description": "Draw handler polyline tooltip start.", + "originalDefault": "Click to start drawing line" + }, "zvoXSU": { "defaultMessage": "Adres in de buurt:
", "description": "Reverse geocoded address result display", diff --git a/src/map/constants.js b/src/map/constants.js index dd7cd2f6b..82ad32d79 100644 --- a/src/map/constants.js +++ b/src/map/constants.js @@ -6,5 +6,10 @@ import {CRS_RD, TILE_LAYER_RD} from '@open-formulieren/leaflet-tools'; // Roughly the center of the Netherlands const DEFAULT_LAT_LNG = [52.1326332, 5.291266]; const DEFAULT_ZOOM = 13; +const DEFAULT_INTERACTIONS = { + marker: true, + polygon: false, + polyline: false, +}; -export {CRS_RD, DEFAULT_LAT_LNG, DEFAULT_ZOOM, TILE_LAYER_RD}; +export {CRS_RD, DEFAULT_LAT_LNG, DEFAULT_ZOOM, DEFAULT_INTERACTIONS, TILE_LAYER_RD};