aboutsummaryrefslogtreecommitdiff
path: root/modern/src
diff options
context:
space:
mode:
authorAnton Tananaev <anton@traccar.org>2022-04-17 13:33:27 -0700
committerAnton Tananaev <anton@traccar.org>2022-04-17 13:33:27 -0700
commit6505a13e0037d5de5737e940907cc62c4a9107bc (patch)
treec4b4ceeb0a8b4bd7b688ca4c6f1fd59834cc9f6f /modern/src
parente470eeb4fcc923bc54968a6561f66c75dab288b9 (diff)
downloadtrackermap-web-6505a13e0037d5de5737e940907cc62c4a9107bc.tar.gz
trackermap-web-6505a13e0037d5de5737e940907cc62c4a9107bc.tar.bz2
trackermap-web-6505a13e0037d5de5737e940907cc62c4a9107bc.zip
Refactor settings layout
Diffstat (limited to 'modern/src')
-rw-r--r--modern/src/DevicesList.js7
-rw-r--r--modern/src/EditCollectionView.js9
-rw-r--r--modern/src/GeofencesList.js4
-rw-r--r--modern/src/map/CurrentPositionsMap.js4
-rw-r--r--modern/src/map/GeofenceEditMap.js6
-rw-r--r--modern/src/map/GeofenceMap.js4
-rw-r--r--modern/src/reports/ReportFilter.js4
-rw-r--r--modern/src/settings/OptionsLayout.js (renamed from modern/src/settings/OptionsLayout/index.js)49
-rw-r--r--modern/src/settings/OptionsLayout/useRoutes.js95
9 files changed, 58 insertions, 124 deletions
diff --git a/modern/src/DevicesList.js b/modern/src/DevicesList.js
index 0ea07319..15a88874 100644
--- a/modern/src/DevicesList.js
+++ b/modern/src/DevicesList.js
@@ -108,14 +108,15 @@ const DeviceView = ({ updateTimestamp, onMenuClick, filter }) => {
const dispatch = useDispatch();
const listInnerEl = useRef(null);
- const items = useSelector((state) => Object.values(state.devices.items));
+ const items = useSelector((state) => state.devices.items);
const [filteredItems, setFilteredItems] = useState(null);
useEffect(() => {
+ const array = Object.values(items);
setFilteredItems(
filter.trim().length > 0
- ? items.filter((item) => `${item.name} ${item.uniqueId}`.toLowerCase().includes(filter?.toLowerCase()))
- : items,
+ ? array.filter((item) => `${item.name} ${item.uniqueId}`.toLowerCase().includes(filter?.toLowerCase()))
+ : array,
);
}, [filter, items]);
diff --git a/modern/src/EditCollectionView.js b/modern/src/EditCollectionView.js
index 2d011302..6bb9cb3e 100644
--- a/modern/src/EditCollectionView.js
+++ b/modern/src/EditCollectionView.js
@@ -65,11 +65,10 @@ const EditCollectionView = ({
return (
<>
<Content updateTimestamp={updateTimestamp} onMenuClick={menuShow} filter={filter} />
- {adminEnabled && !disableAdd
- && (
- <Fab size="medium" color="primary" className={classes.fab} onClick={handleAdd}>
- <AddIcon />
- </Fab>
+ {adminEnabled && !disableAdd && (
+ <Fab size="medium" color="primary" className={classes.fab} onClick={handleAdd}>
+ <AddIcon />
+ </Fab>
)}
<Menu open={!!selectedAnchorEl} anchorEl={selectedAnchorEl} onClose={menuHide}>
<MenuItem onClick={handleEdit}>{t('sharedEdit')}</MenuItem>
diff --git a/modern/src/GeofencesList.js b/modern/src/GeofencesList.js
index 572ac5b1..705bdcc3 100644
--- a/modern/src/GeofencesList.js
+++ b/modern/src/GeofencesList.js
@@ -28,11 +28,11 @@ const GeofenceView = ({ onMenuClick }) => {
const classes = useStyles();
const dispatch = useDispatch();
- const items = useSelector((state) => Object.values(state.geofences.items));
+ const items = useSelector((state) => state.geofences.items);
return (
<List className={classes.list}>
- {items.map((item, index, list) => (
+ {Object.values(items).map((item, index, list) => (
<Fragment key={item.id}>
<ListItem button key={item.id} onClick={() => dispatch(devicesActions.select(item))}>
<ListItemText primary={item.name} />
diff --git a/modern/src/map/CurrentPositionsMap.js b/modern/src/map/CurrentPositionsMap.js
index 9e00774a..874e0804 100644
--- a/modern/src/map/CurrentPositionsMap.js
+++ b/modern/src/map/CurrentPositionsMap.js
@@ -4,8 +4,8 @@ import { useSelector } from 'react-redux';
import PositionsMap from './PositionsMap';
const CurrentPositionsMap = () => {
- const positions = useSelector((state) => Object.values(state.positions.items));
- return (<PositionsMap positions={positions} />);
+ const positions = useSelector((state) => state.positions.items);
+ return (<PositionsMap positions={Object.values(positions)} />);
};
export default CurrentPositionsMap;
diff --git a/modern/src/map/GeofenceEditMap.js b/modern/src/map/GeofenceEditMap.js
index 91addd43..25c336d1 100644
--- a/modern/src/map/GeofenceEditMap.js
+++ b/modern/src/map/GeofenceEditMap.js
@@ -37,7 +37,7 @@ const GeofenceEditMap = () => {
const dispatch = useDispatch();
const history = useHistory();
- const geofences = useSelector((state) => Object.values(state.geofences.items));
+ const geofences = useSelector((state) => state.geofences.items);
const refreshGeofences = useCallback(async () => {
const response = await fetch('/api/geofences');
@@ -89,7 +89,7 @@ const GeofenceEditMap = () => {
useEffect(() => {
const listener = async (event) => {
const feature = event.features[0];
- const item = geofences.find((i) => i.id === feature.id);
+ const item = Object.values(geofences).find((i) => i.id === feature.id);
if (item) {
const updatedItem = { ...item, area: geometryToArea(feature.geometry) };
const response = await fetch(`/api/geofences/${feature.id}`, {
@@ -109,7 +109,7 @@ const GeofenceEditMap = () => {
useEffect(() => {
draw.deleteAll();
- geofences.forEach((geofence) => {
+ Object.values(geofences).forEach((geofence) => {
draw.add(geofenceToFeature(geofence));
});
}, [geofences]);
diff --git a/modern/src/map/GeofenceMap.js b/modern/src/map/GeofenceMap.js
index c0ecef40..0d27df82 100644
--- a/modern/src/map/GeofenceMap.js
+++ b/modern/src/map/GeofenceMap.js
@@ -7,7 +7,7 @@ import { geofenceToFeature } from './mapUtil';
const GeofenceMap = () => {
const id = 'geofences';
- const geofences = useSelector((state) => Object.values(state.geofences.items));
+ const geofences = useSelector((state) => state.geofences.items);
useEffect(() => {
map.addSource(id, {
@@ -74,7 +74,7 @@ const GeofenceMap = () => {
useEffect(() => {
map.getSource(id).setData({
type: 'FeatureCollection',
- features: geofences.map(geofenceToFeature),
+ features: Object.values(geofences).map(geofenceToFeature),
});
}, [geofences]);
diff --git a/modern/src/reports/ReportFilter.js b/modern/src/reports/ReportFilter.js
index bfd8a540..827b36fb 100644
--- a/modern/src/reports/ReportFilter.js
+++ b/modern/src/reports/ReportFilter.js
@@ -9,7 +9,7 @@ import { useTranslation } from '../LocalizationProvider';
const ReportFilter = ({ children, handleSubmit, showOnly }) => {
const t = useTranslation();
- const devices = useSelector((state) => Object.values(state.devices.items));
+ const devices = useSelector((state) => state.devices.items);
const [deviceId, setDeviceId] = useState();
const [period, setPeriod] = useState('today');
const [from, setFrom] = useState(moment().subtract(1, 'hour'));
@@ -65,7 +65,7 @@ const ReportFilter = ({ children, handleSubmit, showOnly }) => {
<FormControl variant="filled" fullWidth>
<InputLabel>{t('reportDevice')}</InputLabel>
<Select value={deviceId} onChange={(e) => setDeviceId(e.target.value)}>
- {devices.map((device) => (
+ {Object.values(devices).map((device) => (
<MenuItem key={device.id} value={device.id}>{device.name}</MenuItem>
))}
</Select>
diff --git a/modern/src/settings/OptionsLayout/index.js b/modern/src/settings/OptionsLayout.js
index fea03722..eef9cabb 100644
--- a/modern/src/settings/OptionsLayout/index.js
+++ b/modern/src/settings/OptionsLayout.js
@@ -1,4 +1,4 @@
-import React, { useState, useEffect } from 'react';
+import React, { useState, useEffect, useMemo } from 'react';
import { useHistory, useLocation } from 'react-router-dom';
import {
Typography,
@@ -11,10 +11,19 @@ import {
import ArrowBackIcon from '@material-ui/icons/ArrowBack';
-import SideNav from '../../components/SideNav';
-import NavBar from '../../components/NavBar';
-import useRoutes from './useRoutes';
-import { useTranslation } from '../../LocalizationProvider';
+import SideNav from '../components/SideNav';
+import NavBar from '../components/NavBar';
+import { useTranslation } from '../LocalizationProvider';
+import { useSelector } from 'react-redux';
+import CreateIcon from '@material-ui/icons/Create';
+import NotificationsIcon from '@material-ui/icons/Notifications';
+import FolderIcon from '@material-ui/icons/Folder';
+import PersonIcon from '@material-ui/icons/Person';
+import StorageIcon from '@material-ui/icons/Storage';
+import BuildIcon from '@material-ui/icons/Build';
+import PeopleIcon from '@material-ui/icons/People';
+import BarChartIcon from '@material-ui/icons/BarChart';
+import TodayIcon from '@material-ui/icons/Today';
const useStyles = makeStyles((theme) => ({
root: {
@@ -51,19 +60,39 @@ const useStyles = makeStyles((theme) => ({
}));
const OptionsLayout = ({ children }) => {
+ const t = useTranslation();
const classes = useStyles();
const location = useLocation();
const history = useHistory();
- const routes = useRoutes();
- const t = useTranslation();
const [openDrawer, setOpenDrawer] = useState(false);
const [optionTitle, setOptionTitle] = useState();
+ const admin = useSelector((state) => state.session.user?.administrator);
+ const userId = useSelector((state) => state.session.user?.id);
+
+ const adminRoutes = useMemo(() => [
+ { subheader: t('userAdmin') },
+ { name: t('settingsServer'), href: '/admin/server', icon: <StorageIcon /> },
+ { name: t('settingsUsers'), href: '/admin/users', icon: <PeopleIcon /> },
+ { name: t('statisticsTitle'), href: '/admin/statistics', icon: <BarChartIcon /> },
+ ], [t]);
+
+ const mainRoutes = useMemo(() => [
+ { name: t('settingsUser'), href: `/user/${userId}`, icon: <PersonIcon /> },
+ { name: t('sharedGeofences'), href: '/geofences', icon: <CreateIcon /> },
+ { name: t('sharedNotifications'), href: '/settings/notifications', icon: <NotificationsIcon /> },
+ { name: t('settingsGroups'), href: '/settings/groups', icon: <FolderIcon /> },
+ { name: t('sharedDrivers'), href: '/settings/drivers', icon: <PersonIcon /> },
+ { name: t('sharedCalendars'), href: '/settings/calendars', icon: <TodayIcon /> },
+ { name: t('sharedComputedAttributes'), href: '/settings/attributes', icon: <StorageIcon /> },
+ { name: t('sharedMaintenance'), href: '/settings/maintenances', icon: <BuildIcon /> },
+ ], [t, userId]);
+
+ const routes = useMemo(() => [...mainRoutes, ...(admin ? adminRoutes : [])], [mainRoutes, admin, adminRoutes]);
+
useEffect(() => {
- const activeRoute = routes.find(
- (route) => route.href && location.pathname.match(route.match || route.href),
- );
+ const activeRoute = routes.find((route) => route.href && location.pathname.includes(route.href));
setOptionTitle(activeRoute?.name);
}, [location, routes]);
diff --git a/modern/src/settings/OptionsLayout/useRoutes.js b/modern/src/settings/OptionsLayout/useRoutes.js
deleted file mode 100644
index 70662e4d..00000000
--- a/modern/src/settings/OptionsLayout/useRoutes.js
+++ /dev/null
@@ -1,95 +0,0 @@
-import React, { useMemo } from 'react';
-import { useSelector } from 'react-redux';
-import CreateIcon from '@material-ui/icons/Create';
-import NotificationsIcon from '@material-ui/icons/Notifications';
-import FolderIcon from '@material-ui/icons/Folder';
-import PersonIcon from '@material-ui/icons/Person';
-import StorageIcon from '@material-ui/icons/Storage';
-import BuildIcon from '@material-ui/icons/Build';
-import PeopleIcon from '@material-ui/icons/People';
-import BarChartIcon from '@material-ui/icons/BarChart';
-import TodayIcon from '@material-ui/icons/Today';
-import { useTranslation } from '../../LocalizationProvider';
-
-const useAdminRoutes = (t) => useMemo(() => [
- { subheader: t('userAdmin') },
- {
- name: t('settingsServer'),
- href: '/admin/server',
- icon: <StorageIcon />,
- },
- {
- name: t('settingsUsers'),
- href: '/admin/users',
- icon: <PeopleIcon />,
- },
- {
- name: t('statisticsTitle'),
- href: '/admin/statistics',
- icon: <BarChartIcon />,
- },
-], [t]);
-
-const useMainRoutes = (t, userId) => useMemo(() => [
- {
- name: t('settingsUser'),
- href: `/user/${userId}`,
- icon: <PersonIcon />,
- },
- {
- match: 'geofence',
- name: t('sharedGeofences'),
- href: '/geofences',
- icon: <CreateIcon />,
- },
- {
- match: 'notification',
- name: t('sharedNotifications'),
- href: '/settings/notifications',
- icon: <NotificationsIcon />,
- },
- {
- match: 'group',
- name: t('settingsGroups'),
- href: '/settings/groups',
- icon: <FolderIcon />,
- },
- {
- match: 'driver',
- name: t('sharedDrivers'),
- href: '/settings/drivers',
- icon: <PersonIcon />,
- },
- {
- match: 'calendar',
- name: t('sharedCalendars'),
- href: '/settings/calendars',
- icon: <TodayIcon />,
- },
- {
- match: 'attribute',
- name: t('sharedComputedAttributes'),
- href: '/settings/attributes',
- icon: <StorageIcon />,
- },
- {
- match: 'maintenance',
- name: t('sharedMaintenance'),
- href: '/settings/maintenances',
- icon: <BuildIcon />,
- },
-], [t, userId]);
-
-export default () => {
- const t = useTranslation();
-
- const isAdmin = useSelector((state) => state.session.user?.administrator);
- const userId = useSelector((state) => state.session.user?.id);
-
- const mainRoutes = useMainRoutes(t, userId);
- const adminRoutes = useAdminRoutes(t);
-
- return useMemo(() => [...mainRoutes, ...(isAdmin ? adminRoutes : [])], [
- mainRoutes, isAdmin, adminRoutes,
- ]);
-};