mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-07 08:19:52 +03:00
UI improvements in web
This commit is contained in:
@@ -3,6 +3,7 @@ import * as React from "react";
|
||||
export interface Me {
|
||||
username: string;
|
||||
admin: boolean;
|
||||
version: string; // proddy added
|
||||
}
|
||||
|
||||
export interface AuthenticationContext {
|
||||
|
||||
@@ -59,10 +59,11 @@ class AuthenticationWrapper extends React.Component<AuthenticationWrapperProps,
|
||||
}
|
||||
|
||||
refresh = () => {
|
||||
if (!this.props.features.security) {
|
||||
this.setState({ initialized: true, context: { ...this.state.context, me: { admin: true, username: "admin" } } });
|
||||
return;
|
||||
}
|
||||
// proddy removed
|
||||
// if (!this.props.features.security) {
|
||||
// this.setState({ initialized: true, context: { ...this.state.context, me: { admin: true, username: "admin" } } });
|
||||
// return;
|
||||
// }
|
||||
const accessToken = getStorage().getItem(ACCESS_TOKEN)
|
||||
if (accessToken) {
|
||||
authorizedFetch(VERIFY_AUTHORIZATION_ENDPOINT)
|
||||
|
||||
@@ -124,11 +124,18 @@ class MenuAppBar extends React.Component<MenuAppBarProps, MenuAppBarState> {
|
||||
<Box display="flex">
|
||||
<img src="/app/icon.png" className={classes.toolbarImage} alt={PROJECT_NAME} />
|
||||
</Box>
|
||||
|
||||
<Typography variant="h6" color="textPrimary">
|
||||
{PROJECT_NAME}
|
||||
</Typography>
|
||||
|
||||
<Typography align="right" variant="caption" color="textPrimary">
|
||||
{authenticatedContext.me.version}
|
||||
</Typography>
|
||||
|
||||
<Divider absolute />
|
||||
</Toolbar>
|
||||
|
||||
{features.project && (
|
||||
<Fragment>
|
||||
<ProjectMenu />
|
||||
@@ -149,12 +156,12 @@ class MenuAppBar extends React.Component<MenuAppBarProps, MenuAppBarState> {
|
||||
<ListItemText primary="Access Point" />
|
||||
</ListItem>
|
||||
{features.ntp && (
|
||||
<ListItem to='/ntp/' selected={path.startsWith('/ntp/')} button component={Link}>
|
||||
<ListItemIcon>
|
||||
<AccessTimeIcon />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary="Network Time" />
|
||||
</ListItem>
|
||||
<ListItem to='/ntp/' selected={path.startsWith('/ntp/')} button component={Link}>
|
||||
<ListItemIcon>
|
||||
<AccessTimeIcon />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary="Network Time" />
|
||||
</ListItem>
|
||||
)}
|
||||
{features.mqtt && (
|
||||
<ListItem to='/mqtt/' selected={path.startsWith('/mqtt/')} button component={Link}>
|
||||
|
||||
@@ -44,7 +44,7 @@ export const disconnectReason = ({ disconnect_reason }: MqttStatus) => {
|
||||
}
|
||||
}
|
||||
|
||||
export const mqttStatusHighlight2 = ({ mqtt_fails }: MqttStatus, theme: Theme) => {
|
||||
export const mqttPublishHighlight = ({ mqtt_fails }: MqttStatus, theme: Theme) => {
|
||||
|
||||
if (mqtt_fails === 0)
|
||||
return theme.palette.success.main;
|
||||
@@ -53,5 +53,4 @@ export const mqttStatusHighlight2 = ({ mqtt_fails }: MqttStatus, theme: Theme) =
|
||||
return theme.palette.warning.main;
|
||||
|
||||
return theme.palette.success.main;
|
||||
|
||||
}
|
||||
@@ -9,7 +9,7 @@ import ReportIcon from '@material-ui/icons/Report';
|
||||
import SpeakerNotesOffIcon from "@material-ui/icons/SpeakerNotesOff";
|
||||
|
||||
import { RestFormProps, FormActions, FormButton, HighlightAvatar } from '../components';
|
||||
import { mqttStatusHighlight, mqttStatus, mqttStatusHighlight2, disconnectReason } from './MqttStatus';
|
||||
import { mqttStatusHighlight, mqttStatus, mqttPublishHighlight, disconnectReason } from './MqttStatus';
|
||||
import { MqttStatus } from './types';
|
||||
|
||||
type MqttStatusFormProps = RestFormProps<MqttStatus> & WithTheme;
|
||||
@@ -30,7 +30,7 @@ class MqttStatusForm extends Component<MqttStatusFormProps> {
|
||||
<Divider variant="inset" component="li" />
|
||||
<ListItem>
|
||||
<ListItemAvatar>
|
||||
<HighlightAvatar color={mqttStatusHighlight2(data, theme)}>
|
||||
<HighlightAvatar color={mqttPublishHighlight(data, theme)}>
|
||||
<SpeakerNotesOffIcon />
|
||||
</HighlightAvatar>
|
||||
</ListItemAvatar>
|
||||
|
||||
@@ -9,6 +9,7 @@ import { AuthenticatedRoute } from '../authentication';
|
||||
|
||||
import EMSESPStatusController from './EMSESPStatusController';
|
||||
import EMSESPDevicesController from './EMSESPDevicesController';
|
||||
import EMSESPHelp from './EMSESPHelp';
|
||||
|
||||
class EMSESP extends Component<RouteComponentProps> {
|
||||
|
||||
@@ -20,10 +21,12 @@ class EMSESP extends Component<RouteComponentProps> {
|
||||
return (
|
||||
<MenuAppBar sectionTitle="Dashboard">
|
||||
<Tabs value={this.props.match.url} onChange={this.handleTabChange} variant="fullWidth">
|
||||
<Tab value={`/${PROJECT_PATH}/status`} label="EMS-ESP Status" />
|
||||
<Tab value={`/${PROJECT_PATH}/status`} label="EMS Status" />
|
||||
<Tab value={`/${PROJECT_PATH}/devices`} label="EMS Devices" />
|
||||
<Tab value={`/${PROJECT_PATH}/help`} label="EMS-ESP Help" />
|
||||
</Tabs>
|
||||
<Switch>
|
||||
<AuthenticatedRoute exact path={`/${PROJECT_PATH}/help`} component={EMSESPHelp} />
|
||||
<AuthenticatedRoute exact path={`/${PROJECT_PATH}/status`} component={EMSESPStatusController} />
|
||||
<AuthenticatedRoute exact path={`/${PROJECT_PATH}/devices`} component={EMSESPDevicesController} />
|
||||
<Redirect to={`/${PROJECT_PATH}/status`} />
|
||||
|
||||
@@ -115,7 +115,7 @@ class EMSESPDevicesForm extends Component<EMSESPDevicesFormProps, EMSESPDevicesF
|
||||
(
|
||||
<Box bgcolor="error.main" color="error.contrastText" p={2} mt={2} mb={2}>
|
||||
<Typography variant="body1">
|
||||
No EMS devices found. Check connection and for Tx errors. Try forcing a scan.
|
||||
No EMS devices found. Check the connection and for possible Tx errors and try scanning for new devices.
|
||||
</Typography>
|
||||
</Box>
|
||||
)
|
||||
@@ -174,8 +174,9 @@ class EMSESPDevicesForm extends Component<EMSESPDevicesFormProps, EMSESPDevicesF
|
||||
render() {
|
||||
return (
|
||||
<Fragment>
|
||||
<br></br>
|
||||
{this.createTableItems()}
|
||||
|
||||
<br></br>
|
||||
<Box display="flex" flexWrap="wrap">
|
||||
<Box flexGrow={1} padding={1}>
|
||||
<FormButton startIcon={<RefreshIcon />} variant="contained" color="secondary" onClick={this.props.loadData}>
|
||||
|
||||
35
interface/src/project/EMSESPHelp.tsx
Normal file
35
interface/src/project/EMSESPHelp.tsx
Normal file
@@ -0,0 +1,35 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Typography, Box, Link } from '@material-ui/core';
|
||||
import { SectionContent } from '../components';
|
||||
|
||||
class EMSESPHelp extends Component {
|
||||
|
||||
render() {
|
||||
return (
|
||||
<SectionContent title='EMS-ESP Help' titleGutter>
|
||||
|
||||
<Box bgcolor="info.main" border={1} p={3} mt={1} mb={0}>
|
||||
<Typography variant="body1">
|
||||
EMS-ESP is an open-source firmware to communicate with heating devices that support the EMS protocol, such as equipment from Bosch, Junkers, Nefit, Buderus and Worcester.
|
||||
<p></p>
|
||||
Please consider supporting this project via the GitHub page <Link href="https://github.com/proddy/EMS-ESP" color="primary">{'http://github.com/proddy/EMS-ESP'}</Link>.
|
||||
</Typography>
|
||||
</Box>
|
||||
<br></br>
|
||||
<Typography variant="body1" paragraph>
|
||||
Check for news and updates on the <Link href="https://emsesp.github.io/docs/#/" color="primary">{'Wiki'}</Link>.
|
||||
</Typography>
|
||||
<Typography variant="body1" paragraph>
|
||||
For live community chat go to <Link href="https://gitter.im/EMS-ESP/community#" color="primary">{'Gitter'}</Link>.
|
||||
</Typography>
|
||||
<Typography variant="body1" paragraph>
|
||||
To report an issue or feature request go to <Link href="https://github.com/proddy/EMS-ESP/issues/new/choose" color="primary">{'the github project page'}</Link>.
|
||||
</Typography>
|
||||
|
||||
</SectionContent>
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default EMSESPHelp;
|
||||
@@ -17,7 +17,7 @@ class EMSESPStatusController extends Component<EMSESPStatusControllerProps> {
|
||||
|
||||
render() {
|
||||
return (
|
||||
<SectionContent title="EMS-ESP Status">
|
||||
<SectionContent title="EMS Status">
|
||||
<RestFormLoader
|
||||
{...this.props}
|
||||
render={formProps => <EMSESPStatusForm {...formProps} />}
|
||||
|
||||
@@ -12,9 +12,6 @@ import {
|
||||
ListItem,
|
||||
ListItemAvatar,
|
||||
ListItemText,
|
||||
Typography,
|
||||
Box,
|
||||
Link
|
||||
} from "@material-ui/core";
|
||||
|
||||
import RefreshIcon from "@material-ui/icons/Refresh";
|
||||
@@ -42,17 +39,7 @@ class EMSESPStatusForm extends Component<EMSESPStatusFormProps> {
|
||||
const { data, theme } = this.props;
|
||||
return (
|
||||
<Fragment>
|
||||
<Box bgcolor="info.main" border={1} p={3} mt={1} mb={0}>
|
||||
<Typography variant="body1">
|
||||
Firmware Version is <b>{data.version}</b>
|
||||
<br /><br />
|
||||
Check for news and updates on the <Link href="https://emsesp.github.io/docs/#/" color="primary">{'Wiki'}</Link>
|
||||
<br/>
|
||||
For live community chat go to <Link href="https://gitter.im/EMS-ESP/community#" color="primary">{'Gitter'}</Link>
|
||||
<br/>
|
||||
To report issues, contribute and give kudos visit <Link href="https://github.com/proddy/EMS-ESP" color="primary">{'github.com/proddy/EMS-ESP'}</Link>
|
||||
</Typography>
|
||||
</Box>
|
||||
|
||||
<ListItem>
|
||||
<ListItemAvatar>
|
||||
<HighlightAvatar color={busStatusHighlight(data, theme)}>
|
||||
|
||||
@@ -16,7 +16,6 @@ export enum busConnectionStatus {
|
||||
}
|
||||
|
||||
export interface EMSESPStatus {
|
||||
version: string;
|
||||
status: busConnectionStatus;
|
||||
rx_received: number;
|
||||
tx_sent: number;
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import React, { Component } from 'react';
|
||||
|
||||
import {restController, RestControllerProps, RestFormLoader, SectionContent } from '../components';
|
||||
import { restController, RestControllerProps, RestFormLoader, SectionContent } from '../components';
|
||||
import WiFiSettingsForm from './WiFiSettingsForm';
|
||||
import { WiFiConnectionContext } from './WiFiConnectionContext';
|
||||
import { WIFI_SETTINGS_ENDPOINT } from '../api';
|
||||
import { WiFiSettings } from './types';
|
||||
|
||||
@@ -10,39 +9,15 @@ type WiFiSettingsControllerProps = RestControllerProps<WiFiSettings>;
|
||||
|
||||
class WiFiSettingsController extends Component<WiFiSettingsControllerProps> {
|
||||
|
||||
static contextType = WiFiConnectionContext;
|
||||
context!: React.ContextType<typeof WiFiConnectionContext>;
|
||||
|
||||
componentDidMount() {
|
||||
const { selectedNetwork } = this.context;
|
||||
if (selectedNetwork) {
|
||||
const wifiSettings: WiFiSettings = {
|
||||
ssid: selectedNetwork.ssid,
|
||||
password: "",
|
||||
hostname: "ems-esp",
|
||||
static_ip_config: false,
|
||||
}
|
||||
this.props.setData(wifiSettings);
|
||||
} else {
|
||||
this.props.loadData();
|
||||
}
|
||||
}
|
||||
|
||||
deselectNetworkAndLoadData = () => {
|
||||
this.context.deselectNetwork();
|
||||
this.props.loadData();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.context.deselectNetwork();
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<SectionContent title="WiFi Settings">
|
||||
<RestFormLoader
|
||||
{...this.props}
|
||||
loadData={this.deselectNetworkAndLoadData}
|
||||
render={formProps => <WiFiSettingsForm {...formProps} />}
|
||||
/>
|
||||
</SectionContent>
|
||||
@@ -51,4 +26,4 @@ class WiFiSettingsController extends Component<WiFiSettingsControllerProps> {
|
||||
|
||||
}
|
||||
|
||||
export default restController(WIFI_SETTINGS_ENDPOINT, WiFiSettingsController);
|
||||
export default restController(WIFI_SETTINGS_ENDPOINT, WiFiSettingsController);
|
||||
@@ -24,15 +24,39 @@ class WiFiSettingsForm extends React.Component<WiFiStatusFormProps> {
|
||||
static contextType = WiFiConnectionContext;
|
||||
context!: React.ContextType<typeof WiFiConnectionContext>;
|
||||
|
||||
constructor(props: WiFiStatusFormProps, context: WiFiConnectionContext) {
|
||||
super(props);
|
||||
|
||||
const { selectedNetwork } = context;
|
||||
if (selectedNetwork) {
|
||||
const wifiSettings: WiFiSettings = {
|
||||
ssid: selectedNetwork.ssid,
|
||||
password: "",
|
||||
hostname: props.data.hostname,
|
||||
static_ip_config: false,
|
||||
}
|
||||
props.setData(wifiSettings);
|
||||
}
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
ValidatorForm.addValidationRule('isIP', isIP);
|
||||
ValidatorForm.addValidationRule('isHostname', isHostname);
|
||||
ValidatorForm.addValidationRule('isOptionalIP', optional(isIP));
|
||||
}
|
||||
|
||||
deselectNetworkAndLoadData = () => {
|
||||
this.context.deselectNetwork();
|
||||
this.props.loadData();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.context.deselectNetwork();
|
||||
}
|
||||
|
||||
render() {
|
||||
const { selectedNetwork, deselectNetwork } = this.context;
|
||||
const { data, handleValueChange, saveData, loadData } = this.props;
|
||||
const { data, handleValueChange, saveData } = this.props;
|
||||
return (
|
||||
<ValidatorForm onSubmit={saveData} ref="WiFiSettingsForm">
|
||||
{
|
||||
@@ -167,7 +191,7 @@ class WiFiSettingsForm extends React.Component<WiFiStatusFormProps> {
|
||||
<FormButton startIcon={<SaveIcon />} variant="contained" color="primary" type="submit">
|
||||
Save
|
||||
</FormButton>
|
||||
<FormButton variant="contained" color="secondary" onClick={loadData}>
|
||||
<FormButton variant="contained" color="secondary" onClick={this.deselectNetworkAndLoadData}>
|
||||
Reset
|
||||
</FormButton>
|
||||
</FormActions>
|
||||
@@ -176,4 +200,4 @@ class WiFiSettingsForm extends React.Component<WiFiStatusFormProps> {
|
||||
}
|
||||
}
|
||||
|
||||
export default WiFiSettingsForm;
|
||||
export default WiFiSettingsForm;
|
||||
Reference in New Issue
Block a user