aboutsummaryrefslogtreecommitdiff
path: root/modern/src/admin
diff options
context:
space:
mode:
authorAnton Tananaev <anton@traccar.org>2022-05-08 13:16:57 -0700
committerAnton Tananaev <anton@traccar.org>2022-05-08 13:16:57 -0700
commit2cd374bb9fa941d7e2a6fd8aa5079893a158c98f (patch)
treef4ee48130592fed5de25dce7af4ac0cbeb017680 /modern/src/admin
parent2352071211b61c10fa5bf5736baaff7809d18bf0 (diff)
downloadtrackermap-web-2cd374bb9fa941d7e2a6fd8aa5079893a158c98f.tar.gz
trackermap-web-2cd374bb9fa941d7e2a6fd8aa5079893a158c98f.tar.bz2
trackermap-web-2cd374bb9fa941d7e2a6fd8aa5079893a158c98f.zip
Reorganize remaining files
Diffstat (limited to 'modern/src/admin')
-rw-r--r--modern/src/admin/ServerPage.js241
-rw-r--r--modern/src/admin/StatisticsPage.js145
-rw-r--r--modern/src/admin/UsersPage.js70
3 files changed, 0 insertions, 456 deletions
diff --git a/modern/src/admin/ServerPage.js b/modern/src/admin/ServerPage.js
deleted file mode 100644
index 19a5c993..00000000
--- a/modern/src/admin/ServerPage.js
+++ /dev/null
@@ -1,241 +0,0 @@
-import React, { useState } from 'react';
-import TextField from '@material-ui/core/TextField';
-
-import {
- Accordion, AccordionSummary, AccordionDetails, makeStyles, Typography, Button, FormControl, Container, Checkbox, FormControlLabel, InputLabel, Select, MenuItem,
-} from '@material-ui/core';
-import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
-import { useHistory } from 'react-router-dom';
-import { useDispatch, useSelector } from 'react-redux';
-import { sessionActions } from '../store';
-import EditAttributesView from '../attributes/EditAttributesView';
-import useDeviceAttributes from '../attributes/useDeviceAttributes';
-import useUserAttributes from '../attributes/useUserAttributes';
-import OptionsLayout from '../settings/OptionsLayout';
-import { useTranslation } from '../LocalizationProvider';
-import SelectField from '../form/SelectField';
-
-const useStyles = makeStyles((theme) => ({
- container: {
- marginTop: theme.spacing(2),
- },
- buttons: {
- display: 'flex',
- justifyContent: 'space-evenly',
- '& > *': {
- flexBasis: '33%',
- },
- },
- details: {
- flexDirection: 'column',
- },
-}));
-
-const ServerPage = () => {
- const classes = useStyles();
- const history = useHistory();
- const dispatch = useDispatch();
- const t = useTranslation();
-
- const userAttributes = useUserAttributes(t);
- const deviceAttributes = useDeviceAttributes(t);
-
- const original = useSelector((state) => state.session.server);
- const [item, setItem] = useState({ ...original });
-
- const handleSave = async () => {
- const response = await fetch('/api/server', {
- method: 'PUT',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify(item),
- });
-
- if (response.ok) {
- dispatch(sessionActions.updateServer(await response.json()));
- history.goBack();
- }
- };
-
- return (
- <OptionsLayout>
- <Container maxWidth="xs" className={classes.container}>
- {item && (
- <>
- <Accordion defaultExpanded>
- <AccordionSummary expandIcon={<ExpandMoreIcon />}>
- <Typography variant="subtitle1">
- {t('sharedPreferences')}
- </Typography>
- </AccordionSummary>
- <AccordionDetails className={classes.details}>
- <TextField
- margin="normal"
- value={item.mapUrl || ''}
- onChange={(event) => setItem({ ...item, mapUrl: event.target.value })}
- label={t('mapCustomLabel')}
- variant="filled"
- />
- <TextField
- margin="normal"
- type="number"
- value={item.latitude || 0}
- onChange={(event) => setItem({ ...item, latitude: Number(event.target.value) })}
- label={t('positionLatitude')}
- variant="filled"
- />
- <TextField
- margin="normal"
- type="number"
- value={item.longitude || 0}
- onChange={(event) => setItem({ ...item, longitude: Number(event.target.value) })}
- label={t('positionLongitude')}
- variant="filled"
- />
- <TextField
- margin="normal"
- type="number"
- value={item.zoom || 0}
- onChange={(event) => setItem({ ...item, zoom: Number(event.target.value) })}
- label={t('serverZoom')}
- variant="filled"
- />
- <FormControl variant="filled" margin="normal" fullWidth>
- <InputLabel>{t('settingsCoordinateFormat')}</InputLabel>
- <Select
- value={item.coordinateFormat || 'dd'}
- onChange={(event) => setItem({ ...item, coordinateFormat: event.target.value })}
- >
- <MenuItem value="dd">{t('sharedDecimalDegrees')}</MenuItem>
- <MenuItem value="ddm">{t('sharedDegreesDecimalMinutes')}</MenuItem>
- <MenuItem value="dms">{t('sharedDegreesMinutesSeconds')}</MenuItem>
- </Select>
- </FormControl>
- <FormControl variant="filled" margin="normal" fullWidth>
- <InputLabel>{t('settingsSpeedUnit')}</InputLabel>
- <Select
- value={item.attributes.speedUnit || 'kn'}
- onChange={(e) => setItem({ ...item, attributes: { ...item.attributes, speedUnit: e.target.value } })}
- >
- <MenuItem value="kn">{t('sharedKn')}</MenuItem>
- <MenuItem value="kmh">{t('sharedKmh')}</MenuItem>
- <MenuItem value="mph">{t('sharedMph')}</MenuItem>
- </Select>
- </FormControl>
- <FormControl variant="filled" margin="normal" fullWidth>
- <InputLabel>{t('settingsDistanceUnit')}</InputLabel>
- <Select
- value={item.attributes.distanceUnit || 'km'}
- onChange={(e) => setItem({ ...item, attributes: { ...item.attributes, distanceUnit: e.target.value } })}
- >
- <MenuItem value="km">{t('sharedKm')}</MenuItem>
- <MenuItem value="mi">{t('sharedMi')}</MenuItem>
- <MenuItem value="nmi">{t('sharedNmi')}</MenuItem>
- </Select>
- </FormControl>
- <FormControl variant="filled" margin="normal" fullWidth>
- <InputLabel>{t('settingsVolumeUnit')}</InputLabel>
- <Select
- value={item.attributes.volumeUnit || 'ltr'}
- onChange={(e) => setItem({ ...item, attributes: { ...item.attributes, volumeUnit: e.target.value } })}
- >
- <MenuItem value="ltr">{t('sharedLiter')}</MenuItem>
- <MenuItem value="usGal">{t('sharedUsGallon')}</MenuItem>
- <MenuItem value="impGal">{t('sharedImpGallon')}</MenuItem>
- </Select>
- </FormControl>
- <SelectField
- margin="normal"
- value={item.attributes.timezone || ''}
- emptyValue=""
- onChange={(e) => setItem({ ...item, attributes: { ...item.attributes, timezone: e.target.value } })}
- endpoint="/api/server/timezones"
- keyGetter={(it) => it}
- titleGetter={(it) => it}
- label={t('sharedTimezone')}
- variant="filled"
- />
- <TextField
- margin="normal"
- value={item.poiLayer || ''}
- onChange={(event) => setItem({ ...item, poiLayer: event.target.value })}
- label={t('mapPoiLayer')}
- variant="filled"
- />
- <TextField
- margin="normal"
- value={item.announcement || ''}
- onChange={(event) => setItem({ ...item, announcement: event.target.value })}
- label={t('serverAnnouncement')}
- variant="filled"
- />
- <FormControlLabel
- control={<Checkbox checked={item.twelveHourFormat} onChange={(event) => setItem({ ...item, twelveHourFormat: event.target.checked })} />}
- label={t('settingsTwelveHourFormat')}
- />
- <FormControlLabel
- control={<Checkbox checked={item.forceSettings} onChange={(event) => setItem({ ...item, forceSettings: event.target.checked })} />}
- label={t('serverForceSettings')}
- />
- </AccordionDetails>
- </Accordion>
- <Accordion>
- <AccordionSummary expandIcon={<ExpandMoreIcon />}>
- <Typography variant="subtitle1">
- {t('sharedPermissions')}
- </Typography>
- </AccordionSummary>
- <AccordionDetails className={classes.details}>
- <FormControlLabel
- control={<Checkbox checked={item.registration} onChange={(event) => setItem({ ...item, registration: event.target.checked })} />}
- label={t('serverRegistration')}
- />
- <FormControlLabel
- control={<Checkbox checked={item.readonly} onChange={(event) => setItem({ ...item, readonly: event.target.checked })} />}
- label={t('serverReadonly')}
- />
- <FormControlLabel
- control={<Checkbox checked={item.deviceReadonly} onChange={(event) => setItem({ ...item, deviceReadonly: event.target.checked })} />}
- label={t('userDeviceReadonly')}
- />
- <FormControlLabel
- control={<Checkbox checked={item.limitCommands} onChange={(event) => setItem({ ...item, limitCommands: event.target.checked })} />}
- label={t('userLimitCommands')}
- />
- <FormControlLabel
- control={<Checkbox checked={item.disableReports} onChange={(event) => setItem({ ...item, disableReports: event.target.checked })} />}
- label={t('userDisableReports')}
- />
- </AccordionDetails>
- </Accordion>
- <Accordion>
- <AccordionSummary expandIcon={<ExpandMoreIcon />}>
- <Typography variant="subtitle1">
- {t('sharedAttributes')}
- </Typography>
- </AccordionSummary>
- <AccordionDetails className={classes.details}>
- <EditAttributesView
- attributes={item.attributes}
- setAttributes={(attributes) => setItem({ ...item, attributes })}
- definitions={{ ...userAttributes, ...deviceAttributes }}
- />
- </AccordionDetails>
- </Accordion>
- </>
- )}
- <FormControl fullWidth margin="normal">
- <div className={classes.buttons}>
- <Button type="button" color="primary" variant="outlined" onClick={() => history.goBack()}>
- {t('sharedCancel')}
- </Button>
- <Button type="button" color="primary" variant="contained" onClick={handleSave}>
- {t('sharedSave')}
- </Button>
- </div>
- </FormControl>
- </Container>
- </OptionsLayout>
- );
-};
-
-export default ServerPage;
diff --git a/modern/src/admin/StatisticsPage.js b/modern/src/admin/StatisticsPage.js
deleted file mode 100644
index b8caa9ec..00000000
--- a/modern/src/admin/StatisticsPage.js
+++ /dev/null
@@ -1,145 +0,0 @@
-import React, { useState } from 'react';
-import {
- FormControl, InputLabel, Select, MenuItem, TextField, Button, TableContainer, Table, TableRow, TableCell, TableHead, TableBody,
-} from '@material-ui/core';
-import moment from 'moment';
-import { formatDate } from '../common/util/formatter';
-import OptionsLayout from '../settings/OptionsLayout';
-import { useTranslation } from '../LocalizationProvider';
-
-const Filter = ({ setItems }) => {
- const t = useTranslation();
-
- const [period, setPeriod] = useState('today');
- const [from, setFrom] = useState(moment().subtract(1, 'hour'));
- const [to, setTo] = useState(moment());
-
- const handleClick = async () => {
- let selectedFrom;
- let selectedTo;
- switch (period) {
- case 'today':
- selectedFrom = moment().startOf('day');
- selectedTo = moment().endOf('day');
- break;
- case 'yesterday':
- selectedFrom = moment().subtract(1, 'day').startOf('day');
- selectedTo = moment().subtract(1, 'day').endOf('day');
- break;
- case 'thisWeek':
- selectedFrom = moment().startOf('week');
- selectedTo = moment().endOf('week');
- break;
- case 'previousWeek':
- selectedFrom = moment().subtract(1, 'week').startOf('week');
- selectedTo = moment().subtract(1, 'week').endOf('week');
- break;
- case 'thisMonth':
- selectedFrom = moment().startOf('month');
- selectedTo = moment().endOf('month');
- break;
- case 'previousMonth':
- selectedFrom = moment().subtract(1, 'month').startOf('month');
- selectedTo = moment().subtract(1, 'month').endOf('month');
- break;
- default:
- selectedFrom = from;
- selectedTo = to;
- break;
- }
-
- const query = new URLSearchParams({ from: selectedFrom.toISOString(), to: selectedTo.toISOString() });
- const response = await fetch(`/api/statistics?${query.toString()}`, { Accept: 'application/json' });
- if (response.ok) {
- setItems(await response.json());
- }
- };
-
- return (
- <>
- <FormControl variant="filled" margin="normal" fullWidth>
- <InputLabel>{t('reportPeriod')}</InputLabel>
- <Select value={period} onChange={(e) => setPeriod(e.target.value)}>
- <MenuItem value="today">{t('reportToday')}</MenuItem>
- <MenuItem value="yesterday">{t('reportYesterday')}</MenuItem>
- <MenuItem value="thisWeek">{t('reportThisWeek')}</MenuItem>
- <MenuItem value="previousWeek">{t('reportPreviousWeek')}</MenuItem>
- <MenuItem value="thisMonth">{t('reportThisMonth')}</MenuItem>
- <MenuItem value="previousMonth">{t('reportPreviousMonth')}</MenuItem>
- <MenuItem value="custom">{t('reportCustom')}</MenuItem>
- </Select>
- </FormControl>
- {period === 'custom' && (
- <TextField
- margin="normal"
- variant="filled"
- label={t('reportFrom')}
- type="datetime-local"
- value={from.format(moment.HTML5_FMT.DATETIME_LOCAL)}
- onChange={(e) => setFrom(moment(e.target.value, moment.HTML5_FMT.DATETIME_LOCAL))}
- fullWidth
- />
- )}
- {period === 'custom' && (
- <TextField
- margin="normal"
- variant="filled"
- label={t('reportTo')}
- type="datetime-local"
- value={to.format(moment.HTML5_FMT.DATETIME_LOCAL)}
- onChange={(e) => setTo(moment(e.target.value, moment.HTML5_FMT.DATETIME_LOCAL))}
- fullWidth
- />
- )}
- <Button variant="contained" color="primary" onClick={handleClick} fullWidth>{t('reportShow')}</Button>
- </>
- );
-};
-
-const StatisticsPage = () => {
- const t = useTranslation();
-
- const [items, setItems] = useState([]);
-
- return (
- <OptionsLayout>
- <Filter setItems={setItems} />
- <TableContainer>
- <Table>
- <TableHead>
- <TableRow>
- <TableCell>{t('statisticsCaptureTime')}</TableCell>
- <TableCell>{t('statisticsActiveUsers')}</TableCell>
- <TableCell>{t('statisticsActiveDevices')}</TableCell>
- <TableCell>{t('statisticsRequests')}</TableCell>
- <TableCell>{t('statisticsMessagesReceived')}</TableCell>
- <TableCell>{t('statisticsMessagesStored')}</TableCell>
- <TableCell>{t('notificatorMail')}</TableCell>
- <TableCell>{t('notificatorSms')}</TableCell>
- <TableCell>{t('statisticsGeocoder')}</TableCell>
- <TableCell>{t('statisticsGeolocation')}</TableCell>
- </TableRow>
- </TableHead>
- <TableBody>
- {items.map((item) => (
- <TableRow key={item.id}>
- <TableCell>{formatDate(item.captureTime)}</TableCell>
- <TableCell>{item.activeUsers}</TableCell>
- <TableCell>{item.activeDevices}</TableCell>
- <TableCell>{item.requests}</TableCell>
- <TableCell>{item.messagesReceived}</TableCell>
- <TableCell>{item.messagesStored}</TableCell>
- <TableCell>{item.mailSent}</TableCell>
- <TableCell>{item.smsSent}</TableCell>
- <TableCell>{item.geocoderRequests}</TableCell>
- <TableCell>{item.geolocationRequests}</TableCell>
- </TableRow>
- ))}
- </TableBody>
- </Table>
- </TableContainer>
- </OptionsLayout>
- );
-};
-
-export default StatisticsPage;
diff --git a/modern/src/admin/UsersPage.js b/modern/src/admin/UsersPage.js
deleted file mode 100644
index d8e8bc3c..00000000
--- a/modern/src/admin/UsersPage.js
+++ /dev/null
@@ -1,70 +0,0 @@
-import React, { useState } from 'react';
-import {
- TableContainer, Table, TableRow, TableCell, TableHead, TableBody, makeStyles, IconButton,
-} from '@material-ui/core';
-import MoreVertIcon from '@material-ui/icons/MoreVert';
-import { useEffectAsync } from '../reactHelper';
-import EditCollectionView from '../EditCollectionView';
-import { formatBoolean } from '../common/util/formatter';
-import OptionsLayout from '../settings/OptionsLayout';
-import { useTranslation } from '../LocalizationProvider';
-
-const useStyles = makeStyles((theme) => ({
- columnAction: {
- width: theme.spacing(1),
- padding: theme.spacing(0, 1),
- },
-}));
-
-const UsersView = ({ updateTimestamp, onMenuClick }) => {
- const classes = useStyles();
- const t = useTranslation();
-
- const [items, setItems] = useState([]);
-
- useEffectAsync(async () => {
- const response = await fetch('/api/users');
- if (response.ok) {
- setItems(await response.json());
- }
- }, [updateTimestamp]);
-
- return (
- <TableContainer>
- <Table>
- <TableHead>
- <TableRow>
- <TableCell className={classes.columnAction} />
- <TableCell>{t('sharedName')}</TableCell>
- <TableCell>{t('userEmail')}</TableCell>
- <TableCell>{t('userAdmin')}</TableCell>
- <TableCell>{t('sharedDisabled')}</TableCell>
- </TableRow>
- </TableHead>
- <TableBody>
- {items.map((item) => (
- <TableRow key={item.id}>
- <TableCell className={classes.columnAction} padding="none">
- <IconButton size="small" onClick={(event) => onMenuClick(event.currentTarget, item.id)}>
- <MoreVertIcon />
- </IconButton>
- </TableCell>
- <TableCell>{item.name}</TableCell>
- <TableCell>{item.email}</TableCell>
- <TableCell>{formatBoolean(item.administrator, t)}</TableCell>
- <TableCell>{formatBoolean(item.disabled, t)}</TableCell>
- </TableRow>
- ))}
- </TableBody>
- </Table>
- </TableContainer>
- );
-};
-
-const UsersPage = () => (
- <OptionsLayout>
- <EditCollectionView content={UsersView} editPath="/user" endpoint="users" />
- </OptionsLayout>
-);
-
-export default UsersPage;