diff options
author | Anton Tananaev <anton@traccar.org> | 2022-05-08 13:16:57 -0700 |
---|---|---|
committer | Anton Tananaev <anton@traccar.org> | 2022-05-08 13:16:57 -0700 |
commit | 2cd374bb9fa941d7e2a6fd8aa5079893a158c98f (patch) | |
tree | f4ee48130592fed5de25dce7af4ac0cbeb017680 /modern/src/admin | |
parent | 2352071211b61c10fa5bf5736baaff7809d18bf0 (diff) | |
download | trackermap-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.js | 241 | ||||
-rw-r--r-- | modern/src/admin/StatisticsPage.js | 145 | ||||
-rw-r--r-- | modern/src/admin/UsersPage.js | 70 |
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; |