aboutsummaryrefslogtreecommitdiff
path: root/modern
diff options
context:
space:
mode:
Diffstat (limited to 'modern')
-rw-r--r--modern/package.json4
-rw-r--r--modern/src/App.js163
-rw-r--r--modern/src/Navigation.js131
-rw-r--r--modern/src/SocketController.js6
-rw-r--r--modern/src/common/components/BottomMenu.js14
-rw-r--r--modern/src/common/components/PageLayout.js6
-rw-r--r--modern/src/index.js22
-rw-r--r--modern/src/login/LoginPage.js10
-rw-r--r--modern/src/login/RegisterPage.js8
-rw-r--r--modern/src/login/ResetPasswordPage.js8
-rw-r--r--modern/src/main/MainPage.js6
-rw-r--r--modern/src/main/StatusCard.js12
-rw-r--r--modern/src/map/MapGeofenceEdit.js8
-rw-r--r--modern/src/other/EventPage.js6
-rw-r--r--modern/src/other/GeofencesPage.js6
-rw-r--r--modern/src/other/PositionPage.js6
-rw-r--r--modern/src/other/ReplayPage.js10
-rw-r--r--modern/src/settings/AccumulatorsPage.js8
-rw-r--r--modern/src/settings/CommandSendPage.js8
-rw-r--r--modern/src/settings/ServerPage.js8
-rw-r--r--modern/src/settings/components/CollectionActions.js6
-rw-r--r--modern/src/settings/components/CollectionFab.js6
-rw-r--r--modern/src/settings/components/EditItemView.js8
23 files changed, 242 insertions, 228 deletions
diff --git a/modern/package.json b/modern/package.json
index b1422f44..89b0a6f9 100644
--- a/modern/package.json
+++ b/modern/package.json
@@ -18,8 +18,8 @@
"moment": "^2.29.3",
"react": "^17.0.2",
"react-dom": "^17.0.2",
- "react-redux": "^7.2.4",
- "react-router-dom": "^5.2.0",
+ "react-redux": "^8.0.2",
+ "react-router-dom": "^6.3.0",
"react-scripts": "^3.4.4",
"react-virtualized-auto-sizer": "^1.0.5",
"react-window": "^1.8.6",
diff --git a/modern/src/App.js b/modern/src/App.js
index fee94e5b..84459cd5 100644
--- a/modern/src/App.js
+++ b/modern/src/App.js
@@ -1,56 +1,9 @@
-import React, { useState } from 'react';
-import { ThemeProvider } from '@material-ui/core/styles';
-import { Switch, Route, useHistory } from 'react-router-dom';
-import CssBaseline from '@material-ui/core/CssBaseline';
-import { useDispatch, useSelector } from 'react-redux';
+import React from 'react';
+import { Outlet } from 'react-router-dom';
+import { useSelector } from 'react-redux';
import { makeStyles, LinearProgress, useMediaQuery } from '@material-ui/core';
-import MainPage from './main/MainPage';
-import RouteReportPage from './reports/RouteReportPage';
-import ServerPage from './settings/ServerPage';
-import UsersPage from './settings/UsersPage';
-import DevicePage from './settings/DevicePage';
-import UserPage from './settings/UserPage';
-import SocketController from './SocketController';
-import NotificationsPage from './settings/NotificationsPage';
-import NotificationPage from './settings/NotificationPage';
-import GroupsPage from './settings/GroupsPage';
-import GroupPage from './settings/GroupPage';
-import PositionPage from './other/PositionPage';
-import EventReportPage from './reports/EventReportPage';
-import ReplayPage from './other/ReplayPage';
-import TripReportPage from './reports/TripReportPage';
-import StopReportPage from './reports/StopReportPage';
-import SummaryReportPage from './reports/SummaryReportPage';
-import ChartReportPage from './reports/ChartReportPage';
-import DriversPage from './settings/DriversPage';
-import DriverPage from './settings/DriverPage';
-import CalendarsPage from './settings/CalendarsPage';
-import CalendarPage from './settings/CalendarPage';
-import ComputedAttributesPage from './settings/ComputedAttributesPage';
-import ComputedAttributePage from './settings/ComputedAttributePage';
-import MaintenancesPage from './settings/MaintenancesPage';
-import MaintenancePage from './settings/MaintenancePage';
-import CommandsPage from './settings/CommandsPage';
-import CommandPage from './settings/CommandPage';
-import StatisticsPage from './reports/StatisticsPage';
-import CachingController from './CachingController';
-
-import LoginPage from './login/LoginPage';
-import RegisterPage from './login/RegisterPage';
-import ResetPasswordPage from './login/ResetPasswordPage';
-
import theme from './common/theme';
-import GeofencesPage from './other/GeofencesPage';
-import GeofencePage from './settings/GeofencePage';
-import useQuery from './common/util/useQuery';
-import { useEffectAsync } from './reactHelper';
-import { devicesActions } from './store';
-import EventPage from './other/EventPage';
-import PreferencesPage from './settings/PreferencesPage';
import BottomMenu from './common/components/BottomMenu';
-import AccumulatorsPage from './settings/AccumulatorsPage';
-import CommandSendPage from './settings/CommandSendPage';
-import ErrorHandler from './common/components/ErrorHandler';
const useStyles = makeStyles(() => ({
page: {
@@ -63,107 +16,27 @@ const useStyles = makeStyles(() => ({
}));
const App = () => {
- const history = useHistory();
- const dispatch = useDispatch();
const classes = useStyles();
const desktop = useMediaQuery(theme.breakpoints.up('md'));
const initialized = useSelector((state) => !!state.session.server && !!state.session.user);
- const [redirectsHandled, setRedirectsHandled] = useState(false);
-
- const query = useQuery();
-
- useEffectAsync(async () => {
- if (query.get('token')) {
- const token = query.get('token');
- await fetch(`/api/session?token=${encodeURIComponent(token)}`);
- history.push('/');
- } else if (query.get('deviceId')) {
- const deviceId = query.get('deviceId');
- const response = await fetch(`/api/devices?uniqueId=${deviceId}`);
- if (response.ok) {
- const items = await response.json();
- if (items.length > 0) {
- dispatch(devicesActions.select(items[0].id));
- }
- } else {
- throw Error(await response.text());
- }
- history.push('/');
- } else if (query.get('eventId')) {
- const eventId = parseInt(query.get('eventId'), 10);
- history.push(`/event/${eventId}`);
- } else {
- setRedirectsHandled(true);
- }
- }, [query]);
-
- return (!redirectsHandled ? (<LinearProgress />) : (
- <ThemeProvider theme={theme}>
- <CssBaseline />
- <SocketController />
- <CachingController />
- <Switch>
- <Route exact path="/login" component={LoginPage} />
- <Route exact path="/register" component={RegisterPage} />
- <Route exact path="/reset-password" component={ResetPasswordPage} />
- <Route>
- {!initialized ? (<LinearProgress />) : (
- <>
- <div className={classes.page}>
- <Switch>
- <Route exact path="/" component={MainPage} />
-
- <Route exact path="/position/:id?" component={PositionPage} />
- <Route exact path="/event/:id?" component={EventPage} />
- <Route exact path="/replay" component={ReplayPage} />
- <Route exact path="/geofences" component={GeofencesPage} />
-
- <Route exact path="/settings/accumulators/:deviceId?" component={AccumulatorsPage} />
- <Route exact path="/settings/calendars" component={CalendarsPage} />
- <Route exact path="/settings/calendar/:id?" component={CalendarPage} />
- <Route exact path="/settings/commands" component={CommandsPage} />
- <Route exact path="/settings/command/:id?" component={CommandPage} />
- <Route exact path="/settings/command-send/:deviceId?" component={CommandSendPage} />
- <Route exact path="/settings/attributes" component={ComputedAttributesPage} />
- <Route exact path="/settings/attribute/:id?" component={ComputedAttributePage} />
- <Route exact path="/settings/device/:id?" component={DevicePage} />
- <Route exact path="/settings/drivers" component={DriversPage} />
- <Route exact path="/settings/driver/:id?" component={DriverPage} />
- <Route exact path="/settings/geofence/:id?" component={GeofencePage} />
- <Route exact path="/settings/groups" component={GroupsPage} />
- <Route exact path="/settings/group/:id?" component={GroupPage} />
- <Route exact path="/settings/maintenances" component={MaintenancesPage} />
- <Route exact path="/settings/maintenance/:id?" component={MaintenancePage} />
- <Route exact path="/settings/notifications" component={NotificationsPage} />
- <Route exact path="/settings/notification/:id?" component={NotificationPage} />
- <Route exact path="/settings/preferences" component={PreferencesPage} />
- <Route exact path="/settings/server" component={ServerPage} />
- <Route exact path="/settings/users" component={UsersPage} />
- <Route exact path="/settings/user/:id?" component={UserPage} />
- <Route exact path="/reports/chart" component={ChartReportPage} />
- <Route exact path="/reports/event" component={EventReportPage} />
- <Route exact path="/reports/route" component={RouteReportPage} />
- <Route exact path="/reports/statistics" component={StatisticsPage} />
- <Route exact path="/reports/stop" component={StopReportPage} />
- <Route exact path="/reports/summary" component={SummaryReportPage} />
- <Route exact path="/reports/trip" component={TripReportPage} />
- </Switch>
- </div>
- {!desktop && (
- <div className={classes.menu}>
- <BottomMenu />
- </div>
- )}
- </>
- )}
- </Route>
- </Switch>
- <ErrorHandler />
- </ThemeProvider>
- ));
+ if (!initialized) {
+ return (<LinearProgress />);
+ }
+ return (
+ <>
+ <div className={classes.page}>
+ <Outlet />
+ </div>
+ {!desktop && (
+ <div className={classes.menu}>
+ <BottomMenu />
+ </div>
+ )}
+ </>
+ );
};
export default App;
diff --git a/modern/src/Navigation.js b/modern/src/Navigation.js
new file mode 100644
index 00000000..a538029b
--- /dev/null
+++ b/modern/src/Navigation.js
@@ -0,0 +1,131 @@
+import React, { useState } from 'react';
+import { Route, Routes, useNavigate } from 'react-router-dom';
+import { useDispatch } from 'react-redux';
+import { LinearProgress } from '@material-ui/core';
+import MainPage from './main/MainPage';
+import RouteReportPage from './reports/RouteReportPage';
+import ServerPage from './settings/ServerPage';
+import UsersPage from './settings/UsersPage';
+import DevicePage from './settings/DevicePage';
+import UserPage from './settings/UserPage';
+import NotificationsPage from './settings/NotificationsPage';
+import NotificationPage from './settings/NotificationPage';
+import GroupsPage from './settings/GroupsPage';
+import GroupPage from './settings/GroupPage';
+import PositionPage from './other/PositionPage';
+import EventReportPage from './reports/EventReportPage';
+import ReplayPage from './other/ReplayPage';
+import TripReportPage from './reports/TripReportPage';
+import StopReportPage from './reports/StopReportPage';
+import SummaryReportPage from './reports/SummaryReportPage';
+import ChartReportPage from './reports/ChartReportPage';
+import DriversPage from './settings/DriversPage';
+import DriverPage from './settings/DriverPage';
+import CalendarsPage from './settings/CalendarsPage';
+import CalendarPage from './settings/CalendarPage';
+import ComputedAttributesPage from './settings/ComputedAttributesPage';
+import ComputedAttributePage from './settings/ComputedAttributePage';
+import MaintenancesPage from './settings/MaintenancesPage';
+import MaintenancePage from './settings/MaintenancePage';
+import CommandsPage from './settings/CommandsPage';
+import CommandPage from './settings/CommandPage';
+import StatisticsPage from './reports/StatisticsPage';
+import LoginPage from './login/LoginPage';
+import RegisterPage from './login/RegisterPage';
+import ResetPasswordPage from './login/ResetPasswordPage';
+import GeofencesPage from './other/GeofencesPage';
+import GeofencePage from './settings/GeofencePage';
+import useQuery from './common/util/useQuery';
+import { useEffectAsync } from './reactHelper';
+import { devicesActions } from './store';
+import EventPage from './other/EventPage';
+import PreferencesPage from './settings/PreferencesPage';
+import AccumulatorsPage from './settings/AccumulatorsPage';
+import CommandSendPage from './settings/CommandSendPage';
+import App from './App';
+
+const Navigation = () => {
+ const navigate = useNavigate();
+ const dispatch = useDispatch();
+
+ const [redirectsHandled, setRedirectsHandled] = useState(false);
+
+ const query = useQuery();
+
+ useEffectAsync(async () => {
+ if (query.get('token')) {
+ const token = query.get('token');
+ await fetch(`/api/session?token=${encodeURIComponent(token)}`);
+ navigate('/');
+ } else if (query.get('deviceId')) {
+ const deviceId = query.get('deviceId');
+ const response = await fetch(`/api/devices?uniqueId=${deviceId}`);
+ if (response.ok) {
+ const items = await response.json();
+ if (items.length > 0) {
+ dispatch(devicesActions.select(items[0].id));
+ }
+ } else {
+ throw Error(await response.text());
+ }
+ navigate('/');
+ } else if (query.get('eventId')) {
+ const eventId = parseInt(query.get('eventId'), 10);
+ navigate(`/event/${eventId}`);
+ } else {
+ setRedirectsHandled(true);
+ }
+ }, [query]);
+
+ if (!redirectsHandled) {
+ return (<LinearProgress />);
+ }
+ return (
+ <Routes>
+ <Route path="/login" element={<LoginPage />} />
+ <Route path="/register" element={<RegisterPage />} />
+ <Route path="/reset-password" element={<ResetPasswordPage />} />
+ <Route path="/" element={<App />}>
+ <Route index element={<MainPage />} />
+
+ <Route path="/position/:id?" element={<PositionPage />} />
+ <Route path="/event/:id?" element={<EventPage />} />
+ <Route path="/replay" element={<ReplayPage />} />
+ <Route path="/geofences" element={<GeofencesPage />} />
+
+ <Route path="/settings/accumulators/:deviceId?" element={<AccumulatorsPage />} />
+ <Route path="/settings/calendars" element={<CalendarsPage />} />
+ <Route path="/settings/calendar/:id?" element={<CalendarPage />} />
+ <Route path="/settings/commands" element={<CommandsPage />} />
+ <Route path="/settings/command/:id?" element={<CommandPage />} />
+ <Route path="/settings/command-send/:deviceId?" element={<CommandSendPage />} />
+ <Route path="/settings/attributes" element={<ComputedAttributesPage />} />
+ <Route path="/settings/attribute/:id?" element={<ComputedAttributePage />} />
+ <Route path="/settings/device/:id?" element={<DevicePage />} />
+ <Route path="/settings/drivers" element={<DriversPage />} />
+ <Route path="/settings/driver/:id?" element={<DriverPage />} />
+ <Route path="/settings/geofence/:id?" element={<GeofencePage />} />
+ <Route path="/settings/groups" element={<GroupsPage />} />
+ <Route path="/settings/group/:id?" element={<GroupPage />} />
+ <Route path="/settings/maintenances" element={<MaintenancesPage />} />
+ <Route path="/settings/maintenance/:id?" element={<MaintenancePage />} />
+ <Route path="/settings/notifications" element={<NotificationsPage />} />
+ <Route path="/settings/notification/:id?" element={<NotificationPage />} />
+ <Route path="/settings/preferences" element={<PreferencesPage />} />
+ <Route path="/settings/server" element={<ServerPage />} />
+ <Route path="/settings/users" element={<UsersPage />} />
+ <Route path="/settings/user/:id?" element={<UserPage />} />
+
+ <Route path="/reports/chart" element={<ChartReportPage />} />
+ <Route path="/reports/event" element={<EventReportPage />} />
+ <Route path="/reports/route" element={<RouteReportPage />} />
+ <Route path="/reports/statistics" element={<StatisticsPage />} />
+ <Route path="/reports/stop" element={<StopReportPage />} />
+ <Route path="/reports/summary" element={<SummaryReportPage />} />
+ <Route path="/reports/trip" element={<TripReportPage />} />
+ </Route>
+ </Routes>
+ );
+};
+
+export default Navigation;
diff --git a/modern/src/SocketController.js b/modern/src/SocketController.js
index 9826d4b1..f776ebc7 100644
--- a/modern/src/SocketController.js
+++ b/modern/src/SocketController.js
@@ -1,7 +1,7 @@
import React, { useEffect, useRef, useState } from 'react';
import { useDispatch, useSelector, connect } from 'react-redux';
import { Snackbar } from '@material-ui/core';
-import { useHistory } from 'react-router-dom';
+import { useNavigate } from 'react-router-dom';
import { positionsActions, devicesActions, sessionActions } from './store';
import { useEffectAsync } from './reactHelper';
@@ -11,7 +11,7 @@ import { snackBarDurationLongMs } from './common/util/duration';
const SocketController = () => {
const dispatch = useDispatch();
- const history = useHistory();
+ const navigate = useNavigate();
const t = useTranslation();
const authenticated = useSelector((state) => !!state.session.user);
@@ -74,7 +74,7 @@ const SocketController = () => {
if (response.ok) {
dispatch(sessionActions.updateUser(await response.json()));
} else {
- history.push('/login');
+ navigate('/login');
}
return null;
}, [authenticated]);
diff --git a/modern/src/common/components/BottomMenu.js b/modern/src/common/components/BottomMenu.js
index 30960396..7db4dff8 100644
--- a/modern/src/common/components/BottomMenu.js
+++ b/modern/src/common/components/BottomMenu.js
@@ -1,6 +1,6 @@
import React, { useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
-import { useHistory, useLocation } from 'react-router-dom';
+import { useNavigate, useLocation } from 'react-router-dom';
import {
Paper, BottomNavigation, BottomNavigationAction, Menu, MenuItem, Typography,
} from '@material-ui/core';
@@ -16,7 +16,7 @@ import { useTranslation } from './LocalizationProvider';
import { useReadonly } from '../util/permissions';
const BottomMenu = () => {
- const history = useHistory();
+ const navigate = useNavigate();
const location = useLocation();
const dispatch = useDispatch();
const t = useTranslation();
@@ -41,26 +41,26 @@ const BottomMenu = () => {
const handleAccount = () => {
setAnchorEl(null);
- history.push(`/settings/user/${userId}`);
+ navigate(`/settings/user/${userId}`);
};
const handleLogout = async () => {
setAnchorEl(null);
await fetch('/api/session', { method: 'DELETE' });
- history.push('/login');
+ navigate('/login');
dispatch(sessionActions.updateUser(null));
};
const handleSelection = (event, value) => {
switch (value) {
case 0:
- history.push('/');
+ navigate('/');
break;
case 1:
- history.push('/reports/route');
+ navigate('/reports/route');
break;
case 2:
- history.push('/settings/preferences');
+ navigate('/settings/preferences');
break;
case 3:
if (readonly) {
diff --git a/modern/src/common/components/PageLayout.js b/modern/src/common/components/PageLayout.js
index a1f117c4..d92b71c3 100644
--- a/modern/src/common/components/PageLayout.js
+++ b/modern/src/common/components/PageLayout.js
@@ -4,7 +4,7 @@ import {
} from '@material-ui/core';
import ArrowBackIcon from '@material-ui/icons/ArrowBack';
import MenuIcon from '@material-ui/icons/Menu';
-import { useHistory } from 'react-router-dom';
+import { useNavigate } from 'react-router-dom';
import { useTranslation } from './LocalizationProvider';
const useStyles = makeStyles((theme) => ({
@@ -56,7 +56,7 @@ const PageTitle = ({ breadcrumbs }) => {
const PageLayout = ({ menu, breadcrumbs, children }) => {
const classes = useStyles();
- const history = useHistory();
+ const navigate = useNavigate();
const [openDrawer, setOpenDrawer] = useState(false);
@@ -71,7 +71,7 @@ const PageLayout = ({ menu, breadcrumbs, children }) => {
>
<div className={classes.toolbar}>
<Toolbar>
- <IconButton color="inherit" edge="start" onClick={() => history.push('/')}>
+ <IconButton color="inherit" edge="start" onClick={() => navigate('/')}>
<ArrowBackIcon />
</IconButton>
<PageTitle breadcrumbs={breadcrumbs} />
diff --git a/modern/src/index.js b/modern/src/index.js
index 43462d35..07ac7e3f 100644
--- a/modern/src/index.js
+++ b/modern/src/index.js
@@ -3,21 +3,31 @@ import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import { Provider } from 'react-redux';
-
-import App from './App';
+import { CssBaseline, ThemeProvider } from '@material-ui/core';
import * as serviceWorker from './serviceWorker';
import store from './store';
import { LocalizationProvider } from './common/components/LocalizationProvider';
+import ErrorHandler from './common/components/ErrorHandler';
+import CachingController from './CachingController';
+import SocketController from './SocketController';
+import theme from './common/theme';
+import Navigation from './Navigation';
-const base = window.location.href.indexOf('modern') >= 0 ? '/modern' : null;
+const base = window.location.href.indexOf('modern') >= 0 ? '/modern' : '/';
ReactDOM.render(
(
<Provider store={store}>
<LocalizationProvider>
- <BrowserRouter basename={base}>
- <App />
- </BrowserRouter>
+ <ThemeProvider theme={theme}>
+ <CssBaseline />
+ <BrowserRouter basename={base}>
+ <SocketController />
+ <CachingController />
+ <Navigation />
+ </BrowserRouter>
+ <ErrorHandler />
+ </ThemeProvider>
</LocalizationProvider>
</Provider>
), document.getElementById('root'),
diff --git a/modern/src/login/LoginPage.js b/modern/src/login/LoginPage.js
index 5b690cdc..2a911b84 100644
--- a/modern/src/login/LoginPage.js
+++ b/modern/src/login/LoginPage.js
@@ -6,7 +6,7 @@ import CloseIcon from '@material-ui/icons/Close';
import CachedIcon from '@material-ui/icons/Cached';
import { useTheme } from '@material-ui/core/styles';
import { useDispatch, useSelector } from 'react-redux';
-import { useHistory } from 'react-router-dom';
+import { useNavigate } from 'react-router-dom';
import { sessionActions } from '../store';
import { useLocalization, useTranslation } from '../common/components/LocalizationProvider';
import LoginLayout from './LoginLayout';
@@ -30,7 +30,7 @@ const useStyles = makeStyles((theme) => ({
const LoginPage = () => {
const classes = useStyles();
const dispatch = useDispatch();
- const history = useHistory();
+ const navigate = useNavigate();
const theme = useTheme();
const t = useTranslation();
@@ -58,7 +58,7 @@ const LoginPage = () => {
if (response.ok) {
const user = await response.json();
dispatch(sessionActions.updateUser(user));
- history.push('/');
+ navigate('/');
} else {
throw Error(await response.text());
}
@@ -136,7 +136,7 @@ const LoginPage = () => {
</Grid>
<Grid item container spacing={2}>
<Grid item>
- <Button onClick={() => history.push('/register')} disabled={!registrationEnabled} color="secondary">
+ <Button onClick={() => navigate('/register')} disabled={!registrationEnabled} color="secondary">
{t('loginRegister')}
</Button>
</Grid>
@@ -152,7 +152,7 @@ const LoginPage = () => {
{emailEnabled && (
<Grid item container justifyContent="flex-end">
<Grid item>
- <Link onClick={() => history.push('/reset-password')} className={classes.resetPassword} underline="none">{t('loginReset')}</Link>
+ <Link onClick={() => navigate('/reset-password')} className={classes.resetPassword} underline="none">{t('loginReset')}</Link>
</Grid>
</Grid>
)}
diff --git a/modern/src/login/RegisterPage.js b/modern/src/login/RegisterPage.js
index 78728b58..5fa061bb 100644
--- a/modern/src/login/RegisterPage.js
+++ b/modern/src/login/RegisterPage.js
@@ -2,7 +2,7 @@ import React, { useState } from 'react';
import {
Grid, Button, TextField, Typography, Link, makeStyles, Snackbar,
} from '@material-ui/core';
-import { useHistory } from 'react-router-dom';
+import { useNavigate } from 'react-router-dom';
import ArrowBackIcon from '@material-ui/icons/ArrowBack';
import LoginLayout from './LoginLayout';
import { useTranslation } from '../common/components/LocalizationProvider';
@@ -26,7 +26,7 @@ const useStyles = makeStyles((theme) => ({
const RegisterPage = () => {
const classes = useStyles();
- const history = useHistory();
+ const navigate = useNavigate();
const t = useTranslation();
const [name, setName] = useState('');
@@ -51,7 +51,7 @@ const RegisterPage = () => {
<LoginLayout>
<Snackbar
open={snackbarOpen}
- onClose={() => history.push('/login')}
+ onClose={() => navigate('/login')}
autoHideDuration={snackBarDurationShortMs}
message={t('loginCreated')}
/>
@@ -59,7 +59,7 @@ const RegisterPage = () => {
<Grid container item>
<Grid item>
<Typography className={classes.link} color="primary">
- <Link onClick={() => history.push('/login')}>
+ <Link onClick={() => navigate('/login')}>
<ArrowBackIcon />
</Link>
</Typography>
diff --git a/modern/src/login/ResetPasswordPage.js b/modern/src/login/ResetPasswordPage.js
index 93e154e3..acdf13ab 100644
--- a/modern/src/login/ResetPasswordPage.js
+++ b/modern/src/login/ResetPasswordPage.js
@@ -2,7 +2,7 @@ import React, { useState } from 'react';
import {
Grid, Button, TextField, Typography, Link, makeStyles, Snackbar,
} from '@material-ui/core';
-import { useHistory } from 'react-router-dom';
+import { useNavigate } from 'react-router-dom';
import ArrowBackIcon from '@material-ui/icons/ArrowBack';
import LoginLayout from './LoginLayout';
import { useTranslation } from '../common/components/LocalizationProvider';
@@ -27,7 +27,7 @@ const useStyles = makeStyles((theme) => ({
const ResetPasswordPage = () => {
const classes = useStyles();
- const history = useHistory();
+ const navigate = useNavigate();
const t = useTranslation();
const query = useQuery();
@@ -62,7 +62,7 @@ const ResetPasswordPage = () => {
<LoginLayout>
<Snackbar
open={snackbarOpen}
- onClose={() => history.push('/login')}
+ onClose={() => navigate('/login')}
autoHideDuration={snackBarDurationShortMs}
message={!token ? t('loginResetSuccess') : t('loginUpdateSuccess')}
/>
@@ -70,7 +70,7 @@ const ResetPasswordPage = () => {
<Grid container item>
<Grid item>
<Typography className={classes.link} color="primary">
- <Link onClick={() => history.push('/login')}>
+ <Link onClick={() => navigate('/login')}>
<ArrowBackIcon />
</Link>
</Typography>
diff --git a/modern/src/main/MainPage.js b/modern/src/main/MainPage.js
index 61c10d81..346919e2 100644
--- a/modern/src/main/MainPage.js
+++ b/modern/src/main/MainPage.js
@@ -1,5 +1,5 @@
import React, { useState, useEffect } from 'react';
-import { useHistory } from 'react-router-dom';
+import { useNavigate } from 'react-router-dom';
import {
makeStyles, Paper, Toolbar, TextField, IconButton, Button,
} from '@material-ui/core';
@@ -115,7 +115,7 @@ const useStyles = makeStyles((theme) => ({
const MainPage = () => {
const classes = useStyles();
- const history = useHistory();
+ const navigate = useNavigate();
const dispatch = useDispatch();
const theme = useTheme();
const t = useTranslation();
@@ -178,7 +178,7 @@ const MainPage = () => {
placeholder={t('sharedSearchDevices')}
variant="filled"
/>
- <IconButton onClick={() => history.push('/settings/device')} disabled={deviceReadonly}>
+ <IconButton onClick={() => navigate('/settings/device')} disabled={deviceReadonly}>
<AddIcon />
</IconButton>
{desktop && (
diff --git a/modern/src/main/StatusCard.js b/modern/src/main/StatusCard.js
index d23bc8c3..92db8047 100644
--- a/modern/src/main/StatusCard.js
+++ b/modern/src/main/StatusCard.js
@@ -1,6 +1,6 @@
import React, { useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
-import { useHistory } from 'react-router-dom';
+import { useNavigate } from 'react-router-dom';
import {
makeStyles, Card, CardContent, Typography, CardActions, CardHeader, IconButton, Avatar, Table, TableBody, TableRow, TableCell, TableContainer,
} from '@material-ui/core';
@@ -65,7 +65,7 @@ const StatusRow = ({ name, content }) => {
const StatusCard = ({ deviceId, onClose }) => {
const classes = useStyles();
- const history = useHistory();
+ const navigate = useNavigate();
const dispatch = useDispatch();
const t = useTranslation();
@@ -134,16 +134,16 @@ const StatusCard = ({ deviceId, onClose }) => {
</CardContent>
)}
<CardActions classes={{ root: classes.actions }} disableSpacing>
- <IconButton onClick={() => history.push(`/position/${position.id}`)} disabled={!position} color="secondary">
+ <IconButton onClick={() => navigate(`/position/${position.id}`)} disabled={!position} color="secondary">
<PostAddIcon />
</IconButton>
- <IconButton onClick={() => history.push('/replay')} disabled={!position}>
+ <IconButton onClick={() => navigate('/replay')} disabled={!position}>
<ReplayIcon />
</IconButton>
- <IconButton onClick={() => history.push(`/settings/command-send/${deviceId}`)} disabled={readonly}>
+ <IconButton onClick={() => navigate(`/settings/command-send/${deviceId}`)} disabled={readonly}>
<PublishIcon />
</IconButton>
- <IconButton onClick={() => history.push(`/settings/device/${deviceId}`)} disabled={deviceReadonly}>
+ <IconButton onClick={() => navigate(`/settings/device/${deviceId}`)} disabled={deviceReadonly}>
<EditIcon />
</IconButton>
<IconButton onClick={() => setRemoving(true)} disabled={deviceReadonly} className={classes.negative}>
diff --git a/modern/src/map/MapGeofenceEdit.js b/modern/src/map/MapGeofenceEdit.js
index c64eb736..0b5062d8 100644
--- a/modern/src/map/MapGeofenceEdit.js
+++ b/modern/src/map/MapGeofenceEdit.js
@@ -5,7 +5,7 @@ import theme from '@mapbox/mapbox-gl-draw/src/lib/theme';
import { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
-import { useHistory } from 'react-router-dom';
+import { useNavigate } from 'react-router-dom';
import { map } from './core/Map';
import { geofenceToFeature, geometryToArea } from './core/mapUtil';
import { errorsActions, geofencesActions } from '../store';
@@ -36,7 +36,7 @@ const draw = new MapboxDraw({
const MapGeofenceEdit = () => {
const dispatch = useDispatch();
- const history = useHistory();
+ const navigate = useNavigate();
const geofences = useSelector((state) => state.geofences.items);
@@ -69,7 +69,7 @@ const MapGeofenceEdit = () => {
});
if (response.ok) {
const item = await response.json();
- history.push(`/settings/geofence/${item.id}`);
+ navigate(`/settings/geofence/${item.id}`);
} else {
throw Error(await response.text());
}
@@ -80,7 +80,7 @@ const MapGeofenceEdit = () => {
map.on('draw.create', listener);
return () => map.off('draw.create', listener);
- }, [dispatch, history]);
+ }, [dispatch, navigate]);
useEffect(() => {
const listener = async (event) => {
diff --git a/modern/src/other/EventPage.js b/modern/src/other/EventPage.js
index c688e62a..9f5f7c84 100644
--- a/modern/src/other/EventPage.js
+++ b/modern/src/other/EventPage.js
@@ -4,7 +4,7 @@ import {
makeStyles, Typography, AppBar, Toolbar, IconButton,
} from '@material-ui/core';
import ArrowBackIcon from '@material-ui/icons/ArrowBack';
-import { useHistory, useParams } from 'react-router-dom';
+import { useNavigate, useParams } from 'react-router-dom';
import { useEffectAsync } from '../reactHelper';
import { useTranslation } from '../common/components/LocalizationProvider';
import Map from '../map/core/Map';
@@ -23,7 +23,7 @@ const useStyles = makeStyles(() => ({
const EventPage = () => {
const classes = useStyles();
- const history = useHistory();
+ const navigate = useNavigate();
const t = useTranslation();
const { id } = useParams();
@@ -60,7 +60,7 @@ const EventPage = () => {
<div className={classes.root}>
<AppBar color="inherit" position="static">
<Toolbar>
- <IconButton color="inherit" edge="start" onClick={() => history.push('/')}>
+ <IconButton color="inherit" edge="start" onClick={() => navigate('/')}>
<ArrowBackIcon />
</IconButton>
<Typography variant="h6">{t('positionEvent')}</Typography>
diff --git a/modern/src/other/GeofencesPage.js b/modern/src/other/GeofencesPage.js
index 98833cc7..80e23cba 100644
--- a/modern/src/other/GeofencesPage.js
+++ b/modern/src/other/GeofencesPage.js
@@ -5,7 +5,7 @@ import {
import { useTheme } from '@material-ui/core/styles';
import Drawer from '@material-ui/core/Drawer';
import ArrowBackIcon from '@material-ui/icons/ArrowBack';
-import { useHistory } from 'react-router-dom';
+import { useNavigate } from 'react-router-dom';
import Map from '../map/core/Map';
import MapCurrentLocation from '../map/MapCurrentLocation';
import MapGeofenceEdit from '../map/MapGeofenceEdit';
@@ -51,7 +51,7 @@ const useStyles = makeStyles((theme) => ({
const GeofencesPage = () => {
const theme = useTheme();
const classes = useStyles();
- const history = useHistory();
+ const navigate = useNavigate();
const t = useTranslation();
const isPhone = useMediaQuery(theme.breakpoints.down('xs'));
@@ -65,7 +65,7 @@ const GeofencesPage = () => {
classes={{ paper: classes.drawerPaper }}
>
<div className={classes.drawerHeader}>
- <IconButton onClick={() => history.goBack()}>
+ <IconButton onClick={() => navigate(-1)}>
<ArrowBackIcon />
</IconButton>
<Typography variant="h6" color="inherit" noWrap>
diff --git a/modern/src/other/PositionPage.js b/modern/src/other/PositionPage.js
index 76bb560f..8188f669 100644
--- a/modern/src/other/PositionPage.js
+++ b/modern/src/other/PositionPage.js
@@ -5,7 +5,7 @@ import {
makeStyles, Typography, Container, Paper, AppBar, Toolbar, IconButton, Table, TableHead, TableRow, TableCell, TableBody,
} from '@material-ui/core';
import ArrowBackIcon from '@material-ui/icons/ArrowBack';
-import { useHistory, useParams } from 'react-router-dom';
+import { useNavigate, useParams } from 'react-router-dom';
import { useEffectAsync } from '../reactHelper';
import { prefixString } from '../common/util/stringUtils';
import { useTranslation } from '../common/components/LocalizationProvider';
@@ -26,7 +26,7 @@ const useStyles = makeStyles((theme) => ({
const PositionPage = () => {
const classes = useStyles();
- const history = useHistory();
+ const navigate = useNavigate();
const t = useTranslation();
const { id } = useParams();
@@ -63,7 +63,7 @@ const PositionPage = () => {
<div className={classes.root}>
<AppBar position="sticky" color="inherit">
<Toolbar>
- <IconButton color="inherit" edge="start" onClick={() => history.goBack()}>
+ <IconButton color="inherit" edge="start" onClick={() => navigate(-1)}>
<ArrowBackIcon />
</IconButton>
<Typography variant="h6">
diff --git a/modern/src/other/ReplayPage.js b/modern/src/other/ReplayPage.js
index 5e759d7e..c95240be 100644
--- a/modern/src/other/ReplayPage.js
+++ b/modern/src/other/ReplayPage.js
@@ -10,7 +10,7 @@ import PlayArrowIcon from '@material-ui/icons/PlayArrow';
import PauseIcon from '@material-ui/icons/Pause';
import FastForwardIcon from '@material-ui/icons/FastForward';
import FastRewindIcon from '@material-ui/icons/FastRewind';
-import { useHistory } from 'react-router-dom';
+import { useNavigate } from 'react-router-dom';
import { useSelector } from 'react-redux';
import Map from '../map/core/Map';
import MapReplayPath from '../map/MapReplayPath';
@@ -78,7 +78,7 @@ const TimeLabel = ({ children, open, value }) => (
const ReplayPage = () => {
const t = useTranslation();
const classes = useStyles();
- const history = useHistory();
+ const navigate = useNavigate();
const timerRef = useRef();
const defaultDeviceId = useSelector((state) => state.devices.selectedId);
@@ -100,8 +100,8 @@ const ReplayPage = () => {
});
const onClick = useCallback((positionId) => {
- history.push(`/position/${positionId}`);
- }, [history]);
+ navigate(`/position/${positionId}`);
+ }, [navigate]);
useEffect(() => {
if (playing && positions.length > 0) {
@@ -146,7 +146,7 @@ const ReplayPage = () => {
<div className={classes.sidebar}>
<Paper elevation={3} square>
<Toolbar>
- <IconButton onClick={() => history.push('/')}>
+ <IconButton onClick={() => navigate('/')}>
<ArrowBackIcon />
</IconButton>
<Typography variant="h6" className={classes.title}>{t('reportReplay')}</Typography>
diff --git a/modern/src/settings/AccumulatorsPage.js b/modern/src/settings/AccumulatorsPage.js
index b22fe02e..8ca9d277 100644
--- a/modern/src/settings/AccumulatorsPage.js
+++ b/modern/src/settings/AccumulatorsPage.js
@@ -1,6 +1,6 @@
import React, { useEffect, useState } from 'react';
import { useSelector } from 'react-redux';
-import { useHistory, useParams } from 'react-router-dom';
+import { useNavigate, useParams } from 'react-router-dom';
import {
Accordion, AccordionSummary, AccordionDetails, makeStyles, Typography, Container, TextField, FormControl, Button,
} from '@material-ui/core';
@@ -27,7 +27,7 @@ const useStyles = makeStyles((theme) => ({
}));
const AccumulatorsPage = () => {
- const history = useHistory();
+ const navigate = useNavigate();
const classes = useStyles();
const t = useTranslation();
@@ -54,7 +54,7 @@ const AccumulatorsPage = () => {
});
if (response.ok) {
- history.goBack();
+ navigate(-1);
} else {
throw Error(await response.text());
}
@@ -95,7 +95,7 @@ const AccumulatorsPage = () => {
type="button"
color="primary"
variant="outlined"
- onClick={() => history.goBack()}
+ onClick={() => navigate(-1)}
>
{t('sharedCancel')}
</Button>
diff --git a/modern/src/settings/CommandSendPage.js b/modern/src/settings/CommandSendPage.js
index cc0dae63..98415a5e 100644
--- a/modern/src/settings/CommandSendPage.js
+++ b/modern/src/settings/CommandSendPage.js
@@ -1,5 +1,5 @@
import React, { useState } from 'react';
-import { useHistory, useParams } from 'react-router-dom';
+import { useNavigate, useParams } from 'react-router-dom';
import {
Accordion, AccordionSummary, AccordionDetails, makeStyles, Typography, Container, Button, FormControl,
} from '@material-ui/core';
@@ -28,7 +28,7 @@ const useStyles = makeStyles((theme) => ({
}));
const CommandSendPage = () => {
- const history = useHistory();
+ const navigate = useNavigate();
const classes = useStyles();
const t = useTranslation();
@@ -59,7 +59,7 @@ const CommandSendPage = () => {
});
if (response.ok) {
- history.goBack();
+ navigate(-1);
} else {
throw Error(await response.text());
}
@@ -98,7 +98,7 @@ const CommandSendPage = () => {
type="button"
color="primary"
variant="outlined"
- onClick={() => history.goBack()}
+ onClick={() => navigate(-1)}
>
{t('sharedCancel')}
</Button>
diff --git a/modern/src/settings/ServerPage.js b/modern/src/settings/ServerPage.js
index b745cb96..53feb8ba 100644
--- a/modern/src/settings/ServerPage.js
+++ b/modern/src/settings/ServerPage.js
@@ -5,7 +5,7 @@ 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 { useNavigate } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux';
import { sessionActions } from '../store';
import EditAttributesView from './components/EditAttributesView';
@@ -35,7 +35,7 @@ const useStyles = makeStyles((theme) => ({
const ServerPage = () => {
const classes = useStyles();
- const history = useHistory();
+ const navigate = useNavigate();
const dispatch = useDispatch();
const t = useTranslation();
@@ -54,7 +54,7 @@ const ServerPage = () => {
if (response.ok) {
dispatch(sessionActions.updateServer(await response.json()));
- history.goBack();
+ navigate(-1);
} else {
throw Error(await response.text());
}
@@ -229,7 +229,7 @@ const ServerPage = () => {
)}
<FormControl fullWidth margin="normal">
<div className={classes.buttons}>
- <Button type="button" color="primary" variant="outlined" onClick={() => history.goBack()}>
+ <Button type="button" color="primary" variant="outlined" onClick={() => navigate(-1)}>
{t('sharedCancel')}
</Button>
<Button type="button" color="primary" variant="contained" onClick={handleSave}>
diff --git a/modern/src/settings/components/CollectionActions.js b/modern/src/settings/components/CollectionActions.js
index 98226269..3fef1203 100644
--- a/modern/src/settings/components/CollectionActions.js
+++ b/modern/src/settings/components/CollectionActions.js
@@ -1,21 +1,21 @@
import React, { useState } from 'react';
import { IconButton, Menu, MenuItem } from '@material-ui/core';
import MoreVertIcon from '@material-ui/icons/MoreVert';
-import { useHistory } from 'react-router-dom';
+import { useNavigate } from 'react-router-dom';
import RemoveDialog from '../../common/components/RemoveDialog';
import { useTranslation } from '../../common/components/LocalizationProvider';
const CollectionActions = ({
itemId, editPath, endpoint, setTimestamp,
}) => {
- const history = useHistory();
+ const navigate = useNavigate();
const t = useTranslation();
const [menuAnchorEl, setMenuAnchorEl] = useState(null);
const [removing, setRemoving] = useState(false);
const handleEdit = () => {
- history.push(`${editPath}/${itemId}`);
+ navigate(`${editPath}/${itemId}`);
setMenuAnchorEl(null);
};
diff --git a/modern/src/settings/components/CollectionFab.js b/modern/src/settings/components/CollectionFab.js
index f52bed38..36435cd9 100644
--- a/modern/src/settings/components/CollectionFab.js
+++ b/modern/src/settings/components/CollectionFab.js
@@ -1,7 +1,7 @@
import React from 'react';
import { Fab, makeStyles } from '@material-ui/core';
import AddIcon from '@material-ui/icons/Add';
-import { useHistory } from 'react-router-dom';
+import { useNavigate } from 'react-router-dom';
import { useReadonly } from '../../common/util/permissions';
import dimensions from '../../common/theme/dimensions';
@@ -18,13 +18,13 @@ const useStyles = makeStyles((theme) => ({
const CollectionFab = ({ editPath, disabled }) => {
const classes = useStyles();
- const history = useHistory();
+ const navigate = useNavigate();
const readonly = useReadonly();
if (!readonly && !disabled) {
return (
- <Fab size="medium" color="primary" className={classes.fab} onClick={() => history.push(editPath)}>
+ <Fab size="medium" color="primary" className={classes.fab} onClick={() => navigate(editPath)}>
<AddIcon />
</Fab>
);
diff --git a/modern/src/settings/components/EditItemView.js b/modern/src/settings/components/EditItemView.js
index 28598e77..d0a3dde5 100644
--- a/modern/src/settings/components/EditItemView.js
+++ b/modern/src/settings/components/EditItemView.js
@@ -1,5 +1,5 @@
import React from 'react';
-import { useHistory, useParams } from 'react-router-dom';
+import { useNavigate, useParams } from 'react-router-dom';
import { makeStyles } from '@material-ui/core/styles';
import Container from '@material-ui/core/Container';
import Button from '@material-ui/core/Button';
@@ -25,7 +25,7 @@ const useStyles = makeStyles((theme) => ({
const EditItemView = ({
children, endpoint, item, setItem, defaultItem, validate, onItemSaved, menu, breadcrumbs,
}) => {
- const history = useHistory();
+ const navigate = useNavigate();
const classes = useStyles();
const t = useTranslation();
@@ -60,7 +60,7 @@ const EditItemView = ({
if (onItemSaved) {
onItemSaved(await response.json());
}
- history.goBack();
+ navigate(-1);
} else {
throw Error(await response.text());
}
@@ -76,7 +76,7 @@ const EditItemView = ({
type="button"
color="primary"
variant="outlined"
- onClick={() => history.goBack()}
+ onClick={() => navigate(-1)}
>
{t('sharedCancel')}
</Button>