From a12a9540c65bc1a45d846866924b57c9e53f4f80 Mon Sep 17 00:00:00 2001 From: robinvandermolen Date: Tue, 3 Dec 2024 18:05:15 +0100 Subject: [PATCH 1/6] :sparkles: [open-formulieren/open-forms#2177] added interaction configuration --- src/registry/map/edit.tsx | 11 +- .../map/interaction-configuration.tsx | 101 ++++++++++++++++++ 2 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 src/registry/map/interaction-configuration.tsx diff --git a/src/registry/map/edit.tsx b/src/registry/map/edit.tsx index 4ce73b1..11fab45 100644 --- a/src/registry/map/edit.tsx +++ b/src/registry/map/edit.tsx @@ -23,6 +23,7 @@ import { import {LABELS} from '@/components/builder/messages'; import {Checkbox, Select, TabList, TabPanel, Tabs} from '@/components/formio'; import {BuilderContext} from '@/context'; +import InteractionConfiguration from '@/registry/map/interaction-configuration'; import {useErrorChecker} from '@/utils/errors'; import {EditFormDefinition} from '../types'; @@ -65,7 +66,8 @@ const EditForm: EditFormDefinition = () => { 'useConfigDefaultMapSettings', 'defaultZoom', 'initialCenter', - 'tileLayerIdentifier' + 'tileLayerIdentifier', + 'interactions' )} /> @@ -87,6 +89,7 @@ const EditForm: EditFormDefinition = () => { {!values.useConfigDefaultMapSettings && } + {/* Advanced tab */} @@ -139,6 +142,12 @@ EditForm.defaultValues = { lng: undefined, }, tileLayerIdentifier: undefined, + interactions: { + circle: false, + polygon: false, + polyline: false, + marker: true, + }, defaultValue: null, // Advanced tab conditional: { diff --git a/src/registry/map/interaction-configuration.tsx b/src/registry/map/interaction-configuration.tsx new file mode 100644 index 0000000..90abb9e --- /dev/null +++ b/src/registry/map/interaction-configuration.tsx @@ -0,0 +1,101 @@ +import {FormattedMessage, useIntl} from 'react-intl'; + +import {Checkbox, Panel} from '@/components/formio'; + +const CircleInteraction: React.FC = () => { + const intl = useIntl(); + const tooltip = intl.formatMessage({ + description: "Tooltip for 'interactions.circle' builder field", + defaultMessage: 'Allowing users to draw a circle when using the map component', + }); + return ( + + } + tooltip={tooltip} + /> + ); +}; + +const PolygonInteraction: React.FC = () => { + const intl = useIntl(); + const tooltip = intl.formatMessage({ + description: "Tooltip for 'interactions.polygon' builder field", + defaultMessage: 'Allowing users to draw a polygon when using the map component', + }); + return ( + + } + tooltip={tooltip} + /> + ); +}; + +const PolylineInteraction: React.FC = () => { + const intl = useIntl(); + const tooltip = intl.formatMessage({ + description: "Tooltip for 'interactions.polyline' builder field", + defaultMessage: 'Allowing users to draw a line when using the map component', + }); + return ( + + } + tooltip={tooltip} + /> + ); +}; + +const MarkerInteraction: React.FC = () => { + const intl = useIntl(); + const tooltip = intl.formatMessage({ + description: "Tooltip for 'interactions.marker' builder field", + defaultMessage: 'Allowing users to set a marker when using the map component', + }); + return ( + + } + tooltip={tooltip} + /> + ); +}; + +const InteractionConfiguration: React.FC = () => ( + + } + > + + + + + +); + +export default InteractionConfiguration; From 759d5e98752378e489646fd336d95b03a5869f03 Mon Sep 17 00:00:00 2001 From: robinvandermolen Date: Thu, 12 Dec 2024 15:18:15 +0100 Subject: [PATCH 2/6] :arrow_up: [open-formulieren/open-forms#2177] Upgraded open-forms types --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index dab6066..57ab70b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -39,7 +39,7 @@ "@formatjs/cli": "^6.1.1", "@formatjs/ts-transformer": "^3.12.0", "@fortawesome/fontawesome-free": "^6.4.0", - "@open-formulieren/types": "^0.37.0", + "@open-formulieren/types": "^0.38.0", "@storybook/addon-actions": "^8.3.5", "@storybook/addon-essentials": "^8.3.5", "@storybook/addon-interactions": "^8.3.5", @@ -5087,9 +5087,9 @@ } }, "node_modules/@open-formulieren/types": { - "version": "0.37.0", - "resolved": "https://registry.npmjs.org/@open-formulieren/types/-/types-0.37.0.tgz", - "integrity": "sha512-8lgFytKGV9AeoUQ1oaYZcsoZoyWe/KoFJKkp66V8QQ9pd/IUt6i92VzTZSOqRr0D3kuMGf7aChXEJOhnaEcWSA==", + "version": "0.38.0", + "resolved": "https://registry.npmjs.org/@open-formulieren/types/-/types-0.38.0.tgz", + "integrity": "sha512-fvv+bl4Bl9/JgwxDj1MUyDXdSFW97BfT1+LZw7lMNlSbjdFoxMJeVUXQ0W46hptV2V40i7Ooh9U6J/28GmDYFQ==", "dev": true, "license": "EUPL-1.2" }, @@ -24611,9 +24611,9 @@ } }, "@open-formulieren/types": { - "version": "0.37.0", - "resolved": "https://registry.npmjs.org/@open-formulieren/types/-/types-0.37.0.tgz", - "integrity": "sha512-8lgFytKGV9AeoUQ1oaYZcsoZoyWe/KoFJKkp66V8QQ9pd/IUt6i92VzTZSOqRr0D3kuMGf7aChXEJOhnaEcWSA==", + "version": "0.38.0", + "resolved": "https://registry.npmjs.org/@open-formulieren/types/-/types-0.38.0.tgz", + "integrity": "sha512-fvv+bl4Bl9/JgwxDj1MUyDXdSFW97BfT1+LZw7lMNlSbjdFoxMJeVUXQ0W46hptV2V40i7Ooh9U6J/28GmDYFQ==", "dev": true }, "@pkgjs/parseargs": { diff --git a/package.json b/package.json index 34b7ed4..093409a 100644 --- a/package.json +++ b/package.json @@ -66,7 +66,7 @@ "@formatjs/cli": "^6.1.1", "@formatjs/ts-transformer": "^3.12.0", "@fortawesome/fontawesome-free": "^6.4.0", - "@open-formulieren/types": "^0.37.0", + "@open-formulieren/types": "^0.38.0", "@storybook/addon-actions": "^8.3.5", "@storybook/addon-essentials": "^8.3.5", "@storybook/addon-interactions": "^8.3.5", From e7254fd4a0199d04482347fec6d3183f76f4e1a4 Mon Sep 17 00:00:00 2001 From: robinvandermolen Date: Mon, 16 Dec 2024 09:49:57 +0100 Subject: [PATCH 3/6] :globe_with_meridians: [open-formulieren/open-forms#2177] Map interaction translations --- i18n/messages/en.json | 45 +++++++++++++++++++++++++++++++++++++++++++ i18n/messages/nl.json | 45 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) diff --git a/i18n/messages/en.json b/i18n/messages/en.json index 0c878b2..e3c63bb 100644 --- a/i18n/messages/en.json +++ b/i18n/messages/en.json @@ -149,6 +149,11 @@ "description": "Label for 'customClass' builder field", "originalDefault": "CSS class" }, + "3xnsUT": { + "defaultMessage": "Line interactions", + "description": "Label for 'interactions.polyline' builder field", + "originalDefault": "Line interactions" + }, "4/cCvG": { "defaultMessage": "Location", "description": "Component edit form tab title for 'Location' tab", @@ -564,6 +569,11 @@ "description": "Label for 'disableAddingRemovingRows' builder field", "originalDefault": "Disable adding or removing groups" }, + "NbDr3m": { + "defaultMessage": "Allowing users to draw a line when using the map component", + "description": "Tooltip for 'interactions.polyline' builder field", + "originalDefault": "Allowing users to draw a line when using the map component" + }, "NdaqDN": { "defaultMessage": "Option description ()", "description": "Label for option description location", @@ -589,6 +599,16 @@ "description": "Component property 'Label' label", "originalDefault": "Label" }, + "P84Gif": { + "defaultMessage": "Allowing users to draw a circle when using the map component", + "description": "Tooltip for 'interactions.circle' builder field", + "originalDefault": "Allowing users to draw a circle when using the map component" + }, + "POkaFQ": { + "defaultMessage": "Polygon interactions", + "description": "Label for 'interactions.polygon' builder field", + "originalDefault": "Polygon interactions" + }, "PhXIai": { "defaultMessage": "Number of years. Empty values are ignored.", "description": "Tooltip for 'delta.years' in relative delta date constraint validation", @@ -874,6 +894,16 @@ "description": "Tooltip for 'includePartners' builder field", "originalDefault": "Whether to add partners information to the component." }, + "ZRM6J8": { + "defaultMessage": "Available map interactions", + "description": "Interaction configuration panel title", + "originalDefault": "Available map interactions" + }, + "ZXsJ9p": { + "defaultMessage": "Circle interactions", + "description": "Label for 'interactions.circle' builder field", + "originalDefault": "Circle interactions" + }, "aBADYT": { "defaultMessage": "Maximum number of files", "description": "Label for 'maxNumberOfFiles' builder field", @@ -1144,6 +1174,11 @@ "description": "Label for 'ClearOnHide' builder field", "originalDefault": "Clear on hide" }, + "iyWQAt": { + "defaultMessage": "Allowing users to draw a polygon when using the map component", + "description": "Tooltip for 'interactions.polygon' builder field", + "originalDefault": "Allowing users to draw a polygon when using the map component" + }, "j2vQH3": { "defaultMessage": "Values", "description": "Label for the 'values' builder field", @@ -1184,6 +1219,11 @@ "description": "Label for translation message for validation error code", "originalDefault": "Error message" }, + "kIX7bm": { + "defaultMessage": "Marker interactions", + "description": "Label for 'interactions.marker' builder field", + "originalDefault": "Marker interactions" + }, "kg/eh1": { "defaultMessage": "Choice/option translations", "description": "Values/options translations table header", @@ -1444,6 +1484,11 @@ "description": "Tooltip for 'hideHeader' builder field", "originalDefault": "Do not display the configured label and top line as the header in the fieldset." }, + "vFydxX": { + "defaultMessage": "Allowing users to set a marker when using the map component", + "description": "Tooltip for 'interactions.marker' builder field", + "originalDefault": "Allowing users to set a marker when using the map component" + }, "vRVMpe": { "defaultMessage": "Value", "description": "Translations: property column header", diff --git a/i18n/messages/nl.json b/i18n/messages/nl.json index 692b6b3..a44e64c 100644 --- a/i18n/messages/nl.json +++ b/i18n/messages/nl.json @@ -151,6 +151,11 @@ "isTranslated": true, "originalDefault": "CSS class" }, + "3xnsUT": { + "defaultMessage": "Lijn interacties", + "description": "Label for 'interactions.polyline' builder field", + "originalDefault": "Line interactions" + }, "4/cCvG": { "defaultMessage": "Locatie", "description": "Component edit form tab title for 'Location' tab", @@ -572,6 +577,11 @@ "description": "Label for 'disableAddingRemovingRows' builder field", "originalDefault": "Disable adding or removing groups" }, + "NbDr3m": { + "defaultMessage": "Geeft gebruikers de mogelijkheid een lijn te tekenen, wanneer ze met het kaartmateriaal werken", + "description": "Tooltip for 'interactions.polyline' builder field", + "originalDefault": "Allowing users to draw a line when using the map component" + }, "NdaqDN": { "defaultMessage": "Waarde-omschrijving ()", "description": "Label for option description location", @@ -598,6 +608,16 @@ "isTranslated": true, "originalDefault": "Label" }, + "P84Gif": { + "defaultMessage": "Geeft gebruikers de mogelijkheid een cirkel te tekenen, wanneer ze met het kaartmateriaal werken", + "description": "Tooltip for 'interactions.circle' builder field", + "originalDefault": "Allowing users to draw a circle when using the map component" + }, + "POkaFQ": { + "defaultMessage": "Polygoon interacties", + "description": "Label for 'interactions.polygon' builder field", + "originalDefault": "Polygon interactions" + }, "PhXIai": { "defaultMessage": "Aantal jaren. Lege waarden worden genegeerd.", "description": "Tooltip for 'delta.years' in relative delta date constraint validation", @@ -885,6 +905,16 @@ "description": "Tooltip for 'includePartners' builder field", "originalDefault": "Whether to add partners information to the component." }, + "ZRM6J8": { + "defaultMessage": "Mogelijke kaartmateriaal interacties", + "description": "Interaction configuration panel title", + "originalDefault": "Available map interactions" + }, + "ZXsJ9p": { + "defaultMessage": "Cirkel interacties", + "description": "Label for 'interactions.circle' builder field", + "originalDefault": "Circle interactions" + }, "aBADYT": { "defaultMessage": "Maximum aantal bestanden", "description": "Label for 'maxNumberOfFiles' builder field", @@ -1158,6 +1188,11 @@ "description": "Label for 'ClearOnHide' builder field", "originalDefault": "Clear on hide" }, + "iyWQAt": { + "defaultMessage": "Geeft gebruikers de mogelijkheid een polygoon te tekenen, wanneer ze met het kaartmateriaal werken", + "description": "Tooltip for 'interactions.polygon' builder field", + "originalDefault": "Allowing users to draw a polygon when using the map component" + }, "j2vQH3": { "defaultMessage": "Waarden", "description": "Label for the 'values' builder field", @@ -1199,6 +1234,11 @@ "description": "Label for translation message for validation error code", "originalDefault": "Error message" }, + "kIX7bm": { + "defaultMessage": "Pin interacties", + "description": "Label for 'interactions.marker' builder field", + "originalDefault": "Marker interactions" + }, "kg/eh1": { "defaultMessage": "Waardenvertalingen", "description": "Values/options translations table header", @@ -1464,6 +1504,11 @@ "description": "Tooltip for 'hideHeader' builder field", "originalDefault": "Do not display the configured label and top line as the header in the fieldset." }, + "vFydxX": { + "defaultMessage": "Geeft gebruikers de mogelijkheid een pin te plaatsen, wanneer ze met het kaartmateriaal werken", + "description": "Tooltip for 'interactions.marker' builder field", + "originalDefault": "Allowing users to set a marker when using the map component" + }, "vRVMpe": { "defaultMessage": "(Standaard)tekst", "description": "Translations: property column header", From ad322ba44d2c32eb508bce79c65206e9adbbf4e5 Mon Sep 17 00:00:00 2001 From: robinvandermolen Date: Wed, 18 Dec 2024 14:31:55 +0100 Subject: [PATCH 4/6] :heavy_plus_sign: [open-formulieren/open-forms#2177] Add leaflet-draw dependencies --- package-lock.json | 39 +++++++++++++++++++++++++++++++++++++++ package.json | 2 ++ 2 files changed, 41 insertions(+) diff --git a/package-lock.json b/package-lock.json index 57ab70b..7feaa67 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,9 +18,11 @@ "clsx": "^1.2.1", "formik": "^2.4.5", "leaflet": "^1.9.4", + "leaflet-draw": "^1.0.4", "lodash": "^4.17.21", "react-intl": "^6.3.2", "react-leaflet": "^4.2.1", + "react-leaflet-draw": "^0.20.4", "react-modal": "^3.16.1", "react-select": "^5.8.0", "react-signature-canvas": "^1.0.6", @@ -15850,6 +15852,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/leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -17772,6 +17780,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", @@ -32677,6 +32702,11 @@ "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz", "integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==" }, + "leaflet-draw": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/leaflet-draw/-/leaflet-draw-1.0.4.tgz", + "integrity": "sha512-rsQ6saQO5ST5Aj6XRFylr5zvarWgzWnrg46zQ1MEOEIHsppdC/8hnN8qMoFvACsPvTioAuysya/TVtog15tyAQ==" + }, "leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -34105,6 +34135,15 @@ "@react-leaflet/core": "^2.1.0" } }, + "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==", + "requires": { + "fast-deep-equal": "^3.1.3", + "lodash-es": "^4.17.15" + } + }, "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 093409a..0a9ea1b 100644 --- a/package.json +++ b/package.json @@ -124,9 +124,11 @@ "clsx": "^1.2.1", "formik": "^2.4.5", "leaflet": "^1.9.4", + "leaflet-draw": "^1.0.4", "lodash": "^4.17.21", "react-intl": "^6.3.2", "react-leaflet": "^4.2.1", + "react-leaflet-draw": "^0.20.4", "react-modal": "^3.16.1", "react-select": "^5.8.0", "react-signature-canvas": "^1.0.6", From 8ef3a1f7512a3e4ad3c3659c80f1b4e91ca9da1a Mon Sep 17 00:00:00 2001 From: robinvandermolen Date: Wed, 18 Dec 2024 14:32:33 +0100 Subject: [PATCH 5/6] :sparkles: [open-formulieren/open-forms#2177] Add map component interaction to preview --- src/jsonEditor.scss | 3 +++ src/registry/map/preview.tsx | 35 +++++++++++++++++++++++++++++++---- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/jsonEditor.scss b/src/jsonEditor.scss index 53f87d6..13285db 100644 --- a/src/jsonEditor.scss +++ b/src/jsonEditor.scss @@ -1,3 +1,6 @@ +@import 'leaflet-draw/dist/leaflet.draw.css'; +@import 'leaflet/dist/leaflet.css'; + .json-editor { min-block-size: 45vh; diff --git a/src/registry/map/preview.tsx b/src/registry/map/preview.tsx index b52dbe9..b0a17c3 100644 --- a/src/registry/map/preview.tsx +++ b/src/registry/map/preview.tsx @@ -1,14 +1,15 @@ import {CRS_RD, TILE_LAYER_RD} from '@open-formulieren/leaflet-tools'; import {MapComponentSchema} from '@open-formulieren/types'; -import {useContext, useLayoutEffect} from 'react'; -import {MapContainer, TileLayer, useMap} from 'react-leaflet'; +import type {FeatureGroup as LeafletFeatureGroup} from 'leaflet'; +import {useContext, useLayoutEffect, useRef} from 'react'; +import {FeatureGroup, MapContainer, TileLayer, useMap} from 'react-leaflet'; +import {EditControl} from 'react-leaflet-draw'; import useAsync from 'react-use/esm/useAsync'; import Loader from '@/components/builder/loader'; import {Component, Description} from '@/components/formio'; import {BuilderContext} from '@/context'; - -import {ComponentPreviewProps} from '../types'; +import {ComponentPreviewProps} from '@/registry/types'; interface MapViewProps { lat: number; @@ -41,8 +42,10 @@ const Preview: React.FC> = ({component defaultZoom, initialCenter = {}, tileLayerIdentifier, + interactions, } = component; const {getMapTileLayers} = useContext(BuilderContext); + const featureGroupRef = useRef(null); const {value: tileLayers, loading, error} = useAsync(async () => await getMapTileLayers(), []); if (error) { throw error; @@ -63,6 +66,12 @@ const Preview: React.FC> = ({component TILE_LAYER_RD.url ); }; + + const onFeatureCreate = (event: any) => { + featureGroupRef.current?.clearLayers(); + featureGroupRef.current?.addLayer(event.layer); + }; + return ( > = ({component }} > + + + {description && } From 72b3cc2c47deb62f7c49b8f3fcd0324a927166b6 Mon Sep 17 00:00:00 2001 From: robinvandermolen Date: Wed, 18 Dec 2024 15:21:36 +0100 Subject: [PATCH 6/6] :construction_worker: [open-formulieren/open-forms#2177] Update build scripts Both changes are needed for the leaflet-draw and react-leaflet-draw dependencies. leaflet-draw uses images for the different markers, which are included in the css. For this to work with the scss build, .png and .svg files use the dataurl loader https://esbuild.github.io/content-types/#data-url Typescript errors in the react-leaflet-draw dependency caused a typescript validation/error, which shouldn't happen. Using `skipLibCheck` in the tsconfig.json type issues in the node_modules folder are ignored --- bundle-scss.mjs | 4 ++++ tsconfig.json | 1 + 2 files changed, 5 insertions(+) diff --git a/bundle-scss.mjs b/bundle-scss.mjs index ac68b6b..a0a90f5 100644 --- a/bundle-scss.mjs +++ b/bundle-scss.mjs @@ -5,6 +5,10 @@ await esbuild.build({ entryPoints: ['src/index.ts'], outdir: 'lib/css', bundle: true, + loader: { + ".png": "dataurl", + ".svg": "dataurl", + }, minify: false, sourcemap: true, plugins: [sassPlugin()], diff --git a/tsconfig.json b/tsconfig.json index 589fe44..cc81f0c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -18,6 +18,7 @@ "strictNullChecks": true, "allowSyntheticDefaultImports": true, "noErrorTruncation": true, + "skipLibCheck": true, "paths": { "@/*": ["./*"], "@/sb-decorators": ["../.storybook/decorators.tsx"]