import React, { useEffect, useRef, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; 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 ListItemText from '@mui/material/ListItemText'; import { FixedSizeList } from 'react-window'; import AutoSizer from 'react-virtualized-auto-sizer'; 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 moment from 'moment'; import { devicesActions } from '../store'; import { useEffectAsync } from '../reactHelper'; import { formatAlarm, formatBoolean, formatPercentage, formatStatus, getStatusColor, } from '../common/util/formatter'; import { useTranslation } from '../common/components/LocalizationProvider'; const useStyles = makeStyles((theme) => ({ list: { maxHeight: '100%', }, listInner: { position: 'relative', margin: theme.spacing(1.5, 0), }, icon: { width: '25px', height: '25px', filter: 'brightness(0) invert(1)', }, listItem: { backgroundColor: 'white', '&:hover': { backgroundColor: 'white', }, }, batteryText: { fontSize: '0.75rem', fontWeight: 'normal', lineHeight: '0.875rem', }, positive: { color: theme.palette.colors.positive, }, medium: { color: theme.palette.colors.medium, }, negative: { color: theme.palette.colors.negative, }, neutral: { color: theme.palette.colors.neutral, }, })); const DeviceRow = ({ data, index, style }) => { const classes = useStyles(); const dispatch = useDispatch(); const t = useTranslation(); const { items } = data; const item = items[index]; const position = useSelector((state) => state.positions.items[item.id]); const secondaryText = () => { if (item.status === 'online' || !item.lastUpdate) { return formatStatus(item.status, t); } else { return moment(item.lastUpdate).fromNow(); } }; return (
dispatch(devicesActions.select(item.id))}> {position && ( <> {position.attributes.hasOwnProperty('alarm') && ( )} {position.attributes.hasOwnProperty('ignition') && ( {position.attributes.ignition ? ( ) : ( )} )} {position.attributes.hasOwnProperty('batteryLevel') && ( {position.attributes.batteryLevel > 70 ? ( position.attributes.charge ? () : () ) : position.attributes.batteryLevel > 30 ? ( position.attributes.charge ? () : () ) : ( position.attributes.charge ? () : () )} )} )}
); }; const DevicesList = ({ filter }) => { const classes = useStyles(); const dispatch = useDispatch(); const listInnerEl = useRef(null); const items = useSelector((state) => state.devices.items); const [filteredItems, setFilteredItems] = useState(null); useEffect(() => { const array = Object.values(items); setFilteredItems( filter.trim().length > 0 ? array.filter((item) => `${item.name} ${item.uniqueId}`.toLowerCase().includes(filter?.toLowerCase())) : array, ); }, [filter, items]); if (listInnerEl.current) { listInnerEl.current.className = classes.listInner; } useEffectAsync(async () => { const response = await fetch('/api/devices'); if (response.ok) { dispatch(devicesActions.refresh(await response.json())); } else { throw Error(await response.text()); } }, []); return ( {({ height, width }) => ( {DeviceRow} )} ); }; export default DevicesList;