diff options
Diffstat (limited to 'modern')
-rw-r--r-- | modern/package.json | 2 | ||||
-rw-r--r-- | modern/src/DevicesList.js | 70 | ||||
-rw-r--r-- | modern/src/MainPage.js | 3 | ||||
-rw-r--r-- | modern/src/map/GeofenceEditMap.js | 28 | ||||
-rw-r--r-- | modern/src/map/PositionsMap.js | 8 | ||||
-rw-r--r-- | modern/src/reports/ReportLayoutPage.js | 2 | ||||
-rw-r--r-- | modern/src/settings/MaintenancePage.js | 4 |
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; |