diff options
author | Anton Tananaev <anton@traccar.org> | 2022-06-11 18:32:36 -0700 |
---|---|---|
committer | Anton Tananaev <anton@traccar.org> | 2022-06-11 18:32:36 -0700 |
commit | e7995f3b7a6b0828b81bebaf556ef7afb59bef61 (patch) | |
tree | bd9aebc2ed24253ca0bb2a604ac65ae96730a3d1 /modern | |
parent | 0aecbc3bf856b17f42e363eff2bac4fb0ce1f7ed (diff) | |
download | trackermap-web-e7995f3b7a6b0828b81bebaf556ef7afb59bef61.tar.gz trackermap-web-e7995f3b7a6b0828b81bebaf556ef7afb59bef61.tar.bz2 trackermap-web-e7995f3b7a6b0828b81bebaf556ef7afb59bef61.zip |
Automatically add map keys
Diffstat (limited to 'modern')
-rw-r--r-- | modern/src/common/attributes/useCommonUserAttributes.js | 12 | ||||
-rw-r--r-- | modern/src/map/core/useMapStyles.js | 7 | ||||
-rw-r--r-- | modern/src/settings/PreferencesPage.js | 32 | ||||
-rw-r--r-- | modern/src/settings/UserPage.js | 26 | ||||
-rw-r--r-- | modern/src/settings/components/EditAttributesView.js | 3 |
5 files changed, 60 insertions, 20 deletions
diff --git a/modern/src/common/attributes/useCommonUserAttributes.js b/modern/src/common/attributes/useCommonUserAttributes.js index c17b5c5d..c1c7d981 100644 --- a/modern/src/common/attributes/useCommonUserAttributes.js +++ b/modern/src/common/attributes/useCommonUserAttributes.js @@ -1,6 +1,18 @@ import { useMemo } from 'react'; export default (t) => useMemo(() => ({ + locationIqKey: { + name: t('mapLocationIqKey'), + type: 'string', + }, + mapboxAccessToken: { + name: t('mapMapboxKey'), + type: 'string', + }, + mapTilerKey: { + name: t('mapMapTilerKey'), + type: 'string', + }, notificationTokens: { name: t('attributeNotificationTokens'), type: 'string', diff --git a/modern/src/map/core/useMapStyles.js b/modern/src/map/core/useMapStyles.js index f635e15c..944cd3ea 100644 --- a/modern/src/map/core/useMapStyles.js +++ b/modern/src/map/core/useMapStyles.js @@ -78,12 +78,14 @@ export default () => { title: t('mapLocationIqEarth'), uri: styleLocationIq('earth', locationIqKey), available: !!locationIqKey, + attribute: 'locationIqKey', }, { id: 'locationIqHybrid', title: t('mapLocationIqHybrid'), uri: styleLocationIq('hybrid', locationIqKey), available: !!locationIqKey, + attribute: 'locationIqKey', }, { id: 'osm', @@ -102,30 +104,35 @@ export default () => { title: t('mapMapboxStreets'), uri: styleMapbox('streets-v11'), available: !!mapboxAccessToken, + attribute: 'mapboxAccessToken', }, { id: 'mapboxOutdoors', title: t('mapMapboxOutdoors'), uri: styleMapbox('outdoors-v11'), available: !!mapboxAccessToken, + attribute: 'mapboxAccessToken', }, { id: 'mapboxSatellite', title: t('mapMapboxSatellite'), uri: styleMapbox('satellite-v9'), available: !!mapboxAccessToken, + attribute: 'mapboxAccessToken', }, { id: 'mapTilerBasic', title: t('mapMapTilerBasic'), uri: styleMapTiler('basic', mapTilerKey), available: !!mapTilerKey, + attribute: 'mapTilerKey', }, { id: 'mapTilerHybrid', title: t('mapMapTilerHybrid'), uri: styleMapTiler('hybrid', mapTilerKey), available: !!mapTilerKey, + attribute: 'mapTilerKey', }, { id: 'custom', diff --git a/modern/src/settings/PreferencesPage.js b/modern/src/settings/PreferencesPage.js index c128e5e4..2a2674f7 100644 --- a/modern/src/settings/PreferencesPage.js +++ b/modern/src/settings/PreferencesPage.js @@ -1,17 +1,8 @@ import React from 'react'; +import { useSelector } from 'react-redux'; +import { useNavigate } from 'react-router-dom'; import { - Accordion, - AccordionSummary, - AccordionDetails, - Typography, - Container, - FormControl, - InputLabel, - Select, - MenuItem, - Checkbox, - FormControlLabel, - FormGroup, + Accordion, AccordionSummary, AccordionDetails, Typography, Container, FormControl, InputLabel, Select, MenuItem, Checkbox, FormControlLabel, FormGroup, } from '@mui/material'; import makeStyles from '@mui/styles/makeStyles'; import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; @@ -38,8 +29,11 @@ const useStyles = makeStyles((theme) => ({ const PreferencesPage = () => { const classes = useStyles(); + const navigate = useNavigate(); const t = useTranslation(); + const userId = useSelector((state) => state.session.user.id); + const { languages, language, setLanguage } = useLocalization(); const languageList = Object.entries(languages).map((values) => ({ code: values[0], name: values[1].name })); @@ -96,11 +90,21 @@ const PreferencesPage = () => { <Select label={t('mapActive')} value={activeMapStyles} - onChange={(e) => setActiveMapStyles(e.target.value)} + onChange={(e, child) => { + const clicked = mapStyles.find((s) => s.id === child.props.value); + if (clicked.available) { + setActiveMapStyles(e.target.value); + } else if (clicked.id !== 'custom') { + const query = new URLSearchParams({ attribute: clicked.attribute }); + navigate(`/settings/user/${userId}?${query.toString()}`); + } + }} multiple > {mapStyles.map((style) => ( - <MenuItem key={style.id} value={style.id}>{style.title}</MenuItem> + <MenuItem key={style.id} value={style.id}> + <Typography component="span" color={style.available ? 'textPrimary' : 'error'}>{style.title}</Typography> + </MenuItem> ))} </Select> </FormControl> diff --git a/modern/src/settings/UserPage.js b/modern/src/settings/UserPage.js index d4046fbf..964291e8 100644 --- a/modern/src/settings/UserPage.js +++ b/modern/src/settings/UserPage.js @@ -1,6 +1,4 @@ -import React, { useState } from 'react'; -import TextField from '@mui/material/TextField'; - +import React, { useEffect, useState } from 'react'; import { Accordion, AccordionSummary, @@ -16,6 +14,7 @@ import { IconButton, OutlinedInput, FormGroup, + TextField, } from '@mui/material'; import makeStyles from '@mui/styles/makeStyles'; import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; @@ -33,6 +32,7 @@ import SettingsMenu from './components/SettingsMenu'; import useCommonUserAttributes from '../common/attributes/useCommonUserAttributes'; import { useAdministrator, useManager } from '../common/util/permissions'; import { prefixString } from '../common/util/stringUtils'; +import useQuery from '../common/util/useQuery'; const useStyles = makeStyles((theme) => ({ details: { @@ -58,6 +58,21 @@ const UserPage = () => { const [item, setItem] = useState(); + const query = useQuery(); + const [queryHandled, setQueryHandled] = useState(false); + const attribute = query.get('attribute'); + + useEffect(() => { + if (!queryHandled && item && attribute) { + if (!item.attributes.hasOwnProperty('attribute')) { + const updatedAttributes = { ...item.attributes }; + updatedAttributes[attribute] = ''; + setItem({ ...item, attributes: updatedAttributes }); + } + setQueryHandled(true); + } + }, [item, queryHandled, setQueryHandled, attribute]); + const onItemSaved = (result) => { if (result.id === currentUserId) { dispatch(sessionActions.updateUser(result)); @@ -79,7 +94,7 @@ const UserPage = () => { > {item && ( <> - <Accordion defaultExpanded> + <Accordion defaultExpanded={!attribute}> <AccordionSummary expandIcon={<ExpandMoreIcon />}> <Typography variant="subtitle1"> {t('sharedRequired')} @@ -286,7 +301,7 @@ const UserPage = () => { </FormGroup> </AccordionDetails> </Accordion> - <Accordion> + <Accordion defaultExpanded={!!attribute}> <AccordionSummary expandIcon={<ExpandMoreIcon />}> <Typography variant="subtitle1"> {t('sharedAttributes')} @@ -297,6 +312,7 @@ const UserPage = () => { attributes={item.attributes} setAttributes={(attributes) => setItem({ ...item, attributes })} definitions={{ ...commonUserAttributes, ...userAttributes }} + focusAttribute={attribute} /> </AccordionDetails> </Accordion> diff --git a/modern/src/settings/components/EditAttributesView.js b/modern/src/settings/components/EditAttributesView.js index 6b7ab5ac..3329d7bc 100644 --- a/modern/src/settings/components/EditAttributesView.js +++ b/modern/src/settings/components/EditAttributesView.js @@ -27,7 +27,7 @@ const useStyles = makeStyles((theme) => ({ }, })); -const EditAttributesView = ({ attributes, setAttributes, definitions }) => { +const EditAttributesView = ({ attributes, setAttributes, definitions, focusAttribute }) => { const classes = useStyles(); const t = useTranslation(); @@ -176,6 +176,7 @@ const EditAttributesView = ({ attributes, setAttributes, definitions }) => { type={type === 'number' ? 'number' : 'text'} value={getDisplayValue(value, subtype)} onChange={(e) => updateAttribute(key, e.target.value, type, subtype)} + autoFocus={focusAttribute === key} endAdornment={( <InputAdornment position="end"> <IconButton size="small" onClick={() => deleteAttribute(key)}> |