diff options
-rw-r--r-- | modern/src/CommandsPage.js | 8 | ||||
-rw-r--r-- | modern/src/DevicesList.js | 94 | ||||
-rw-r--r-- | modern/src/map/StatusView.js | 34 |
3 files changed, 100 insertions, 36 deletions
diff --git a/modern/src/CommandsPage.js b/modern/src/CommandsPage.js index e36c365..1458b43 100644 --- a/modern/src/CommandsPage.js +++ b/modern/src/CommandsPage.js @@ -66,18 +66,19 @@ const CommandsPage = () => { }, [id]); const handleSend = async () => { - console.log ('Selected: ' + selectedCommand); const response = await fetch(`/api/commands/send`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ - id: selectedCommand.id, - deviceId: device.id, + 'id': selectedCommand, + 'deviceId': device.id, }), }); if (response.ok) { history.goBack(); + } else { + console.log ('response!', response); } }; @@ -90,6 +91,7 @@ const CommandsPage = () => { <> <CardContent> <Typography gutterBottom variant="h5">{t('commandSend')}</Typography> + <Typography variant="body2" color="text.secondary">{device.name}</Typography> {commands && ( <FormControl fullWidth aria-label="command"> <RadioGroup onChange={(event) => setSelectedCommand(event.target.value) }> diff --git a/modern/src/DevicesList.js b/modern/src/DevicesList.js index 3c1b44f..fda6f60 100644 --- a/modern/src/DevicesList.js +++ b/modern/src/DevicesList.js @@ -13,10 +13,18 @@ import AutoSizer from 'react-virtualized-auto-sizer'; import BatteryFullIcon from '@material-ui/icons/BatteryFull'; import { ReactComponent as IgnitionIcon } from '../public/images/ignition.svg'; +import FiberManualRecordIcon from '@material-ui/icons/FiberManualRecord'; +import PersonIcon from '@material-ui/icons/Person'; +import SpeedIcon from '@material-ui/icons/Speed'; +import CalendarTodayIcon from '@material-ui/icons/CalendarToday'; +import LockIcon from '@material-ui/icons/Lock'; +import LockOpenIcon from '@material-ui/icons/LockOpen'; + import { devicesActions, uiActions } from './store'; import EditCollectionView from './EditCollectionView'; import { useEffectAsync } from './reactHelper'; -import { formatPosition } from './common/formatter'; +import { formatPosition, formatSpeed, formatDate, formatHours } from './common/formatter'; +import { useAttributePreference } from './common/preferences'; import { getDevices, getFilteredDevices, getPosition } from './common/selectors'; import { useTranslation } from './LocalizationProvider'; @@ -32,12 +40,18 @@ const useStyles = makeStyles((theme) => ({ width: '40px', height: '40px', }, + statusIcon: { + paddingRight: '5px', + }, listItem: { backgroundColor: 'white', '&:hover': { backgroundColor: 'white', }, }, + listItemSecondary: { + fontSize: '0.92rem', + }, batteryText: { fontSize: '0.75rem', fontWeight: 'normal', @@ -84,11 +98,21 @@ const DeviceRow = ({ data, index, style }) => { const dispatch = useDispatch(); const t = useTranslation(); + const speedUnit = useAttributePreference('speedUnit'); + const { items } = data; const item = items[index]; const position = useSelector(getPosition(item.id)); const showIgnition = position?.attributes.hasOwnProperty('ignition') && position.attributes.ignition; + const statusColor = () => { + if (position && position.speed >= 2) { + return 'primary'; + } else { + return 'error'; + } + }; + return ( <div style={style}> <ListItem button key={item.id} className={classes.listItem} onClick={() => { @@ -97,30 +121,60 @@ const DeviceRow = ({ data, index, style }) => { setTimeout (() => { dispatch(devicesActions.unselect()); }, 1000); - }}> + }}> + {/* Avatar */} <ListItemAvatar> <img className={classes.icon} src={`images/icon/${(item.category || 'default').toLowerCase()}.png`} alt="" /> </ListItemAvatar> - <ListItemText primary={item.name} secondary={item.status} classes={{ secondary: classes[getStatusColor(item.status)] }} /> + {/* Status icon */} + + <ListItemText primary={ + <> + <FiberManualRecordIcon fontSize="inherit" color={statusColor()} classes={{ colorPrimary: classes.green }} /> + {position && position.attributes.out1 == false && ( + <LockOpenIcon fontSize="inherit" color="primary" classes={{ colorPrimary: classes.green }} /> + )} + {position && position.attributes.out1 == true && ( + <LockIcon fontSize="inherit" color="error" /> + ) } + {` ${item.name}`} + </>} secondary={( + <> + {/* Contact */} + <PersonIcon fontSize="inherit" /> {item.contact}<br/> + {position && ( + <> + {/* Speed */} + <SpeedIcon fontSize="inherit" /> {formatSpeed(position.speed, speedUnit, t)}<br/> + {/* Datetime */} + <CalendarTodayIcon fontSize="inherit" /> {formatDate(position.serverTime)} + {/* Hours */} + {position.attributes.hours && position.attributes.hours > 1 && ` (${formatHours(position.attributes.hours, t)})`} + </> + )} + </> + )} classes={{ secondary: classes.listItemSecondary }} /> <ListItemSecondaryAction className={classes.indicators}> {position && ( - <Grid container direction="row" alignItems="center" alignContent="center" spacing={2}> - {showIgnition && ( - <Grid item> - <SvgIcon component={IgnitionIcon} /> + <Grid container direction="row" alignItems="center" alignContent="center" spacing={2}> + {/* Ignition */} + {showIgnition && ( + <Grid item> + <SvgIcon component={IgnitionIcon} /> + </Grid> + )} + {/* Battery level */} + {position.attributes.hasOwnProperty('batteryLevel') && ( + <Grid item container xs alignItems="center" alignContent="center"> + <Grid item> + <span className={classes.batteryText}>{formatPosition(position.attributes.batteryLevel, 'batteryLevel', t)}</span> + </Grid> + <Grid item> + <BatteryFullIcon className={classes[getBatteryStatus(position.attributes.batteryLevel)]} /> + </Grid> + </Grid> + )} </Grid> - )} - {position.attributes.hasOwnProperty('batteryLevel') && ( - <Grid item container xs alignItems="center" alignContent="center"> - <Grid item> - <span className={classes.batteryText}>{formatPosition(position.attributes.batteryLevel, 'batteryLevel', t)}</span> - </Grid> - <Grid item> - <BatteryFullIcon className={classes[getBatteryStatus(position.attributes.batteryLevel)]} /> - </Grid> - </Grid> - )} - </Grid> )} </ListItemSecondaryAction> </ListItem> @@ -158,7 +212,7 @@ const DeviceView = ({ updateTimestamp, onMenuClick }) => { height={height} itemCount={items.length} itemData={{items, onMenuClick}} - itemSize={92} + itemSize={144} overscanCount={10} innerRef={listInnerEl} > diff --git a/modern/src/map/StatusView.js b/modern/src/map/StatusView.js index 6b6836c..6fb72c7 100644 --- a/modern/src/map/StatusView.js +++ b/modern/src/map/StatusView.js @@ -7,11 +7,12 @@ import ListItem from '@material-ui/core/ListItem'; import ListItemText from '@material-ui/core/ListItemText'; import { useSelector } from 'react-redux'; -import ReplayIcon from '@material-ui/icons/Replay'; import EditIcon from '@material-ui/icons/Edit'; import SendIcon from '@material-ui/icons/Send'; import DeleteIcon from '@material-ui/icons/Delete'; import LinkIcon from '@material-ui/icons/Link'; +import InfoIcon from '@material-ui/icons/Info'; +import PlayCircleFilledIcon from '@material-ui/icons/PlayCircleFilled'; import { formatSpeed, formatDate, formatHours, @@ -42,6 +43,7 @@ const StatusView = ({ const t = useTranslation(); const [removeDialogShown, setRemoveDialogShown] = useState(false); + const session = useSelector((state) => state.session); const device = useSelector((state) => state.devices.items[deviceId]); const position = useSelector(getPosition(deviceId)); @@ -100,11 +102,13 @@ const StatusView = ({ </Grid> <Grid item container> <Grid item> - <Button color="secondary" onClick={handleClick}>{t('sharedShowInfo')}</Button> + <IconButton onClick={handleClick}> + <InfoIcon /> + </IconButton> </Grid> <Grid item> <IconButton onClick={onShowHistory}> - <ReplayIcon /> + <PlayCircleFilledIcon /> </IconButton> </Grid> <Grid item> @@ -117,16 +121,20 @@ const StatusView = ({ <SendIcon /> </IconButton> </Grid> - <Grid item> - <IconButton onClick={handleEditClick}> - <EditIcon /> - </IconButton> - </Grid> - <Grid item> - <IconButton onClick={handleRemove} className={classes.red}> - <DeleteIcon /> - </IconButton> - </Grid> + {!session.server.deviceReadonly && ( + <> + <Grid item> + <IconButton onClick={handleEditClick}> + <EditIcon /> + </IconButton> + </Grid> + <Grid item> + <IconButton onClick={handleRemove} className={classes.red}> + <DeleteIcon /> + </IconButton> + </Grid> + </> + )} </Grid> </Grid> </Paper> |