diff options
author | Anton Tananaev <anton@traccar.org> | 2022-08-01 09:08:48 -0700 |
---|---|---|
committer | Anton Tananaev <anton@traccar.org> | 2022-08-01 09:08:48 -0700 |
commit | 027f56866f4584debdef22792f0b9f1d7a545faf (patch) | |
tree | 7fe236975d3b3d8bf4eda8f41548c58cf51ede00 | |
parent | 04385204c0ee230f73615224955b2b8b7a7d9c73 (diff) | |
download | trackermap-web-027f56866f4584debdef22792f0b9f1d7a545faf.tar.gz trackermap-web-027f56866f4584debdef22792f0b9f1d7a545faf.tar.bz2 trackermap-web-027f56866f4584debdef22792f0b9f1d7a545faf.zip |
Quick geofence creation
-rw-r--r-- | modern/src/main/StatusCard.js | 29 | ||||
-rw-r--r-- | modern/src/settings/GeofencePage.js | 12 | ||||
-rw-r--r-- | web/l10n/en.json | 1 |
3 files changed, 38 insertions, 4 deletions
diff --git a/modern/src/main/StatusCard.js b/modern/src/main/StatusCard.js index 1e7b241b..373b02ab 100644 --- a/modern/src/main/StatusCard.js +++ b/modern/src/main/StatusCard.js @@ -30,7 +30,7 @@ import { useDeviceReadonly, useRestriction } from '../common/util/permissions'; import usePersistedState from '../common/util/usePersistedState'; import usePositionAttributes from '../common/attributes/usePositionAttributes'; import { devicesActions } from '../store'; -import { useCatch } from '../reactHelper'; +import { useCatch, useCatchCallback } from '../reactHelper'; const useStyles = makeStyles((theme) => ({ card: { @@ -126,6 +126,32 @@ const StatusCard = ({ deviceId, onClose }) => { setRemoving(false); }); + const handleGeofence = useCatchCallback(async () => { + const newItem = { + name: '', + area: `CIRCLE (${position.latitude} ${position.longitude}, 50)`, + }; + const response = await fetch('/api/geofences', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(newItem), + }); + if (response.ok) { + const item = await response.json(); + const permissionResponse = await fetch('/api/permissions', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ deviceId: position.deviceId, geofenceId: item.id }), + }); + if (!permissionResponse.ok) { + throw Error(await permissionResponse.text()); + } + navigate(`/settings/geofence/${item.id}`); + } else { + throw Error(await response.text()); + } + }, [navigate]); + return ( <> {device && ( @@ -209,6 +235,7 @@ const StatusCard = ({ deviceId, onClose }) => { {position && ( <Menu anchorEl={anchorEl} open={Boolean(anchorEl)} onClose={() => setAnchorEl(null)}> <MenuItem onClick={() => navigate(`/position/${position.id}`)}><Typography color="secondary">{t('sharedShowDetails')}</Typography></MenuItem> + <MenuItem onClick={handleGeofence}>{t('sharedCreateGeofence')}</MenuItem> <MenuItem component="a" target="_blank" href={`https://www.google.com/maps/search/?api=1&query=${position.latitude}%2C${position.longitude}`}>{t('linkGoogleMaps')}</MenuItem> <MenuItem component="a" target="_blank" href={`http://maps.apple.com/?ll=${position.latitude},${position.longitude}`}>{t('linkAppleMaps')}</MenuItem> <MenuItem component="a" target="_blank" href={`https://www.google.com/maps/@?api=1&map_action=pano&viewpoint=${position.latitude}%2C${position.longitude}&heading=${position.course}`}>{t('linkStreetView')}</MenuItem> diff --git a/modern/src/settings/GeofencePage.js b/modern/src/settings/GeofencePage.js index 3bebea30..b6c516a1 100644 --- a/modern/src/settings/GeofencePage.js +++ b/modern/src/settings/GeofencePage.js @@ -1,8 +1,7 @@ import React, { useState } from 'react'; -import TextField from '@mui/material/TextField'; - +import { useDispatch } from 'react-redux'; import { - Accordion, AccordionSummary, AccordionDetails, Typography, + Accordion, AccordionSummary, AccordionDetails, Typography, TextField, } from '@mui/material'; import makeStyles from '@mui/styles/makeStyles'; import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; @@ -12,6 +11,7 @@ import { useTranslation } from '../common/components/LocalizationProvider'; import useGeofenceAttributes from '../common/attributes/useGeofenceAttributes'; import SettingsMenu from './components/SettingsMenu'; import SelectField from '../common/components/SelectField'; +import { geofencesActions } from '../store'; const useStyles = makeStyles((theme) => ({ details: { @@ -24,12 +24,17 @@ const useStyles = makeStyles((theme) => ({ const GeofencePage = () => { const classes = useStyles(); + const dispatch = useDispatch(); const t = useTranslation(); const geofenceAttributes = useGeofenceAttributes(t); const [item, setItem] = useState(); + const onItemSaved = (result) => { + dispatch(geofencesActions.update([result])); + }; + const validate = () => item && item.name; return ( @@ -38,6 +43,7 @@ const GeofencePage = () => { item={item} setItem={setItem} validate={validate} + onItemSaved={onItemSaved} menu={<SettingsMenu />} breadcrumbs={['settingsTitle', 'sharedGeofence']} > diff --git a/web/l10n/en.json b/web/l10n/en.json index 2549a081..3a7be25d 100644 --- a/web/l10n/en.json +++ b/web/l10n/en.json @@ -33,6 +33,7 @@ "sharedSearch": "Search", "sharedGeofence": "Geofence", "sharedGeofences": "Geofences", + "sharedCreateGeofence": "Create Geofence", "sharedNotifications": "Notifications", "sharedNotification": "Notification", "sharedAttributes": "Attributes", |