diff options
Diffstat (limited to 'modern/src/main/DeviceList.js')
-rw-r--r-- | modern/src/main/DeviceList.js | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/modern/src/main/DeviceList.js b/modern/src/main/DeviceList.js new file mode 100644 index 00000000..80104b00 --- /dev/null +++ b/modern/src/main/DeviceList.js @@ -0,0 +1,69 @@ +import React, { useEffect, useRef, useState } from 'react'; +import { useDispatch } from 'react-redux'; +import makeStyles from '@mui/styles/makeStyles'; +import { List } from '@mui/material'; +import { FixedSizeList } from 'react-window'; +import AutoSizer from 'react-virtualized-auto-sizer'; +import { devicesActions } from '../store'; +import { useEffectAsync } from '../reactHelper'; +import DeviceRow from './DeviceRow'; + +const useStyles = makeStyles((theme) => ({ + list: { + maxHeight: '100%', + }, + listInner: { + position: 'relative', + margin: theme.spacing(1.5, 0), + }, +})); + +const DeviceList = ({ devices }) => { + const classes = useStyles(); + const dispatch = useDispatch(); + const listInnerEl = useRef(null); + + if (listInnerEl.current) { + listInnerEl.current.className = classes.listInner; + } + + const [, setTime] = useState(Date.now()); + + useEffect(() => { + const interval = setInterval(() => setTime(Date.now()), 60000); + return () => { + clearInterval(interval); + }; + }, []); + + useEffectAsync(async () => { + const response = await fetch('/api/devices'); + if (response.ok) { + dispatch(devicesActions.refresh(await response.json())); + } else { + throw Error(await response.text()); + } + }, []); + + return ( + <AutoSizer className={classes.list}> + {({ height, width }) => ( + <List disablePadding> + <FixedSizeList + width={width} + height={height} + itemCount={devices.length} + itemData={{ items: devices }} + itemSize={72} + overscanCount={10} + innerRef={listInnerEl} + > + {DeviceRow} + </FixedSizeList> + </List> + )} + </AutoSizer> + ); +}; + +export default DeviceList; |