improved icon toggling

This commit is contained in:
Proddy
2022-05-28 20:23:16 +02:00
parent 356390c92b
commit e4447ee1b9
4 changed files with 100 additions and 46 deletions

View File

@@ -0,0 +1,39 @@
import { FC } from 'react';
import { SvgIconProps } from '@mui/material';
import EditOutlinedIcon from '@mui/icons-material/EditOutlined';
import EditOffOutlinedIcon from '@mui/icons-material/EditOffOutlined';
import StarIcon from '@mui/icons-material/Star';
import StarOutlineIcon from '@mui/icons-material/StarOutline';
import VisibilityOffOutlinedIcon from '@mui/icons-material/VisibilityOffOutlined';
import VisibilityOutlinedIcon from '@mui/icons-material/VisibilityOutlined';
import CommentsDisabledOutlinedIcon from '@mui/icons-material/CommentsDisabledOutlined';
import InsertCommentOutlinedIcon from '@mui/icons-material/InsertCommentOutlined';
type OptionType = 'readonly' | 'web_exclude' | 'api_mqtt_exclude' | 'favorite';
const OPTION_ICONS: { [type in OptionType]: [React.ComponentType<SvgIconProps>, React.ComponentType<SvgIconProps>] } = {
readonly: [EditOffOutlinedIcon, EditOutlinedIcon],
web_exclude: [VisibilityOffOutlinedIcon, VisibilityOutlinedIcon],
api_mqtt_exclude: [CommentsDisabledOutlinedIcon, InsertCommentOutlinedIcon],
favorite: [StarIcon, StarOutlineIcon]
};
interface OptionIconProps {
type: OptionType;
isSet: boolean;
}
const OptionIcon: FC<OptionIconProps> = ({ type, isSet }) => {
const Icon = OPTION_ICONS[type][isSet ? 0 : 1];
return isSet ? (
<Icon color="primary" sx={{ fontSize: 14, verticalAlign: 'middle' }} />
) : (
<Icon sx={{ fontSize: 14, verticalAlign: 'middle' }} />
);
};
export default OptionIcon;

View File

@@ -25,10 +25,12 @@ import { useSnackbar } from 'notistack';
import SaveIcon from '@mui/icons-material/Save'; import SaveIcon from '@mui/icons-material/Save';
import CancelIcon from '@mui/icons-material/Cancel'; import CancelIcon from '@mui/icons-material/Cancel';
import EditOffOutlinedIcon from '@mui/icons-material/EditOffOutlined';
import StarIcon from '@mui/icons-material/Star'; // import EditOffOutlinedIcon from '@mui/icons-material/EditOffOutlined';
import VisibilityOffOutlinedIcon from '@mui/icons-material/VisibilityOffOutlined'; // import StarIcon from '@mui/icons-material/Star';
import CommentsDisabledOutlinedIcon from '@mui/icons-material/CommentsDisabledOutlined'; // import VisibilityOffOutlinedIcon from '@mui/icons-material/VisibilityOffOutlined';
// import CommentsDisabledOutlinedIcon from '@mui/icons-material/CommentsDisabledOutlined';
import SettingsBackupRestoreIcon from '@mui/icons-material/SettingsBackupRestore'; import SettingsBackupRestoreIcon from '@mui/icons-material/SettingsBackupRestore';
import KeyboardArrowUpOutlinedIcon from '@mui/icons-material/KeyboardArrowUpOutlined'; import KeyboardArrowUpOutlinedIcon from '@mui/icons-material/KeyboardArrowUpOutlined';
import KeyboardArrowDownOutlinedIcon from '@mui/icons-material/KeyboardArrowDownOutlined'; import KeyboardArrowDownOutlinedIcon from '@mui/icons-material/KeyboardArrowDownOutlined';
@@ -36,6 +38,8 @@ import UnfoldMoreOutlinedIcon from '@mui/icons-material/UnfoldMoreOutlined';
import SearchIcon from '@mui/icons-material/Search'; import SearchIcon from '@mui/icons-material/Search';
import FilterListIcon from '@mui/icons-material/FilterList'; import FilterListIcon from '@mui/icons-material/FilterList';
import OptionIcon from './OptionIcon';
import { ButtonRow, FormLoader, ValidatedTextField, SectionContent } from '../components'; import { ButtonRow, FormLoader, ValidatedTextField, SectionContent } from '../components';
import * as EMSESP from './api'; import * as EMSESP from './api';
@@ -202,14 +206,12 @@ const SettingsCustomization: FC = () => {
function formatName(de: DeviceEntity) { function formatName(de: DeviceEntity) {
if (de.n === undefined || de.n === de.id) { if (de.n === undefined || de.n === de.id) {
return de.id; return de.id;
} else if (de.n === '') {
return 'Command: ' + de.id;
} }
return de.n + ' (' + de.id + ')'; return de.n + ' (' + de.id + ')';
} }
function isCmd(de: DeviceEntity) {
return de.n === undefined;
}
const getMaskNumber = (newMask: string[]) => { const getMaskNumber = (newMask: string[]) => {
var new_mask = 0; var new_mask = 0;
for (let entry of newMask) { for (let entry of newMask) {
@@ -317,14 +319,14 @@ const SettingsCustomization: FC = () => {
<Box mb={2} color="warning.main"> <Box mb={2} color="warning.main">
<Typography variant="body2">Select a device and customize each of its entities using the options:</Typography> <Typography variant="body2">Select a device and customize each of its entities using the options:</Typography>
<Typography variant="body2"> <Typography variant="body2">
<StarIcon sx={{ fontSize: 16, verticalAlign: 'middle' }} /> <OptionIcon type="favorite" isSet={true} />
=mark/unmark as a favorite&nbsp;&nbsp; =mark as a favorite&nbsp;&nbsp;
<EditOffOutlinedIcon sx={{ fontSize: 16, verticalAlign: 'middle' }} /> <OptionIcon type="readonly" isSet={true} />
=enable/disable write action&nbsp;&nbsp; =disable write action&nbsp;&nbsp;
<CommentsDisabledOutlinedIcon sx={{ fontSize: 16, verticalAlign: 'middle' }} /> <OptionIcon type="api_mqtt_exclude" isSet={true} />
=include/exclude from MQTT and API outputs&nbsp;&nbsp; =exclude from MQTT and API outputs&nbsp;&nbsp;
<VisibilityOffOutlinedIcon sx={{ fontSize: 16, verticalAlign: 'middle' }} /> <OptionIcon type="web_exclude" isSet={true} />
=show/hide from Web Dashboard =hide from Web Dashboard
</Typography> </Typography>
</Box> </Box>
<ValidatedTextField <ValidatedTextField
@@ -384,9 +386,11 @@ const SettingsCustomization: FC = () => {
}} }}
/> />
</Grid> </Grid>
<Tooltip arrow placement="top" title="apply filter">
<Grid item> <Grid item>
<FilterListIcon color="primary" sx={{ fontSize: 14, verticalAlign: 'middle' }} />: <FilterListIcon color="primary" sx={{ fontSize: 14, verticalAlign: 'middle' }} />:
</Grid> </Grid>
</Tooltip>
<Grid item> <Grid item>
<ToggleButtonGroup <ToggleButtonGroup
size="small" size="small"
@@ -397,24 +401,16 @@ const SettingsCustomization: FC = () => {
}} }}
> >
<ToggleButton value="8"> <ToggleButton value="8">
<Tooltip arrow placement="top" title="filter favorites"> <OptionIcon type="favorite" isSet={true} />
<StarIcon sx={{ fontSize: 14 }} />
</Tooltip>
</ToggleButton> </ToggleButton>
<ToggleButton value="4"> <ToggleButton value="4">
<Tooltip arrow placement="top" title="filter entities with write action disabled"> <OptionIcon type="readonly" isSet={true} />
<EditOffOutlinedIcon sx={{ fontSize: 14 }} />
</Tooltip>
</ToggleButton> </ToggleButton>
<ToggleButton value="2"> <ToggleButton value="2">
<Tooltip arrow placement="top" title="filter entities excluded from MQTT and API outputs"> <OptionIcon type="api_mqtt_exclude" isSet={true} />
<CommentsDisabledOutlinedIcon sx={{ fontSize: 14 }} />
</Tooltip>
</ToggleButton> </ToggleButton>
<ToggleButton value="1"> <ToggleButton value="1">
<Tooltip arrow placement="top" title="filter entities hidden from Web Dashboard"> <OptionIcon type="web_exclude" isSet={true} />
<VisibilityOffOutlinedIcon sx={{ fontSize: 14 }} />
</Tooltip>
</ToggleButton> </ToggleButton>
</ToggleButtonGroup> </ToggleButtonGroup>
</Grid> </Grid>
@@ -428,9 +424,9 @@ const SettingsCustomization: FC = () => {
color="inherit" color="inherit"
onClick={() => maskDisabled(false)} onClick={() => maskDisabled(false)}
> >
set&nbsp; set all&nbsp;
<CommentsDisabledOutlinedIcon color="primary" sx={{ fontSize: 14, verticalAlign: 'middle' }} /> <OptionIcon type="api_mqtt_exclude" isSet={false} />
<VisibilityOffOutlinedIcon color="primary" sx={{ fontSize: 14, verticalAlign: 'middle' }} /> <OptionIcon type="web_exclude" isSet={false} />
</Button> </Button>
</Tooltip> </Tooltip>
</Grid> </Grid>
@@ -443,9 +439,9 @@ const SettingsCustomization: FC = () => {
color="inherit" color="inherit"
onClick={() => maskDisabled(true)} onClick={() => maskDisabled(true)}
> >
unset&nbsp; set all&nbsp;
<CommentsDisabledOutlinedIcon sx={{ fontSize: 14, verticalAlign: 'middle' }} /> <OptionIcon type="api_mqtt_exclude" isSet={true} />
<VisibilityOffOutlinedIcon sx={{ fontSize: 14, verticalAlign: 'middle' }} /> <OptionIcon type="web_exclude" isSet={true} />
</Button> </Button>
</Tooltip> </Tooltip>
</Grid> </Grid>
@@ -479,23 +475,40 @@ const SettingsCustomization: FC = () => {
value={getMaskString(de.m)} value={getMaskString(de.m)}
onChange={(event, mask) => { onChange={(event, mask) => {
de.m = getMaskNumber(mask); de.m = getMaskNumber(mask);
if (de.n === '' && de.m & DeviceEntityMask.DV_READONLY) {
de.m = de.m | DeviceEntityMask.DV_WEB_EXCLUDE;
}
if (de.m & DeviceEntityMask.DV_WEB_EXCLUDE) { if (de.m & DeviceEntityMask.DV_WEB_EXCLUDE) {
de.m = de.m & ~DeviceEntityMask.DV_FAVORITE; de.m = de.m & ~DeviceEntityMask.DV_FAVORITE;
} }
setMasks(['']); setMasks(['']);
}} }}
> >
<ToggleButton value="8" disabled={(de.m & 1) !== 0}> <ToggleButton value="8" disabled={(de.m & 1) !== 0 || de.n === undefined}>
<StarIcon sx={{ fontSize: 14 }} /> <OptionIcon
type="favorite"
isSet={(de.m & DeviceEntityMask.DV_FAVORITE) === DeviceEntityMask.DV_FAVORITE}
/>
</ToggleButton> </ToggleButton>
<ToggleButton value="4" disabled={!de.w || (de.m & 3) === 3 || isCmd(de)}> <ToggleButton value="4" disabled={!de.w || (de.m & 3) === 3}>
<EditOffOutlinedIcon sx={{ fontSize: 14 }} /> <OptionIcon
type="readonly"
isSet={(de.m & DeviceEntityMask.DV_READONLY) === DeviceEntityMask.DV_READONLY}
/>
</ToggleButton> </ToggleButton>
<ToggleButton value="2" disabled={isCmd(de)}> <ToggleButton value="2" disabled={de.n === ''}>
<CommentsDisabledOutlinedIcon sx={{ fontSize: 14 }} /> <OptionIcon
type="api_mqtt_exclude"
isSet={
(de.m & DeviceEntityMask.DV_API_MQTT_EXCLUDE) === DeviceEntityMask.DV_API_MQTT_EXCLUDE
}
/>
</ToggleButton> </ToggleButton>
<ToggleButton value="1"> <ToggleButton value="1" disabled={de.n === undefined}>
<VisibilityOffOutlinedIcon sx={{ fontSize: 14 }} /> <OptionIcon
type="web_exclude"
isSet={(de.m & DeviceEntityMask.DV_WEB_EXCLUDE) === DeviceEntityMask.DV_WEB_EXCLUDE}
/>
</ToggleButton> </ToggleButton>
</ToggleButtonGroup> </ToggleButtonGroup>
</Cell> </Cell>

View File

@@ -630,7 +630,7 @@ const emsesp_deviceentities_1 = [
] ]
const emsesp_deviceentities_2 = [ const emsesp_deviceentities_2 = [
{ u: 0, id: 'reset', m: 8, w: false }, { u: 0, n: '', id: 'reset', m: 8, w: false },
{ v: false, n: 'heating active', id: 'heatingactive', m: 8, w: false }, { v: false, n: 'heating active', id: 'heatingactive', m: 8, w: false },
{ v: false, n: 'tapwater active', id: 'tapwateractive', m: 4, w: false }, { v: false, n: 'tapwater active', id: 'tapwateractive', m: 4, w: false },
{ v: 5, n: 'selected flow temperature', id: 'selflowtemp', m: 4, w: true }, { v: 5, n: 'selected flow temperature', id: 'selflowtemp', m: 4, w: true },

View File

@@ -850,6 +850,8 @@ void EMSdevice::generate_values_web_customization(JsonArray & output) {
obj["n"] = name; obj["n"] = name;
} }
} }
} else {
obj["n"] = "";
} }
obj["m"] = dv.state >> 4; // send back the mask state. We're only interested in the high nibble obj["m"] = dv.state >> 4; // send back the mask state. We're only interested in the high nibble