aboutsummaryrefslogtreecommitdiff
path: root/modern/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'modern/src/main')
-rw-r--r--modern/src/main/DevicesList.js45
-rw-r--r--modern/src/main/MainPage.js35
-rw-r--r--modern/src/main/StatusCard.js82
3 files changed, 101 insertions, 61 deletions
diff --git a/modern/src/main/DevicesList.js b/modern/src/main/DevicesList.js
index 6ff08c6a..06b75715 100644
--- a/modern/src/main/DevicesList.js
+++ b/modern/src/main/DevicesList.js
@@ -1,27 +1,26 @@
import React, { useEffect, useRef, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
-import { makeStyles } from '@material-ui/core/styles';
-import { IconButton, Tooltip } from '@material-ui/core';
-import Avatar from '@material-ui/core/Avatar';
-import List from '@material-ui/core/List';
-import ListItem from '@material-ui/core/ListItem';
-import ListItemAvatar from '@material-ui/core/ListItemAvatar';
-import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction';
-import ListItemText from '@material-ui/core/ListItemText';
+import makeStyles from '@mui/styles/makeStyles';
+import { IconButton, Tooltip } from '@mui/material';
+import Avatar from '@mui/material/Avatar';
+import List from '@mui/material/List';
+import ListItem from '@mui/material/ListItem';
+import ListItemAvatar from '@mui/material/ListItemAvatar';
+import ListItemSecondaryAction from '@mui/material/ListItemSecondaryAction';
+import ListItemText from '@mui/material/ListItemText';
import { FixedSizeList } from 'react-window';
import AutoSizer from 'react-virtualized-auto-sizer';
-import BatteryFullIcon from '@material-ui/icons/BatteryFull';
-import BatteryChargingFullIcon from '@material-ui/icons/BatteryChargingFull';
-import Battery60Icon from '@material-ui/icons/Battery60';
-import BatteryCharging60Icon from '@material-ui/icons/BatteryCharging60';
-import Battery20Icon from '@material-ui/icons/Battery20';
-import BatteryCharging20Icon from '@material-ui/icons/BatteryCharging20';
-import FlashOnIcon from '@material-ui/icons/FlashOn';
-import FlashOffIcon from '@material-ui/icons/FlashOff';
-import ErrorIcon from '@material-ui/icons/Error';
+import BatteryFullIcon from '@mui/icons-material/BatteryFull';
+import BatteryChargingFullIcon from '@mui/icons-material/BatteryChargingFull';
+import Battery60Icon from '@mui/icons-material/Battery60';
+import BatteryCharging60Icon from '@mui/icons-material/BatteryCharging60';
+import Battery20Icon from '@mui/icons-material/Battery20';
+import BatteryCharging20Icon from '@mui/icons-material/BatteryCharging20';
+import FlashOnIcon from '@mui/icons-material/FlashOn';
+import FlashOffIcon from '@mui/icons-material/FlashOff';
+import ErrorIcon from '@mui/icons-material/Error';
import { devicesActions } from '../store';
-import EditCollectionView from '../settings/components/EditCollectionView';
import { useEffectAsync } from '../reactHelper';
import {
formatAlarm, formatBoolean, formatPercentage, formatStatus, getStatusColor,
@@ -139,7 +138,7 @@ const DeviceRow = ({ data, index, style }) => {
);
};
-const DeviceView = ({ updateTimestamp, onMenuClick, filter }) => {
+const DevicesList = ({ filter }) => {
const classes = useStyles();
const dispatch = useDispatch();
const listInnerEl = useRef(null);
@@ -167,7 +166,7 @@ const DeviceView = ({ updateTimestamp, onMenuClick, filter }) => {
} else {
throw Error(await response.text());
}
- }, [updateTimestamp]);
+ }, []);
return (
<AutoSizer className={classes.list}>
@@ -177,7 +176,7 @@ const DeviceView = ({ updateTimestamp, onMenuClick, filter }) => {
width={width}
height={height}
itemCount={filteredItems.length}
- itemData={{ items: filteredItems, onMenuClick }}
+ itemData={{ items: filteredItems }}
itemSize={72}
overscanCount={10}
innerRef={listInnerEl}
@@ -190,8 +189,4 @@ const DeviceView = ({ updateTimestamp, onMenuClick, filter }) => {
);
};
-const DevicesList = ({ filter }) => (
- <EditCollectionView content={DeviceView} editPath="/settings/device" endpoint="devices" disableAdd filter={filter} />
-);
-
export default DevicesList;
diff --git a/modern/src/main/MainPage.js b/modern/src/main/MainPage.js
index 61c10d81..059d7043 100644
--- a/modern/src/main/MainPage.js
+++ b/modern/src/main/MainPage.js
@@ -1,15 +1,17 @@
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';
+ Paper, Toolbar, TextField, IconButton, Button,
+} from '@mui/material';
-import { useTheme } from '@material-ui/core/styles';
-import useMediaQuery from '@material-ui/core/useMediaQuery';
-import AddIcon from '@material-ui/icons/Add';
-import CloseIcon from '@material-ui/icons/Close';
-import ArrowBackIcon from '@material-ui/icons/ArrowBack';
-import ListIcon from '@material-ui/icons/ViewList';
+import makeStyles from '@mui/styles/makeStyles';
+
+import { useTheme } from '@mui/material/styles';
+import useMediaQuery from '@mui/material/useMediaQuery';
+import AddIcon from '@mui/icons-material/Add';
+import CloseIcon from '@mui/icons-material/Close';
+import ArrowBackIcon from '@mui/icons-material/ArrowBack';
+import ListIcon from '@mui/icons-material/ViewList';
import { useDispatch, useSelector } from 'react-redux';
import DevicesList from './DevicesList';
@@ -46,7 +48,7 @@ const useStyles = makeStyles((theme) => ({
bottom: theme.dimensions.bottomBarHeight,
transition: 'transform .5s ease',
backgroundColor: 'white',
- [theme.breakpoints.down('sm')]: {
+ [theme.breakpoints.down('md')]: {
width: '100%',
margin: 0,
},
@@ -54,7 +56,7 @@ const useStyles = makeStyles((theme) => ({
sidebarCollapsed: {
transform: `translateX(-${theme.dimensions.drawerWidthDesktop})`,
marginLeft: 0,
- [theme.breakpoints.down('sm')]: {
+ [theme.breakpoints.down('md')]: {
transform: 'translateX(-100vw)',
},
},
@@ -75,7 +77,7 @@ const useStyles = makeStyles((theme) => ({
left: `calc(50% + ${theme.dimensions.drawerWidthDesktop} / 2)`,
bottom: theme.spacing(3),
},
- [theme.breakpoints.down('sm')]: {
+ [theme.breakpoints.down('md')]: {
left: '50%',
bottom: theme.spacing(3) + theme.dimensions.bottomBarHeight,
},
@@ -87,7 +89,7 @@ const useStyles = makeStyles((theme) => ({
top: theme.spacing(3),
borderRadius: '0px',
minWidth: 0,
- [theme.breakpoints.down('sm')]: {
+ [theme.breakpoints.down('md')]: {
left: 0,
},
},
@@ -115,14 +117,14 @@ const useStyles = makeStyles((theme) => ({
const MainPage = () => {
const classes = useStyles();
- const history = useHistory();
+ const navigate = useNavigate();
const dispatch = useDispatch();
const theme = useTheme();
const t = useTranslation();
const deviceReadonly = useDeviceReadonly();
const desktop = useMediaQuery(theme.breakpoints.up('md'));
- const phone = useMediaQuery(theme.breakpoints.down('xs'));
+ const phone = useMediaQuery(theme.breakpoints.down('sm'));
const [mapLiveRoutes] = usePersistedState('mapLiveRoutes', false);
@@ -176,9 +178,8 @@ const MainPage = () => {
autoComplete="searchKeyword"
onChange={(event) => setSearchKeyword(event.target.value)}
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 b470890e..ec33efa2 100644
--- a/modern/src/main/StatusCard.js
+++ b/modern/src/main/StatusCard.js
@@ -1,15 +1,27 @@
import React, { useState } from 'react';
-import { useSelector } from 'react-redux';
-import { useHistory } from 'react-router-dom';
+import { useDispatch, useSelector } from 'react-redux';
+import { useNavigate } from 'react-router-dom';
import {
- makeStyles, Card, CardContent, Typography, CardActions, CardHeader, IconButton, Avatar, Table, TableBody, TableRow, TableCell, TableContainer,
-} from '@material-ui/core';
-import CloseIcon from '@material-ui/icons/Close';
-import PostAddIcon from '@material-ui/icons/PostAdd';
-import ReplayIcon from '@material-ui/icons/Replay';
-import PublishIcon from '@material-ui/icons/Publish';
-import EditIcon from '@material-ui/icons/Edit';
-import DeleteIcon from '@material-ui/icons/Delete';
+ Card,
+ CardContent,
+ Typography,
+ CardActions,
+ CardHeader,
+ IconButton,
+ Avatar,
+ Table,
+ TableBody,
+ TableRow,
+ TableCell,
+ TableContainer,
+} from '@mui/material';
+import makeStyles from '@mui/styles/makeStyles';
+import CloseIcon from '@mui/icons-material/Close';
+import PostAddIcon from '@mui/icons-material/PostAdd';
+import ReplayIcon from '@mui/icons-material/Replay';
+import PublishIcon from '@mui/icons-material/Publish';
+import EditIcon from '@mui/icons-material/Edit';
+import DeleteIcon from '@mui/icons-material/Delete';
import { useTranslation } from '../common/components/LocalizationProvider';
import { formatStatus } from '../common/util/formatter';
@@ -19,6 +31,8 @@ import dimensions from '../common/theme/dimensions';
import { useDeviceReadonly, useReadonly } from '../common/util/permissions';
import usePersistedState from '../common/util/usePersistedState';
import usePositionAttributes from '../common/attributes/usePositionAttributes';
+import { devicesActions } from '../store';
+import { useCatch } from '../reactHelper';
const useStyles = makeStyles((theme) => ({
card: {
@@ -63,7 +77,8 @@ const StatusRow = ({ name, content }) => {
const StatusCard = ({ deviceId, onClose }) => {
const classes = useStyles();
- const history = useHistory();
+ const navigate = useNavigate();
+ const dispatch = useDispatch();
const t = useTranslation();
const readonly = useReadonly();
@@ -75,7 +90,19 @@ const StatusCard = ({ deviceId, onClose }) => {
const positionAttributes = usePositionAttributes(t);
const [positionItems] = usePersistedState('positionItems', ['speed', 'address', 'totalDistance', 'course']);
- const [removeDialogShown, setRemoveDialogShown] = useState(false);
+ const [removing, setRemoving] = useState(false);
+
+ const handleRemove = useCatch(async (removed) => {
+ if (removed) {
+ const response = await fetch('/api/devices');
+ if (response.ok) {
+ dispatch(devicesActions.refresh(await response.json()));
+ } else {
+ throw Error(await response.text());
+ }
+ }
+ setRemoving(false);
+ });
return (
<>
@@ -119,29 +146,46 @@ const StatusCard = ({ deviceId, onClose }) => {
</CardContent>
)}
<CardActions classes={{ root: classes.actions }} disableSpacing>
- <IconButton onClick={() => history.push(`/position/${position.id}`)} disabled={!position} color="secondary">
+ <IconButton
+ color="secondary"
+ onClick={() => navigate(`/position/${position.id}`)}
+ disabled={!position}
+ >
<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={() => setRemoveDialogShown(true)} disabled={deviceReadonly} className={classes.negative}>
+ <IconButton
+ onClick={() => setRemoving(true)}
+ disabled={deviceReadonly}
+ className={classes.negative}
+ >
<DeleteIcon />
</IconButton>
</CardActions>
</Card>
)}
<RemoveDialog
- open={removeDialogShown}
+ open={removing}
endpoint="devices"
itemId={deviceId}
- onResult={() => setRemoveDialogShown(false)}
+ onResult={(removed) => handleRemove(removed)}
/>
</>
);