aboutsummaryrefslogtreecommitdiff
path: root/modern/src/settings/PreferencesPage.js
diff options
context:
space:
mode:
authorAnton Tananaev <anton@traccar.org>2022-10-28 13:28:28 -0700
committerAnton Tananaev <anton@traccar.org>2022-10-28 13:28:28 -0700
commitfac80024e0956d543b762296e0ee49cd72035b93 (patch)
tree41074dddc57d0c4fdb1b7162b1c3d74633e4ea31 /modern/src/settings/PreferencesPage.js
parentef315b8e10329db80da1a97e96b3cc82481370ae (diff)
downloadtrackermap-web-fac80024e0956d543b762296e0ee49cd72035b93.tar.gz
trackermap-web-fac80024e0956d543b762296e0ee49cd72035b93.tar.bz2
trackermap-web-fac80024e0956d543b762296e0ee49cd72035b93.zip
Persist user preferences
Diffstat (limited to 'modern/src/settings/PreferencesPage.js')
-rw-r--r--modern/src/settings/PreferencesPage.js106
1 files changed, 44 insertions, 62 deletions
diff --git a/modern/src/settings/PreferencesPage.js b/modern/src/settings/PreferencesPage.js
index 9a2b37e7..5229a03c 100644
--- a/modern/src/settings/PreferencesPage.js
+++ b/modern/src/settings/PreferencesPage.js
@@ -9,8 +9,7 @@ import makeStyles from '@mui/styles/makeStyles';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import CachedIcon from '@mui/icons-material/Cached';
import ContentCopyIcon from '@mui/icons-material/ContentCopy';
-import { useLocalization, useTranslation, useTranslationKeys } from '../common/components/LocalizationProvider';
-import usePersistedState from '../common/util/usePersistedState';
+import { useTranslation, useTranslationKeys } from '../common/components/LocalizationProvider';
import PageLayout from '../common/components/PageLayout';
import SettingsMenu from './components/SettingsMenu';
import usePositionAttributes from '../common/attributes/usePositionAttributes';
@@ -64,25 +63,13 @@ const PreferencesPage = () => {
const user = useSelector((state) => state.session.user);
const [attributes, setAttributes] = useState(user.attributes);
- const { languages, language, setLanguage } = useLocalization();
- const languageList = Object.entries(languages).map((values) => ({ code: values[0], name: values[1].name }));
-
const [token, setToken] = useState(null);
const [tokenExpiration, setTokenExpiration] = useState(moment().add(1, 'week').locale('en').format(moment.HTML5_FMT.DATE));
const mapStyles = useMapStyles();
- const [activeMapStyles, setActiveMapStyles] = usePersistedState('activeMapStyles', ['locationIqStreets', 'osm', 'carto']);
-
const mapOverlays = useMapOverlays();
- const [selectedMapOverlay, setSelectedMapOverlay] = usePersistedState('selectedMapOverlay');
const positionAttributes = usePositionAttributes(t);
- const [positionItems, setPositionItems] = usePersistedState('positionItems', ['speed', 'address', 'totalDistance', 'course']);
-
- const [mapLiveRoutes, setMapLiveRoutes] = usePersistedState('mapLiveRoutes', false);
- const [mapFollow, setMapFollow] = usePersistedState('mapFollow', false);
- const [mapCluster, setMapCluster] = usePersistedState('mapCluster', true);
- const [mapOnSelect, setMapOnSelect] = usePersistedState('mapOnSelect', true);
const filter = createFilterOptions();
@@ -104,12 +91,6 @@ const PreferencesPage = () => {
name: t(it),
}));
- const [devicePrimary, setDevicePrimary] = usePersistedState('devicePrimary', 'name');
- const [deviceSecondary, setDeviceSecondary] = usePersistedState('deviceSecondary', '');
-
- const [soundEvents, setSoundEvents] = usePersistedState('soundEvents', []);
- const [soundAlarms, setSoundAlarms] = usePersistedState('soundAlarms', ['sos']);
-
const handleSave = useCatch(async () => {
const response = await fetch(`/api/users/${user.id}`, {
method: 'PUT',
@@ -130,25 +111,6 @@ const PreferencesPage = () => {
<Accordion defaultExpanded>
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
<Typography variant="subtitle1">
- {t('sharedPreferences')}
- </Typography>
- </AccordionSummary>
- <AccordionDetails className={classes.details}>
- <FormControl>
- <InputLabel>{t('loginLanguage')}</InputLabel>
- <Select
- label={t('loginLanguage')}
- value={language}
- onChange={(e) => setLanguage(e.target.value)}
- >
- {languageList.map((it) => <MenuItem key={it.code} value={it.code}>{it.name}</MenuItem>)}
- </Select>
- </FormControl>
- </AccordionDetails>
- </Accordion>
- <Accordion defaultExpanded>
- <AccordionSummary expandIcon={<ExpandMoreIcon />}>
- <Typography variant="subtitle1">
{t('userToken')}
</Typography>
</AccordionSummary>
@@ -196,11 +158,11 @@ const PreferencesPage = () => {
<InputLabel>{t('mapActive')}</InputLabel>
<Select
label={t('mapActive')}
- value={activeMapStyles}
+ value={attributes.activeMapStyles?.split(',') || ['locationIqStreets', 'osm', 'carto']}
onChange={(e, child) => {
const clicked = mapStyles.find((s) => s.id === child.props.value);
if (clicked.available) {
- setActiveMapStyles(e.target.value);
+ setAttributes({ ...attributes, activeMapStyles: e.target.value.join(',') });
} else if (clicked.id !== 'custom') {
const query = new URLSearchParams({ attribute: clicked.attribute });
navigate(`/settings/user/${user.id}?${query.toString()}`);
@@ -219,11 +181,11 @@ const PreferencesPage = () => {
<InputLabel>{t('mapOverlay')}</InputLabel>
<Select
label={t('mapOverlay')}
- value={selectedMapOverlay}
+ value={attributes.selectedMapOverlay}
onChange={(e) => {
const clicked = mapOverlays.find((o) => o.id === e.target.value);
if (!clicked || clicked.available) {
- setSelectedMapOverlay(e.target.value);
+ setAttributes({ ...attributes, selectedMapOverlay: e.target.value });
} else if (clicked.id !== 'custom') {
const query = new URLSearchParams({ attribute: clicked.attribute });
navigate(`/settings/user/${user.id}?${query.toString()}`);
@@ -243,9 +205,9 @@ const PreferencesPage = () => {
freeSolo
options={Object.keys(positionAttributes)}
getOptionLabel={(option) => (positionAttributes.hasOwnProperty(option) ? positionAttributes[option].name : option)}
- value={positionItems}
+ value={attributes.positionItems?.split(',') || ['speed', 'address', 'totalDistance', 'course']}
onChange={(_, option) => {
- setPositionItems(option);
+ setAttributes({ ...attributes, positionItems: option.join(',') });
}}
filterOptions={(options, params) => {
const filtered = filter(options, params);
@@ -257,7 +219,7 @@ const PreferencesPage = () => {
renderInput={(params) => (
<TextField
{...params}
- placeholder={t('sharedAttributes')}
+ label={t('attributePopupInfo')}
/>
)}
/>
@@ -272,19 +234,39 @@ const PreferencesPage = () => {
label={t('attributeShowGeofences')}
/>
<FormControlLabel
- control={<Checkbox checked={mapLiveRoutes} onChange={(e) => setMapLiveRoutes(e.target.checked)} />}
+ control={(
+ <Checkbox
+ checked={attributes.hasOwnProperty('mapLiveRoutes') ? attributes.mapLiveRoutes : false}
+ onChange={(e) => setAttributes({ ...attributes, mapLiveRoutes: e.target.checked })}
+ />
+ )}
label={t('mapLiveRoutes')}
/>
<FormControlLabel
- control={<Checkbox checked={mapFollow} onChange={(e) => setMapFollow(e.target.checked)} />}
+ control={(
+ <Checkbox
+ checked={attributes.hasOwnProperty('mapFollow') ? attributes.mapFollow : false}
+ onChange={(e) => setAttributes({ ...attributes, mapFollow: e.target.checked })}
+ />
+ )}
label={t('deviceFollow')}
/>
<FormControlLabel
- control={<Checkbox checked={mapCluster} onChange={(e) => setMapCluster(e.target.checked)} />}
+ control={(
+ <Checkbox
+ checked={attributes.hasOwnProperty('mapCluster') ? attributes.mapCluster : true}
+ onChange={(e) => setAttributes({ ...attributes, mapCluster: e.target.checked })}
+ />
+ )}
label={t('mapClustering')}
/>
<FormControlLabel
- control={<Checkbox checked={mapOnSelect} onChange={(e) => setMapOnSelect(e.target.checked)} />}
+ control={(
+ <Checkbox
+ checked={attributes.hasOwnProperty('mapOnSelect') ? attributes.mapOnSelect : true}
+ onChange={(e) => setAttributes({ ...attributes, mapOnSelect: e.target.checked })}
+ />
+ )}
label={t('mapOnSelect')}
/>
</FormGroup>
@@ -299,19 +281,19 @@ const PreferencesPage = () => {
<AccordionDetails className={classes.details}>
<SelectField
emptyValue={null}
- value={devicePrimary}
- onChange={(e) => setDevicePrimary(e.target.value)}
+ value={attributes.devicePrimary || 'name'}
+ onChange={(e) => setAttributes({ ...attributes, devicePrimary: e.target.value })}
data={deviceFields}
titleGetter={(it) => t(it.name)}
- label={t('sharedPrimary')}
+ label={t('devicePrimaryInfo')}
/>
<SelectField
emptyValue=""
- value={deviceSecondary}
- onChange={(e) => setDeviceSecondary(e.target.value)}
+ value={attributes.deviceSecondary || ''}
+ onChange={(e) => setAttributes({ ...attributes, deviceSecondary: e.target.value })}
data={deviceFields}
titleGetter={(it) => t(it.name)}
- label={t('sharedSecondary')}
+ label={t('deviceSecondaryInfo')}
/>
</AccordionDetails>
</Accordion>
@@ -324,20 +306,20 @@ const PreferencesPage = () => {
<AccordionDetails className={classes.details}>
<SelectField
multiple
- value={soundEvents}
- onChange={(e) => setSoundEvents(e.target.value)}
+ value={attributes.soundEvents?.split(',') || []}
+ onChange={(e) => setAttributes({ ...attributes, soundEvents: e.target.value.join(',') })}
endpoint="/api/notifications/types"
keyGetter={(it) => it.type}
titleGetter={(it) => t(prefixString('event', it.type))}
- label={t('reportEventTypes')}
+ label={t('eventsSoundEvents')}
/>
<SelectField
multiple
- value={soundAlarms}
- onChange={(e) => setSoundAlarms(e.target.value)}
+ value={attributes.soundAlarms?.split(',') || ['sos']}
+ onChange={(e) => setAttributes({ ...attributes, soundAlarms: e.target.value.join(',') })}
data={alarms}
keyGetter={(it) => it.key}
- label={t('sharedAlarms')}
+ label={t('eventsSoundAlarms')}
/>
</AccordionDetails>
</Accordion>