diff options
-rw-r--r-- | modern/package.json | 2 | ||||
-rw-r--r-- | modern/src/DevicesList.js | 70 | ||||
-rw-r--r-- | modern/src/MainPage.js | 3 |
3 files changed, 51 insertions, 24 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, |