aboutsummaryrefslogtreecommitdiff
path: root/modern
diff options
context:
space:
mode:
Diffstat (limited to 'modern')
-rw-r--r--modern/package.json2
-rw-r--r--modern/src/DevicesList.js70
-rw-r--r--modern/src/MainPage.js3
-rw-r--r--modern/src/map/GeofenceEditMap.js28
-rw-r--r--modern/src/map/PositionsMap.js8
-rw-r--r--modern/src/reports/ReportLayoutPage.js2
-rw-r--r--modern/src/settings/MaintenancePage.js4
7 files changed, 83 insertions, 34 deletions
diff --git a/modern/package.json b/modern/package.json
index b0522408..29c0e47f 100644
--- a/modern/package.json
+++ b/modern/package.json
@@ -22,6 +22,8 @@
"react-redux": "^7.2.1",
"react-router-dom": "^5.2.0",
"react-scripts": "^3.4.3",
+ "react-virtualized-auto-sizer": "^1.0.5",
+ "react-window": "^1.8.6",
"recharts": "^2.0.9",
"redux": "^4.0.5",
"typeface-roboto": "0.0.75",
diff --git a/modern/src/DevicesList.js b/modern/src/DevicesList.js
index 976fd84a..f66d717d 100644
--- a/modern/src/DevicesList.js
+++ b/modern/src/DevicesList.js
@@ -10,6 +10,8 @@ import ListItemAvatar from '@material-ui/core/ListItemAvatar';
import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction';
import ListItemText from '@material-ui/core/ListItemText';
import MoreVertIcon from '@material-ui/icons/MoreVert';
+import { FixedSizeList } from 'react-window';
+import AutoSizer from 'react-virtualized-auto-sizer';
import { devicesActions } from './store';
import EditCollectionView from './EditCollectionView';
@@ -18,7 +20,6 @@ import { useEffectAsync } from './reactHelper';
const useStyles = makeStyles(() => ({
list: {
maxHeight: '100%',
- overflow: 'auto',
},
icon: {
width: '25px',
@@ -27,6 +28,35 @@ const useStyles = makeStyles(() => ({
},
}));
+const DeviceRow = ({ data, index, style }) => {
+ const classes = useStyles();
+ const dispatch = useDispatch();
+
+ const { items, onMenuClick } = data;
+ const item = items[index];
+
+ return (
+ <div style={style}>
+ <Fragment key={index}>
+ <ListItem button key={item.id} onClick={() => dispatch(devicesActions.select(item))}>
+ <ListItemAvatar>
+ <Avatar>
+ <img className={classes.icon} src={`images/icon/${item.category || 'default'}.svg`} alt="" />
+ </Avatar>
+ </ListItemAvatar>
+ <ListItemText primary={item.name} secondary={item.uniqueId} />
+ <ListItemSecondaryAction>
+ <IconButton onClick={(event) => onMenuClick(event.currentTarget, item.id)}>
+ <MoreVertIcon />
+ </IconButton>
+ </ListItemSecondaryAction>
+ </ListItem>
+ {index < items.length - 1 ? <Divider /> : null}
+ </Fragment>
+ </div>
+ );
+};
+
const DeviceView = ({ updateTimestamp, onMenuClick }) => {
const classes = useStyles();
const dispatch = useDispatch();
@@ -41,33 +71,27 @@ const DeviceView = ({ updateTimestamp, onMenuClick }) => {
}, [updateTimestamp]);
return (
- <List className={classes.list}>
- {items.map((item, index, list) => (
- <Fragment key={item.id}>
- <ListItem button key={item.id} onClick={() => dispatch(devicesActions.select(item))}>
- <ListItemAvatar>
- <Avatar>
- <img className={classes.icon} src={`images/icon/${item.category || 'default'}.svg`} alt="" />
- </Avatar>
- </ListItemAvatar>
- <ListItemText primary={item.name} secondary={item.uniqueId} />
- <ListItemSecondaryAction>
- <IconButton onClick={(event) => onMenuClick(event.currentTarget, item.id)}>
- <MoreVertIcon />
- </IconButton>
- </ListItemSecondaryAction>
- </ListItem>
- {index < list.length - 1 ? <Divider /> : null}
- </Fragment>
- ))}
- </List>
+ <AutoSizer className={classes.list}>
+ {({ height, width }) => (
+ <List disablePadding>
+ <FixedSizeList
+ width={width}
+ height={height}
+ itemCount={items.length}
+ itemData={{ items, onMenuClick }}
+ itemSize={72 + 1} >
+ {DeviceRow}
+ </FixedSizeList>
+ </List>
+ )}
+ </AutoSizer>
);
-}
+};
const DevicesList = () => {
return (
<EditCollectionView content={DeviceView} editPath="/device" endpoint="devices" />
);
-}
+};
export default DevicesList;
diff --git a/modern/src/MainPage.js b/modern/src/MainPage.js
index b6b5044c..8d0b18d2 100644
--- a/modern/src/MainPage.js
+++ b/modern/src/MainPage.js
@@ -33,7 +33,8 @@ const useStyles = makeStyles(theme => ({
},
[theme.breakpoints.down('xs')]: {
height: 250,
- }
+ },
+ overflow: 'hidden',
},
mapContainer: {
flexGrow: 1,
diff --git a/modern/src/map/GeofenceEditMap.js b/modern/src/map/GeofenceEditMap.js
index 291cab75..fe843382 100644
--- a/modern/src/map/GeofenceEditMap.js
+++ b/modern/src/map/GeofenceEditMap.js
@@ -1,5 +1,6 @@
import '@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css'
import MapboxDraw from '@mapbox/mapbox-gl-draw';
+import theme from '@mapbox/mapbox-gl-draw/src/lib/theme';
import { useEffect } from 'react';
import { map } from './Map';
@@ -14,6 +15,21 @@ const draw = new MapboxDraw({
polygon: true,
trash: true,
},
+ userProperties: true,
+ styles: [...theme, {
+ 'id': 'gl-draw-title',
+ 'type': 'symbol',
+ 'filter': ['all'],
+ 'layout': {
+ 'text-field': '{user_name}',
+ 'text-font': ['Roboto Regular'],
+ 'text-size': 12,
+ },
+ 'paint': {
+ 'text-halo-color': 'white',
+ 'text-halo-width': 1,
+ },
+ }],
});
const GeofenceEditMap = () => {
@@ -34,11 +50,6 @@ const GeofenceEditMap = () => {
map.addControl(draw, 'top-left');
- draw.deleteAll();
- for (const geofence of geofences) {
- draw.add(geofenceToFeature(geofence));
- }
-
map.on('draw.create', async event => {
const feature = event.features[0];
const newItem = { name: '', area: geometryToArea(feature.geometry) };
@@ -81,6 +92,13 @@ const GeofenceEditMap = () => {
return () => map.removeControl(draw);
}, []);
+ useEffect(() => {
+ draw.deleteAll();
+ for (const geofence of geofences) {
+ draw.add(geofenceToFeature(geofence));
+ }
+ }, [geofences]);
+
return null;
}
diff --git a/modern/src/map/PositionsMap.js b/modern/src/map/PositionsMap.js
index a953ce3d..baa801fb 100644
--- a/modern/src/map/PositionsMap.js
+++ b/modern/src/map/PositionsMap.js
@@ -27,11 +27,11 @@ const PositionsMap = ({ positions }) => {
};
const createFeature = (devices, position) => {
- const device = devices[position.deviceId] || null;
+ const device = devices[position.deviceId];
return {
deviceId: position.deviceId,
- name: device ? device.name : '',
- category: device && (device.category || 'default'),
+ name: device.name,
+ category: device.category || 'default',
color: deviceColor(device),
}
};
@@ -147,7 +147,7 @@ const PositionsMap = ({ positions }) => {
useEffect(() => {
map.getSource(id).setData({
type: 'FeatureCollection',
- features: positions.map(position => ({
+ features: positions.filter(it => devices.hasOwnProperty(it.deviceId)).map(position => ({
type: 'Feature',
geometry: {
type: 'Point',
diff --git a/modern/src/reports/ReportLayoutPage.js b/modern/src/reports/ReportLayoutPage.js
index fafffc72..6bab67c6 100644
--- a/modern/src/reports/ReportLayoutPage.js
+++ b/modern/src/reports/ReportLayoutPage.js
@@ -75,7 +75,7 @@ const ReportLayoutPage = ({ children, filter, }) => {
break;
}
});
- }, []);
+ }, [location]);
return (
<div className={classes.root}>
diff --git a/modern/src/settings/MaintenancePage.js b/modern/src/settings/MaintenancePage.js
index 9263ee30..3b4fde54 100644
--- a/modern/src/settings/MaintenancePage.js
+++ b/modern/src/settings/MaintenancePage.js
@@ -64,6 +64,8 @@ const MaintenancePage = () => {
return speedFromKnots(value, speedUnit);
case 'distance':
return distanceFromMeters(value, distanceUnit);
+ default:
+ return value;
}
}
return value;
@@ -78,6 +80,8 @@ const MaintenancePage = () => {
return speedToKnots(value, speedUnit);
case 'distance':
return distanceToMeters(value, distanceUnit);
+ default:
+ return value;
}
}
return value;