diff options
author | Anton Tananaev <anton@traccar.org> | 2022-10-23 08:25:18 -0700 |
---|---|---|
committer | Anton Tananaev <anton@traccar.org> | 2022-10-23 08:25:18 -0700 |
commit | 0a89d1ecae4e70b7c694b85b1696bf0c24b5c8d1 (patch) | |
tree | ca7944be8e954057fe4e9d4a1db3f3c0c29af393 /modern/src/main | |
parent | 0510fac36d0d852984b567104e2c9f0df9906492 (diff) | |
download | trackermap-web-0a89d1ecae4e70b7c694b85b1696bf0c24b5c8d1.tar.gz trackermap-web-0a89d1ecae4e70b7c694b85b1696bf0c24b5c8d1.tar.bz2 trackermap-web-0a89d1ecae4e70b7c694b85b1696bf0c24b5c8d1.zip |
Implement filter popover
Diffstat (limited to 'modern/src/main')
-rw-r--r-- | modern/src/main/DeviceList.js | 25 | ||||
-rw-r--r-- | modern/src/main/DeviceRow.js | 7 | ||||
-rw-r--r-- | modern/src/main/MainPage.js | 1 | ||||
-rw-r--r-- | modern/src/main/MainToolbar.js | 47 |
4 files changed, 53 insertions, 27 deletions
diff --git a/modern/src/main/DeviceList.js b/modern/src/main/DeviceList.js index 6672ac46..eb51232f 100644 --- a/modern/src/main/DeviceList.js +++ b/modern/src/main/DeviceList.js @@ -1,7 +1,6 @@ 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'; @@ -48,19 +47,17 @@ const DeviceList = ({ devices }) => { return ( <AutoSizer className={classes.list}> {({ height, width }) => ( - <List disablePadding> - <FixedSizeList - width={width} - height={height} - itemCount={devices.length} - itemData={devices} - itemSize={72} - overscanCount={10} - innerRef={listInnerEl} - > - {DeviceRow} - </FixedSizeList> - </List> + <FixedSizeList + width={width} + height={height} + itemCount={devices.length} + itemData={devices} + itemSize={72} + overscanCount={10} + innerRef={listInnerEl} + > + {DeviceRow} + </FixedSizeList> )} </AutoSizer> ); diff --git a/modern/src/main/DeviceRow.js b/modern/src/main/DeviceRow.js index 978813b4..11dbfdcb 100644 --- a/modern/src/main/DeviceRow.js +++ b/modern/src/main/DeviceRow.js @@ -28,12 +28,6 @@ const useStyles = makeStyles((theme) => ({ height: '25px', filter: 'brightness(0) invert(1)', }, - listItem: { - backgroundColor: 'white', - '&:hover': { - backgroundColor: 'white', - }, - }, batteryText: { fontSize: '0.75rem', fontWeight: 'normal', @@ -98,7 +92,6 @@ const DeviceRow = ({ data, index, style }) => { <div style={style}> <ListItemButton key={item.id} - className={classes.listItem} onClick={() => dispatch(devicesActions.select(item.id))} disabled={!admin && item.disabled} > diff --git a/modern/src/main/MainPage.js b/modern/src/main/MainPage.js index a296d5f6..9a21d570 100644 --- a/modern/src/main/MainPage.js +++ b/modern/src/main/MainPage.js @@ -105,6 +105,7 @@ const MainPage = () => { <div className={classes.sidebar}> <Paper square elevation={3} className={classes.header}> <MainToolbar + filteredDevices={filteredDevices} devicesOpen={devicesOpen} setDevicesOpen={setDevicesOpen} filter={filter} diff --git a/modern/src/main/MainToolbar.js b/modern/src/main/MainToolbar.js index 015e86ba..2aa604e8 100644 --- a/modern/src/main/MainToolbar.js +++ b/modern/src/main/MainToolbar.js @@ -2,15 +2,16 @@ import React, { useState, useRef } from 'react'; import { useSelector } from 'react-redux'; import { useNavigate } from 'react-router-dom'; import { - Toolbar, IconButton, OutlinedInput, InputAdornment, Popover, FormControl, InputLabel, Select, MenuItem, FormGroup, FormControlLabel, Checkbox, Badge, + Toolbar, IconButton, OutlinedInput, InputAdornment, Popover, FormControl, InputLabel, Select, MenuItem, FormGroup, FormControlLabel, Checkbox, Badge, ListItemButton, ListItemText, } from '@mui/material'; -import { makeStyles } from '@mui/styles'; +import { makeStyles, useTheme } from '@mui/styles'; import MapIcon from '@mui/icons-material/Map'; import ViewListIcon from '@mui/icons-material/ViewList'; import AddIcon from '@mui/icons-material/Add'; import TuneIcon from '@mui/icons-material/Tune'; import { useTranslation } from '../common/components/LocalizationProvider'; import { useDeviceReadonly } from '../common/util/permissions'; +import DeviceRow from './DeviceRow'; const useStyles = makeStyles((theme) => ({ toolbar: { @@ -27,6 +28,7 @@ const useStyles = makeStyles((theme) => ({ })); const MainToolbar = ({ + filteredDevices, devicesOpen, setDevicesOpen, filter, @@ -37,6 +39,7 @@ const MainToolbar = ({ setFilterMap, }) => { const classes = useStyles(); + const theme = useTheme(); const navigate = useNavigate(); const t = useTranslation(); @@ -45,24 +48,28 @@ const MainToolbar = ({ const groups = useSelector((state) => state.groups.items); const devices = useSelector((state) => state.devices.items); - const filterRef = useRef(); + const toolbarRef = useRef(); + const inputRef = useRef(); const [filterAnchorEl, setFilterAnchorEl] = useState(null); + const [devicesAnchorEl, setDevicesAnchorEl] = useState(null); const deviceStatusCount = (status) => Object.values(devices).filter((d) => d.status === status).length; return ( - <Toolbar className={classes.toolbar}> + <Toolbar ref={toolbarRef} className={classes.toolbar}> <IconButton edge="start" onClick={() => setDevicesOpen(!devicesOpen)}> {devicesOpen ? <MapIcon /> : <ViewListIcon />} </IconButton> <OutlinedInput - ref={filterRef} + ref={inputRef} placeholder={t('sharedSearchDevices')} value={filter.keyword} onChange={(e) => setFilter({ ...filter, keyword: e.target.value })} + onFocus={() => setDevicesAnchorEl(toolbarRef.current)} + onBlur={() => setDevicesAnchorEl(null)} endAdornment={( <InputAdornment position="end"> - <IconButton size="small" edge="end" onClick={() => setFilterAnchorEl(filterRef.current)}> + <IconButton size="small" edge="end" onClick={() => setFilterAnchorEl(inputRef.current)}> <Badge color="info" variant="dot" invisible={!filter.statuses.length && !filter.groups.length}> <TuneIcon fontSize="small" /> </Badge> @@ -73,6 +80,34 @@ const MainToolbar = ({ fullWidth /> <Popover + open={!!devicesAnchorEl && !devicesOpen} + anchorEl={devicesAnchorEl} + onClose={() => setDevicesAnchorEl(null)} + anchorOrigin={{ + vertical: 'bottom', + horizontal: Number(theme.spacing(2).slice(0, -2)), + }} + marginThreshold={0} + PaperProps={{ + style: { width: `calc(${toolbarRef.current?.clientWidth}px - ${theme.spacing(4)})` }, + }} + elevation={1} + disableAutoFocus + disableEnforceFocus + > + {filteredDevices.slice(0, 3).map((_, index) => ( + <DeviceRow data={filteredDevices} index={index} /> + ))} + {filteredDevices.length > 3 && ( + <ListItemButton alignItems="center" onClick={() => setDevicesOpen(true)}> + <ListItemText + primary={t('notificationAlways')} + style={{ textAlign: 'center' }} + /> + </ListItemButton> + )} + </Popover> + <Popover open={!!filterAnchorEl} anchorEl={filterAnchorEl} onClose={() => setFilterAnchorEl(null)} |