mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-07 08:19:52 +03:00
eslint
This commit is contained in:
@@ -1,6 +1,11 @@
|
||||
import React, { Component } from 'react';
|
||||
|
||||
import { restController, RestControllerProps, RestFormLoader, SectionContent } from '../components';
|
||||
import {
|
||||
restController,
|
||||
RestControllerProps,
|
||||
RestFormLoader,
|
||||
SectionContent
|
||||
} from '../components';
|
||||
import { OTA_SETTINGS_ENDPOINT } from '../api';
|
||||
|
||||
import OTASettingsForm from './OTASettingsForm';
|
||||
@@ -9,7 +14,6 @@ import { OTASettings } from './types';
|
||||
type OTASettingsControllerProps = RestControllerProps<OTASettings>;
|
||||
|
||||
class OTASettingsController extends Component<OTASettingsControllerProps> {
|
||||
|
||||
componentDidMount() {
|
||||
this.props.loadData();
|
||||
}
|
||||
@@ -19,12 +23,11 @@ class OTASettingsController extends Component<OTASettingsControllerProps> {
|
||||
<SectionContent title="OTA Settings" titleGutter>
|
||||
<RestFormLoader
|
||||
{...this.props}
|
||||
render={formProps => <OTASettingsForm {...formProps} />}
|
||||
render={(formProps) => <OTASettingsForm {...formProps} />}
|
||||
/>
|
||||
</SectionContent>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default restController(OTA_SETTINGS_ENDPOINT, OTASettingsController);
|
||||
|
||||
@@ -4,7 +4,13 @@ import { TextValidator, ValidatorForm } from 'react-material-ui-form-validator';
|
||||
import { Checkbox } from '@material-ui/core';
|
||||
import SaveIcon from '@material-ui/icons/Save';
|
||||
|
||||
import { RestFormProps, BlockFormControlLabel, PasswordValidator, FormButton, FormActions } from '../components';
|
||||
import {
|
||||
RestFormProps,
|
||||
BlockFormControlLabel,
|
||||
PasswordValidator,
|
||||
FormButton,
|
||||
FormActions
|
||||
} from '../components';
|
||||
import { isIP, isHostname, or } from '../validators';
|
||||
|
||||
import { OTASettings } from './types';
|
||||
@@ -12,7 +18,6 @@ import { OTASettings } from './types';
|
||||
type OTASettingsFormProps = RestFormProps<OTASettings>;
|
||||
|
||||
class OTASettingsForm extends React.Component<OTASettingsFormProps> {
|
||||
|
||||
componentDidMount() {
|
||||
ValidatorForm.addValidationRule('isIPOrHostname', or(isIP, isHostname));
|
||||
}
|
||||
@@ -25,14 +30,24 @@ class OTASettingsForm extends React.Component<OTASettingsFormProps> {
|
||||
control={
|
||||
<Checkbox
|
||||
checked={data.enabled}
|
||||
onChange={handleValueChange("enabled")}
|
||||
onChange={handleValueChange('enabled')}
|
||||
/>
|
||||
}
|
||||
label="Enable OTA Updates"
|
||||
/>
|
||||
<TextValidator
|
||||
validators={['required', 'isNumber', 'minNumber:1025', 'maxNumber:65535']}
|
||||
errorMessages={['Port is required', "Must be a number", "Must be greater than 1024 ", "Max value is 65535"]}
|
||||
validators={[
|
||||
'required',
|
||||
'isNumber',
|
||||
'minNumber:1025',
|
||||
'maxNumber:65535'
|
||||
]}
|
||||
errorMessages={[
|
||||
'Port is required',
|
||||
'Must be a number',
|
||||
'Must be greater than 1024 ',
|
||||
'Max value is 65535'
|
||||
]}
|
||||
name="port"
|
||||
label="Port"
|
||||
fullWidth
|
||||
@@ -44,7 +59,10 @@ class OTASettingsForm extends React.Component<OTASettingsFormProps> {
|
||||
/>
|
||||
<PasswordValidator
|
||||
validators={['required', 'matchRegexp:^.{1,64}$']}
|
||||
errorMessages={['OTA Password is required', 'OTA Point Password must be 64 characters or less']}
|
||||
errorMessages={[
|
||||
'OTA Password is required',
|
||||
'OTA Point Password must be 64 characters or less'
|
||||
]}
|
||||
name="password"
|
||||
label="Password"
|
||||
fullWidth
|
||||
@@ -54,7 +72,12 @@ class OTASettingsForm extends React.Component<OTASettingsFormProps> {
|
||||
margin="normal"
|
||||
/>
|
||||
<FormActions>
|
||||
<FormButton startIcon={<SaveIcon />} variant="contained" color="primary" type="submit">
|
||||
<FormButton
|
||||
startIcon={<SaveIcon />}
|
||||
variant="contained"
|
||||
color="primary"
|
||||
type="submit"
|
||||
>
|
||||
Save
|
||||
</FormButton>
|
||||
</FormActions>
|
||||
|
||||
@@ -1,22 +1,27 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Redirect, Switch, RouteComponentProps } from 'react-router-dom'
|
||||
import { Component } from 'react';
|
||||
import { Redirect, Switch, RouteComponentProps } from 'react-router-dom';
|
||||
|
||||
import { Tabs, Tab } from '@material-ui/core';
|
||||
|
||||
import { WithFeaturesProps, withFeatures } from '../features/FeaturesContext';
|
||||
|
||||
import { withAuthenticatedContext, AuthenticatedContextProps, AuthenticatedRoute } from '../authentication';
|
||||
import {
|
||||
withAuthenticatedContext,
|
||||
AuthenticatedContextProps,
|
||||
AuthenticatedRoute
|
||||
} from '../authentication';
|
||||
import { MenuAppBar } from '../components';
|
||||
|
||||
import SystemStatusController from './SystemStatusController';
|
||||
import OTASettingsController from './OTASettingsController';
|
||||
import UploadFirmwareController from './UploadFirmwareController';
|
||||
|
||||
type SystemProps = AuthenticatedContextProps & RouteComponentProps & WithFeaturesProps;
|
||||
type SystemProps = AuthenticatedContextProps &
|
||||
RouteComponentProps &
|
||||
WithFeaturesProps;
|
||||
|
||||
class System extends Component<SystemProps> {
|
||||
|
||||
handleTabChange = (event: React.ChangeEvent<{}>, path: string) => {
|
||||
handleTabChange = (path: string) => {
|
||||
this.props.history.push(path);
|
||||
};
|
||||
|
||||
@@ -24,27 +29,51 @@ class System extends Component<SystemProps> {
|
||||
const { authenticatedContext, features } = this.props;
|
||||
return (
|
||||
<MenuAppBar sectionTitle="System">
|
||||
<Tabs value={this.props.match.url} onChange={this.handleTabChange} variant="fullWidth">
|
||||
<Tabs
|
||||
value={this.props.match.url}
|
||||
onChange={(e, path) => this.handleTabChange(path)}
|
||||
variant="fullWidth"
|
||||
>
|
||||
<Tab value="/system/status" label="System Status" />
|
||||
{features.ota && (
|
||||
<Tab value="/system/ota" label="OTA Settings" disabled={!authenticatedContext.me.admin} />
|
||||
<Tab
|
||||
value="/system/ota"
|
||||
label="OTA Settings"
|
||||
disabled={!authenticatedContext.me.admin}
|
||||
/>
|
||||
)}
|
||||
{features.upload_firmware && (
|
||||
<Tab value="/system/upload" label="Upload Firmware" disabled={!authenticatedContext.me.admin} />
|
||||
<Tab
|
||||
value="/system/upload"
|
||||
label="Upload Firmware"
|
||||
disabled={!authenticatedContext.me.admin}
|
||||
/>
|
||||
)}
|
||||
</Tabs>
|
||||
<Switch>
|
||||
<AuthenticatedRoute exact path="/system/status" component={SystemStatusController} />
|
||||
<AuthenticatedRoute
|
||||
exact
|
||||
path="/system/status"
|
||||
component={SystemStatusController}
|
||||
/>
|
||||
{features.ota && (
|
||||
<AuthenticatedRoute exact path="/system/ota" component={OTASettingsController} />
|
||||
<AuthenticatedRoute
|
||||
exact
|
||||
path="/system/ota"
|
||||
component={OTASettingsController}
|
||||
/>
|
||||
)}
|
||||
{features.upload_firmware && (
|
||||
<AuthenticatedRoute exact path="/system/upload" component={UploadFirmwareController} />
|
||||
<AuthenticatedRoute
|
||||
exact
|
||||
path="/system/upload"
|
||||
component={UploadFirmwareController}
|
||||
/>
|
||||
)}
|
||||
<Redirect to="/system/status" />
|
||||
</Switch>
|
||||
</MenuAppBar>
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
import React, { Component } from 'react';
|
||||
|
||||
import { restController, RestControllerProps, RestFormLoader, SectionContent } from '../components';
|
||||
import {
|
||||
restController,
|
||||
RestControllerProps,
|
||||
RestFormLoader,
|
||||
SectionContent
|
||||
} from '../components';
|
||||
import { SYSTEM_STATUS_ENDPOINT } from '../api';
|
||||
|
||||
import SystemStatusForm from './SystemStatusForm';
|
||||
@@ -9,7 +14,6 @@ import { SystemStatus } from './types';
|
||||
type SystemStatusControllerProps = RestControllerProps<SystemStatus>;
|
||||
|
||||
class SystemStatusController extends Component<SystemStatusControllerProps> {
|
||||
|
||||
componentDidMount() {
|
||||
this.props.loadData();
|
||||
}
|
||||
@@ -19,12 +23,11 @@ class SystemStatusController extends Component<SystemStatusControllerProps> {
|
||||
<SectionContent title="System Status">
|
||||
<RestFormLoader
|
||||
{...this.props}
|
||||
render={formProps => <SystemStatusForm {...formProps} />}
|
||||
render={(formProps) => <SystemStatusForm {...formProps} />}
|
||||
/>
|
||||
</SectionContent>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default restController(SYSTEM_STATUS_ENDPOINT, SystemStatusController);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Component } from 'react';
|
||||
|
||||
import { SectionContent } from '../components';
|
||||
import { UPLOAD_FIRMWARE_ENDPOINT } from '../api';
|
||||
@@ -12,8 +12,10 @@ interface UploadFirmwareControllerState {
|
||||
progress?: ProgressEvent;
|
||||
}
|
||||
|
||||
class UploadFirmwareController extends Component<WithSnackbarProps, UploadFirmwareControllerState> {
|
||||
|
||||
class UploadFirmwareController extends Component<
|
||||
WithSnackbarProps,
|
||||
UploadFirmwareControllerState
|
||||
> {
|
||||
state: UploadFirmwareControllerState = {
|
||||
xhr: undefined,
|
||||
progress: undefined
|
||||
@@ -25,47 +27,67 @@ class UploadFirmwareController extends Component<WithSnackbarProps, UploadFirmwa
|
||||
|
||||
updateProgress = (progress: ProgressEvent) => {
|
||||
this.setState({ progress });
|
||||
}
|
||||
};
|
||||
|
||||
uploadFile = (file: File) => {
|
||||
if (this.state.xhr) {
|
||||
return;
|
||||
}
|
||||
var xhr = new XMLHttpRequest();
|
||||
const xhr = new XMLHttpRequest();
|
||||
this.setState({ xhr });
|
||||
redirectingAuthorizedUpload(xhr, UPLOAD_FIRMWARE_ENDPOINT, file, this.updateProgress).then(() => {
|
||||
if (xhr.status !== 200) {
|
||||
throw Error("Invalid status code: " + xhr.status);
|
||||
}
|
||||
this.props.enqueueSnackbar("Activating new firmware", { variant: 'success' });
|
||||
this.setState({ xhr: undefined, progress: undefined });
|
||||
}).catch((error: Error) => {
|
||||
if (error.name === 'AbortError') {
|
||||
this.props.enqueueSnackbar("Upload cancelled by user", { variant: 'warning' });
|
||||
} else {
|
||||
const errorMessage = error.name === 'UploadError' ? "Error during upload" : (error.message || "Unknown error");
|
||||
this.props.enqueueSnackbar("Problem uploading: " + errorMessage, { variant: 'error' });
|
||||
redirectingAuthorizedUpload(
|
||||
xhr,
|
||||
UPLOAD_FIRMWARE_ENDPOINT,
|
||||
file,
|
||||
this.updateProgress
|
||||
)
|
||||
.then(() => {
|
||||
if (xhr.status !== 200) {
|
||||
throw Error('Invalid status code: ' + xhr.status);
|
||||
}
|
||||
this.props.enqueueSnackbar('Activating new firmware', {
|
||||
variant: 'success'
|
||||
});
|
||||
this.setState({ xhr: undefined, progress: undefined });
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((error: Error) => {
|
||||
if (error.name === 'AbortError') {
|
||||
this.props.enqueueSnackbar('Upload cancelled by user', {
|
||||
variant: 'warning'
|
||||
});
|
||||
} else {
|
||||
const errorMessage =
|
||||
error.name === 'UploadError'
|
||||
? 'Error during upload'
|
||||
: error.message || 'Unknown error';
|
||||
this.props.enqueueSnackbar('Problem uploading: ' + errorMessage, {
|
||||
variant: 'error'
|
||||
});
|
||||
this.setState({ xhr: undefined, progress: undefined });
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
cancelUpload = () => {
|
||||
if (this.state.xhr) {
|
||||
this.state.xhr.abort();
|
||||
this.setState({ xhr: undefined, progress: undefined });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const { xhr, progress } = this.state;
|
||||
return (
|
||||
<SectionContent title="Upload Firmware">
|
||||
<UploadFirmwareForm onFileSelected={this.uploadFile} onCancel={this.cancelUpload} uploading={!!xhr} progress={progress} />
|
||||
<UploadFirmwareForm
|
||||
onFileSelected={this.uploadFile}
|
||||
onCancel={this.cancelUpload}
|
||||
uploading={!!xhr}
|
||||
progress={progress}
|
||||
/>
|
||||
</SectionContent>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default withSnackbar(UploadFirmwareController);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { Fragment } from "react";
|
||||
import { SingleUpload } from "../components";
|
||||
import { Box } from "@material-ui/core";
|
||||
import React, { Fragment } from 'react';
|
||||
import { SingleUpload } from '../components';
|
||||
import { Box } from '@material-ui/core';
|
||||
|
||||
interface UploadFirmwareFormProps {
|
||||
uploading: boolean;
|
||||
@@ -22,8 +22,10 @@ class UploadFirmwareForm extends React.Component<UploadFirmwareFormProps> {
|
||||
return (
|
||||
<Fragment>
|
||||
<Box py={2}>
|
||||
Upload a new firmware file (.bin or .bin.gz) below to replace the existing firmware.
|
||||
<p></p>This can take up to a minute. Wait until you see "Activating new Firmware" and EMS-ESP will then automatically restart.
|
||||
Upload a new firmware file (.bin or .bin.gz) below to replace the
|
||||
existing firmware.
|
||||
<p></p>This can take up to a minute. Wait until you see "Activating
|
||||
new Firmware" and EMS-ESP will then automatically restart.
|
||||
</Box>
|
||||
<SingleUpload
|
||||
onDrop={this.handleDrop}
|
||||
|
||||
@@ -1,37 +1,38 @@
|
||||
export enum EspPlatform {
|
||||
ESP8266 = 'esp8266',
|
||||
ESP32 = 'esp32',
|
||||
ESP32 = 'esp32'
|
||||
}
|
||||
|
||||
interface ESPSystemStatus {
|
||||
esp_platform: EspPlatform
|
||||
max_alloc_heap: number
|
||||
cpu_freq_mhz: number
|
||||
free_heap: number
|
||||
sdk_version: string
|
||||
flash_chip_size: number
|
||||
flash_chip_speed: number
|
||||
fs_used: number
|
||||
fs_total: number
|
||||
uptime: string
|
||||
free_mem: number
|
||||
emsesp_version: string;
|
||||
esp_platform: EspPlatform;
|
||||
max_alloc_heap: number;
|
||||
cpu_freq_mhz: number;
|
||||
free_heap: number;
|
||||
sdk_version: string;
|
||||
flash_chip_size: number;
|
||||
flash_chip_speed: number;
|
||||
fs_used: number;
|
||||
fs_total: number;
|
||||
uptime: string;
|
||||
free_mem: number;
|
||||
}
|
||||
|
||||
export interface ESP32SystemStatus extends ESPSystemStatus {
|
||||
esp_platform: EspPlatform.ESP32
|
||||
psram_size: number
|
||||
free_psram: number
|
||||
esp_platform: EspPlatform.ESP32;
|
||||
psram_size: number;
|
||||
free_psram: number;
|
||||
}
|
||||
|
||||
export interface ESP8266SystemStatus extends ESPSystemStatus {
|
||||
esp_platform: EspPlatform.ESP8266
|
||||
heap_fragmentation: number
|
||||
esp_platform: EspPlatform.ESP8266;
|
||||
heap_fragmentation: number;
|
||||
}
|
||||
|
||||
export type SystemStatus = ESP8266SystemStatus | ESP32SystemStatus
|
||||
export type SystemStatus = ESP8266SystemStatus | ESP32SystemStatus;
|
||||
|
||||
export interface OTASettings {
|
||||
enabled: boolean
|
||||
port: number
|
||||
password: string
|
||||
enabled: boolean;
|
||||
port: number;
|
||||
password: string;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user