mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-07 00:09:51 +03:00
improved icon toggling
This commit is contained in:
39
interface/src/project/OptionIcon.tsx
Normal file
39
interface/src/project/OptionIcon.tsx
Normal 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;
|
||||
@@ -25,10 +25,12 @@ import { useSnackbar } from 'notistack';
|
||||
|
||||
import SaveIcon from '@mui/icons-material/Save';
|
||||
import CancelIcon from '@mui/icons-material/Cancel';
|
||||
import EditOffOutlinedIcon from '@mui/icons-material/EditOffOutlined';
|
||||
import StarIcon from '@mui/icons-material/Star';
|
||||
import VisibilityOffOutlinedIcon from '@mui/icons-material/VisibilityOffOutlined';
|
||||
import CommentsDisabledOutlinedIcon from '@mui/icons-material/CommentsDisabledOutlined';
|
||||
|
||||
// import EditOffOutlinedIcon from '@mui/icons-material/EditOffOutlined';
|
||||
// import StarIcon from '@mui/icons-material/Star';
|
||||
// import VisibilityOffOutlinedIcon from '@mui/icons-material/VisibilityOffOutlined';
|
||||
// import CommentsDisabledOutlinedIcon from '@mui/icons-material/CommentsDisabledOutlined';
|
||||
|
||||
import SettingsBackupRestoreIcon from '@mui/icons-material/SettingsBackupRestore';
|
||||
import KeyboardArrowUpOutlinedIcon from '@mui/icons-material/KeyboardArrowUpOutlined';
|
||||
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 FilterListIcon from '@mui/icons-material/FilterList';
|
||||
|
||||
import OptionIcon from './OptionIcon';
|
||||
|
||||
import { ButtonRow, FormLoader, ValidatedTextField, SectionContent } from '../components';
|
||||
|
||||
import * as EMSESP from './api';
|
||||
@@ -202,14 +206,12 @@ const SettingsCustomization: FC = () => {
|
||||
function formatName(de: DeviceEntity) {
|
||||
if (de.n === undefined || de.n === de.id) {
|
||||
return de.id;
|
||||
} else if (de.n === '') {
|
||||
return 'Command: ' + de.id;
|
||||
}
|
||||
return de.n + ' (' + de.id + ')';
|
||||
}
|
||||
|
||||
function isCmd(de: DeviceEntity) {
|
||||
return de.n === undefined;
|
||||
}
|
||||
|
||||
const getMaskNumber = (newMask: string[]) => {
|
||||
var new_mask = 0;
|
||||
for (let entry of newMask) {
|
||||
@@ -317,14 +319,14 @@ const SettingsCustomization: FC = () => {
|
||||
<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">
|
||||
<StarIcon sx={{ fontSize: 16, verticalAlign: 'middle' }} />
|
||||
=mark/unmark as a favorite
|
||||
<EditOffOutlinedIcon sx={{ fontSize: 16, verticalAlign: 'middle' }} />
|
||||
=enable/disable write action
|
||||
<CommentsDisabledOutlinedIcon sx={{ fontSize: 16, verticalAlign: 'middle' }} />
|
||||
=include/exclude from MQTT and API outputs
|
||||
<VisibilityOffOutlinedIcon sx={{ fontSize: 16, verticalAlign: 'middle' }} />
|
||||
=show/hide from Web Dashboard
|
||||
<OptionIcon type="favorite" isSet={true} />
|
||||
=mark as a favorite
|
||||
<OptionIcon type="readonly" isSet={true} />
|
||||
=disable write action
|
||||
<OptionIcon type="api_mqtt_exclude" isSet={true} />
|
||||
=exclude from MQTT and API outputs
|
||||
<OptionIcon type="web_exclude" isSet={true} />
|
||||
=hide from Web Dashboard
|
||||
</Typography>
|
||||
</Box>
|
||||
<ValidatedTextField
|
||||
@@ -384,9 +386,11 @@ const SettingsCustomization: FC = () => {
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<FilterListIcon color="primary" sx={{ fontSize: 14, verticalAlign: 'middle' }} />:
|
||||
</Grid>
|
||||
<Tooltip arrow placement="top" title="apply filter">
|
||||
<Grid item>
|
||||
<FilterListIcon color="primary" sx={{ fontSize: 14, verticalAlign: 'middle' }} />:
|
||||
</Grid>
|
||||
</Tooltip>
|
||||
<Grid item>
|
||||
<ToggleButtonGroup
|
||||
size="small"
|
||||
@@ -397,24 +401,16 @@ const SettingsCustomization: FC = () => {
|
||||
}}
|
||||
>
|
||||
<ToggleButton value="8">
|
||||
<Tooltip arrow placement="top" title="filter favorites">
|
||||
<StarIcon sx={{ fontSize: 14 }} />
|
||||
</Tooltip>
|
||||
<OptionIcon type="favorite" isSet={true} />
|
||||
</ToggleButton>
|
||||
<ToggleButton value="4">
|
||||
<Tooltip arrow placement="top" title="filter entities with write action disabled">
|
||||
<EditOffOutlinedIcon sx={{ fontSize: 14 }} />
|
||||
</Tooltip>
|
||||
<OptionIcon type="readonly" isSet={true} />
|
||||
</ToggleButton>
|
||||
<ToggleButton value="2">
|
||||
<Tooltip arrow placement="top" title="filter entities excluded from MQTT and API outputs">
|
||||
<CommentsDisabledOutlinedIcon sx={{ fontSize: 14 }} />
|
||||
</Tooltip>
|
||||
<OptionIcon type="api_mqtt_exclude" isSet={true} />
|
||||
</ToggleButton>
|
||||
<ToggleButton value="1">
|
||||
<Tooltip arrow placement="top" title="filter entities hidden from Web Dashboard">
|
||||
<VisibilityOffOutlinedIcon sx={{ fontSize: 14 }} />
|
||||
</Tooltip>
|
||||
<OptionIcon type="web_exclude" isSet={true} />
|
||||
</ToggleButton>
|
||||
</ToggleButtonGroup>
|
||||
</Grid>
|
||||
@@ -428,9 +424,9 @@ const SettingsCustomization: FC = () => {
|
||||
color="inherit"
|
||||
onClick={() => maskDisabled(false)}
|
||||
>
|
||||
set
|
||||
<CommentsDisabledOutlinedIcon color="primary" sx={{ fontSize: 14, verticalAlign: 'middle' }} />
|
||||
<VisibilityOffOutlinedIcon color="primary" sx={{ fontSize: 14, verticalAlign: 'middle' }} />
|
||||
set all
|
||||
<OptionIcon type="api_mqtt_exclude" isSet={false} />
|
||||
<OptionIcon type="web_exclude" isSet={false} />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</Grid>
|
||||
@@ -443,9 +439,9 @@ const SettingsCustomization: FC = () => {
|
||||
color="inherit"
|
||||
onClick={() => maskDisabled(true)}
|
||||
>
|
||||
unset
|
||||
<CommentsDisabledOutlinedIcon sx={{ fontSize: 14, verticalAlign: 'middle' }} />
|
||||
<VisibilityOffOutlinedIcon sx={{ fontSize: 14, verticalAlign: 'middle' }} />
|
||||
set all
|
||||
<OptionIcon type="api_mqtt_exclude" isSet={true} />
|
||||
<OptionIcon type="web_exclude" isSet={true} />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</Grid>
|
||||
@@ -479,23 +475,40 @@ const SettingsCustomization: FC = () => {
|
||||
value={getMaskString(de.m)}
|
||||
onChange={(event, 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) {
|
||||
de.m = de.m & ~DeviceEntityMask.DV_FAVORITE;
|
||||
}
|
||||
setMasks(['']);
|
||||
}}
|
||||
>
|
||||
<ToggleButton value="8" disabled={(de.m & 1) !== 0}>
|
||||
<StarIcon sx={{ fontSize: 14 }} />
|
||||
<ToggleButton value="8" disabled={(de.m & 1) !== 0 || de.n === undefined}>
|
||||
<OptionIcon
|
||||
type="favorite"
|
||||
isSet={(de.m & DeviceEntityMask.DV_FAVORITE) === DeviceEntityMask.DV_FAVORITE}
|
||||
/>
|
||||
</ToggleButton>
|
||||
<ToggleButton value="4" disabled={!de.w || (de.m & 3) === 3 || isCmd(de)}>
|
||||
<EditOffOutlinedIcon sx={{ fontSize: 14 }} />
|
||||
<ToggleButton value="4" disabled={!de.w || (de.m & 3) === 3}>
|
||||
<OptionIcon
|
||||
type="readonly"
|
||||
isSet={(de.m & DeviceEntityMask.DV_READONLY) === DeviceEntityMask.DV_READONLY}
|
||||
/>
|
||||
</ToggleButton>
|
||||
<ToggleButton value="2" disabled={isCmd(de)}>
|
||||
<CommentsDisabledOutlinedIcon sx={{ fontSize: 14 }} />
|
||||
<ToggleButton value="2" disabled={de.n === ''}>
|
||||
<OptionIcon
|
||||
type="api_mqtt_exclude"
|
||||
isSet={
|
||||
(de.m & DeviceEntityMask.DV_API_MQTT_EXCLUDE) === DeviceEntityMask.DV_API_MQTT_EXCLUDE
|
||||
}
|
||||
/>
|
||||
</ToggleButton>
|
||||
<ToggleButton value="1">
|
||||
<VisibilityOffOutlinedIcon sx={{ fontSize: 14 }} />
|
||||
<ToggleButton value="1" disabled={de.n === undefined}>
|
||||
<OptionIcon
|
||||
type="web_exclude"
|
||||
isSet={(de.m & DeviceEntityMask.DV_WEB_EXCLUDE) === DeviceEntityMask.DV_WEB_EXCLUDE}
|
||||
/>
|
||||
</ToggleButton>
|
||||
</ToggleButtonGroup>
|
||||
</Cell>
|
||||
|
||||
@@ -630,7 +630,7 @@ const emsesp_deviceentities_1 = [
|
||||
]
|
||||
|
||||
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: 'tapwater active', id: 'tapwateractive', m: 4, w: false },
|
||||
{ v: 5, n: 'selected flow temperature', id: 'selflowtemp', m: 4, w: true },
|
||||
|
||||
@@ -850,6 +850,8 @@ void EMSdevice::generate_values_web_customization(JsonArray & output) {
|
||||
obj["n"] = name;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
obj["n"] = "";
|
||||
}
|
||||
|
||||
obj["m"] = dv.state >> 4; // send back the mask state. We're only interested in the high nibble
|
||||
|
||||
Reference in New Issue
Block a user