replace Refresh with Alova useAutoRequest()

This commit is contained in:
proddy
2024-08-10 20:54:57 +02:00
parent cde8ba0e9e
commit 962d007d91
11 changed files with 410 additions and 533 deletions

View File

@@ -5,7 +5,6 @@ import { toast } from 'react-toastify';
import AddIcon from '@mui/icons-material/Add'; import AddIcon from '@mui/icons-material/Add';
import CancelIcon from '@mui/icons-material/Cancel'; import CancelIcon from '@mui/icons-material/Cancel';
import EditOutlinedIcon from '@mui/icons-material/EditOutlined'; import EditOutlinedIcon from '@mui/icons-material/EditOutlined';
import RefreshIcon from '@mui/icons-material/Refresh';
import WarningIcon from '@mui/icons-material/Warning'; import WarningIcon from '@mui/icons-material/Warning';
import { Box, Button, Typography } from '@mui/material'; import { Box, Button, Typography } from '@mui/material';
@@ -19,7 +18,7 @@ import {
Table Table
} from '@table-library/react-table-library/table'; } from '@table-library/react-table-library/table';
import { useTheme } from '@table-library/react-table-library/theme'; import { useTheme } from '@table-library/react-table-library/theme';
import { updateState, useRequest } from 'alova/client'; import { updateState, useAutoRequest, useRequest } from 'alova/client';
import { import {
BlockNavigation, BlockNavigation,
ButtonRow, ButtonRow,
@@ -49,8 +48,9 @@ const CustomEntities = () => {
data: entities, data: entities,
send: fetchEntities, send: fetchEntities,
error error
} = useRequest(readCustomEntities, { } = useAutoRequest(readCustomEntities, {
initialData: [] initialData: [],
pollingTime: 2000
}); });
const { send: writeEntities } = useRequest( const { send: writeEntities } = useRequest(
@@ -324,24 +324,14 @@ const CustomEntities = () => {
)} )}
</Box> </Box>
<Box flexWrap="nowrap" whiteSpace="nowrap"> <Box flexWrap="nowrap" whiteSpace="nowrap">
<ButtonRow> <Button
<Button startIcon={<AddIcon />}
startIcon={<RefreshIcon />} variant="outlined"
variant="outlined" color="primary"
color="secondary" onClick={addEntityItem}
onClick={fetchEntities} >
> {LL.ADD(0)}
{LL.REFRESH()} </Button>
</Button>
<Button
startIcon={<AddIcon />}
variant="outlined"
color="primary"
onClick={addEntityItem}
>
{LL.ADD(0)}
</Button>
</ButtonRow>
</Box> </Box>
</Box> </Box>
</SectionContent> </SectionContent>

View File

@@ -19,7 +19,6 @@ import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined';
import KeyboardArrowDownOutlinedIcon from '@mui/icons-material/KeyboardArrowDownOutlined'; import KeyboardArrowDownOutlinedIcon from '@mui/icons-material/KeyboardArrowDownOutlined';
import KeyboardArrowUpOutlinedIcon from '@mui/icons-material/KeyboardArrowUpOutlined'; import KeyboardArrowUpOutlinedIcon from '@mui/icons-material/KeyboardArrowUpOutlined';
import PlayArrowIcon from '@mui/icons-material/PlayArrow'; import PlayArrowIcon from '@mui/icons-material/PlayArrow';
import RefreshIcon from '@mui/icons-material/Refresh';
import StarIcon from '@mui/icons-material/Star'; import StarIcon from '@mui/icons-material/Star';
import StarBorderOutlinedIcon from '@mui/icons-material/StarBorderOutlined'; import StarBorderOutlinedIcon from '@mui/icons-material/StarBorderOutlined';
import UnfoldMoreOutlinedIcon from '@mui/icons-material/UnfoldMoreOutlined'; import UnfoldMoreOutlinedIcon from '@mui/icons-material/UnfoldMoreOutlined';
@@ -56,8 +55,8 @@ import {
import { useTheme } from '@table-library/react-table-library/theme'; import { useTheme } from '@table-library/react-table-library/theme';
import type { Action, State } from '@table-library/react-table-library/types/common'; import type { Action, State } from '@table-library/react-table-library/types/common';
import { dialogStyle } from 'CustomTheme'; import { dialogStyle } from 'CustomTheme';
import { useRequest } from 'alova/client'; import { useAutoRequest, useRequest } from 'alova/client';
import { ButtonRow, MessageBox, SectionContent, useLayoutTitle } from 'components'; import { MessageBox, SectionContent, useLayoutTitle } from 'components';
import { AuthenticatedContext } from 'contexts/authentication'; import { AuthenticatedContext } from 'contexts/authentication';
import { useI18nContext } from 'i18n/i18n-react'; import { useI18nContext } from 'i18n/i18n-react';
@@ -84,12 +83,16 @@ const Devices = () => {
useLayoutTitle(LL.DEVICES()); useLayoutTitle(LL.DEVICES());
const { data: coreData, send: sendCoreData } = useRequest(() => readCoreData(), { const { data: coreData, send: sendCoreData } = useAutoRequest(
initialData: { () => readCoreData(),
connected: true, {
devices: [] initialData: {
connected: true,
devices: []
},
pollingTime: 2000
} }
}); );
const { data: deviceData, send: sendDeviceData } = useRequest( const { data: deviceData, send: sendDeviceData } = useRequest(
(id: number) => readDeviceData(id), (id: number) => readDeviceData(id),
@@ -681,11 +684,6 @@ const Devices = () => {
)} )}
</IconButton> </IconButton>
</ButtonTooltip> </ButtonTooltip>
<ButtonTooltip title={LL.REFRESH()}>
<IconButton onClick={refreshData}>
<RefreshIcon color="primary" sx={{ fontSize: 18 }} />
</IconButton>
</ButtonTooltip>
</Typography> </Typography>
<Grid item zeroMinWidth justifyContent="flex-end"> <Grid item zeroMinWidth justifyContent="flex-end">
<ButtonTooltip title={LL.CANCEL()}> <ButtonTooltip title={LL.CANCEL()}>
@@ -780,16 +778,6 @@ const Devices = () => {
progress={submitting} progress={submitting}
/> />
)} )}
<ButtonRow mt={1}>
<Button
startIcon={<RefreshIcon />}
variant="outlined"
color="secondary"
onClick={refreshData}
>
{LL.REFRESH()}
</Button>
</ButtonRow>
</SectionContent> </SectionContent>
); );
}; };

View File

@@ -53,18 +53,18 @@ const Help = () => {
return ( return (
<> <>
<SectionContent> <SectionContent>
<List sx={{ borderRadius: 3, border: '2px solid grey' }}> <List sx={{ borderRadius: 3, border: '2px solid grey' }}>
<ListItem> <ListItem>
<ListItemButton component="a" href="https://emsesp.org"> <ListItemButton component="a" href="https://emsesp.org">
<ListItemAvatar> <ListItemAvatar>
<Avatar sx={{ bgcolor: '#72caf9' }}> <Avatar sx={{ bgcolor: '#72caf9' }}>
<MenuBookIcon /> <MenuBookIcon />
</Avatar> </Avatar>
</ListItemAvatar> </ListItemAvatar>
<ListItemText primary={LL.HELP_INFORMATION_1()} /> <ListItemText primary={LL.HELP_INFORMATION_1()} />
</ListItemButton> </ListItemButton>
</ListItem> </ListItem>
<ListItem> <ListItem>
<ListItemButton component="a" href="https://discord.gg/3J3GgnzpyT"> <ListItemButton component="a" href="https://discord.gg/3J3GgnzpyT">

View File

@@ -4,7 +4,6 @@ import { toast } from 'react-toastify';
import AddCircleOutlineOutlinedIcon from '@mui/icons-material/AddCircleOutlineOutlined'; import AddCircleOutlineOutlinedIcon from '@mui/icons-material/AddCircleOutlineOutlined';
import KeyboardArrowDownOutlinedIcon from '@mui/icons-material/KeyboardArrowDownOutlined'; import KeyboardArrowDownOutlinedIcon from '@mui/icons-material/KeyboardArrowDownOutlined';
import KeyboardArrowUpOutlinedIcon from '@mui/icons-material/KeyboardArrowUpOutlined'; import KeyboardArrowUpOutlinedIcon from '@mui/icons-material/KeyboardArrowUpOutlined';
import RefreshIcon from '@mui/icons-material/Refresh';
import UnfoldMoreOutlinedIcon from '@mui/icons-material/UnfoldMoreOutlined'; import UnfoldMoreOutlinedIcon from '@mui/icons-material/UnfoldMoreOutlined';
import { Box, Button, Typography } from '@mui/material'; import { Box, Button, Typography } from '@mui/material';
@@ -20,8 +19,8 @@ import {
} from '@table-library/react-table-library/table'; } from '@table-library/react-table-library/table';
import { useTheme } from '@table-library/react-table-library/theme'; import { useTheme } from '@table-library/react-table-library/theme';
import type { State } from '@table-library/react-table-library/types/common'; import type { State } from '@table-library/react-table-library/types/common';
import { useRequest } from 'alova/client'; import { useAutoRequest, useRequest } from 'alova/client';
import { ButtonRow, SectionContent, useLayoutTitle } from 'components'; import { SectionContent, useLayoutTitle } from 'components';
import { AuthenticatedContext } from 'contexts/authentication'; import { AuthenticatedContext } from 'contexts/authentication';
import { useI18nContext } from 'i18n/i18n-react'; import { useI18nContext } from 'i18n/i18n-react';
@@ -60,7 +59,7 @@ const Sensors = () => {
const [analogDialogOpen, setAnalogDialogOpen] = useState<boolean>(false); const [analogDialogOpen, setAnalogDialogOpen] = useState<boolean>(false);
const [creating, setCreating] = useState<boolean>(false); const [creating, setCreating] = useState<boolean>(false);
const { data: sensorData, send: sendSensorData } = useRequest( const { data: sensorData, send: sendSensorData } = useAutoRequest(
() => readSensorData(), () => readSensorData(),
{ {
initialData: { initialData: {
@@ -68,7 +67,8 @@ const Sensors = () => {
as: [], as: [],
analog_enabled: false, analog_enabled: false,
platform: 'ESP32' platform: 'ESP32'
} },
pollingTime: 2000
} }
); );
@@ -500,30 +500,18 @@ const Sensors = () => {
)} )}
</> </>
)} )}
<ButtonRow> <Box mt={1} display="flex" flexWrap="wrap">
<Box mt={1} display="flex" flexWrap="wrap"> {sensorData?.analog_enabled === true && me.admin && (
<Box flexGrow={1}> <Button
<Button variant="outlined"
startIcon={<RefreshIcon />} color="primary"
variant="outlined" startIcon={<AddCircleOutlineOutlinedIcon />}
color="secondary" onClick={addAnalogSensor}
onClick={sendSensorData} >
> {LL.ADD(0) + ' ' + LL.ANALOG_SENSOR(1)}
{LL.REFRESH()} </Button>
</Button> )}
</Box> </Box>
{sensorData?.analog_enabled === true && me.admin && (
<Button
variant="outlined"
color="primary"
startIcon={<AddCircleOutlineOutlinedIcon />}
onClick={addAnalogSensor}
>
{LL.ADD(0) + ' ' + LL.ANALOG_SENSOR(1)}
</Button>
)}
</Box>
</ButtonRow>
</SectionContent> </SectionContent>
); );
}; };

View File

@@ -1,10 +1,8 @@
import ComputerIcon from '@mui/icons-material/Computer'; import ComputerIcon from '@mui/icons-material/Computer';
import DeviceHubIcon from '@mui/icons-material/DeviceHub'; import DeviceHubIcon from '@mui/icons-material/DeviceHub';
import RefreshIcon from '@mui/icons-material/Refresh';
import SettingsInputAntennaIcon from '@mui/icons-material/SettingsInputAntenna'; import SettingsInputAntennaIcon from '@mui/icons-material/SettingsInputAntenna';
import { import {
Avatar, Avatar,
Button,
Divider, Divider,
List, List,
ListItem, ListItem,
@@ -16,8 +14,8 @@ import type { Theme } from '@mui/material';
import * as APApi from 'api/ap'; import * as APApi from 'api/ap';
import { useRequest } from 'alova/client'; import { useAutoRequest } from 'alova/client';
import { ButtonRow, FormLoader, SectionContent, useLayoutTitle } from 'components'; import { FormLoader, SectionContent, useLayoutTitle } from 'components';
import { useI18nContext } from 'i18n/i18n-react'; import { useI18nContext } from 'i18n/i18n-react';
import type { APStatusType } from 'types'; import type { APStatusType } from 'types';
import { APNetworkStatus } from 'types'; import { APNetworkStatus } from 'types';
@@ -36,7 +34,11 @@ export const apStatusHighlight = ({ status }: APStatusType, theme: Theme) => {
}; };
const APStatus = () => { const APStatus = () => {
const { data: data, send: loadData, error } = useRequest(APApi.readAPStatus); const {
data: data,
send: loadData,
error
} = useAutoRequest(APApi.readAPStatus, { pollingTime: 5000 });
const { LL } = useI18nContext(); const { LL } = useI18nContext();
useLayoutTitle(LL.STATUS_OF(LL.ACCESS_POINT(0))); useLayoutTitle(LL.STATUS_OF(LL.ACCESS_POINT(0)));
@@ -62,60 +64,45 @@ const APStatus = () => {
} }
return ( return (
<> <List>
<List> <ListItem>
<ListItem> <ListItemAvatar>
<ListItemAvatar> <Avatar sx={{ bgcolor: apStatusHighlight(data, theme) }}>
<Avatar sx={{ bgcolor: apStatusHighlight(data, theme) }}> <SettingsInputAntennaIcon />
<SettingsInputAntennaIcon /> </Avatar>
</Avatar> </ListItemAvatar>
</ListItemAvatar> <ListItemText primary={LL.STATUS_OF('')} secondary={apStatus(data)} />
<ListItemText primary={LL.STATUS_OF('')} secondary={apStatus(data)} /> </ListItem>
</ListItem> <Divider variant="inset" component="li" />
<Divider variant="inset" component="li" /> <ListItem>
<ListItem> <ListItemAvatar>
<ListItemAvatar> <Avatar>IP</Avatar>
<Avatar>IP</Avatar> </ListItemAvatar>
</ListItemAvatar> <ListItemText primary={LL.ADDRESS_OF('IP')} secondary={data.ip_address} />
<ListItemText </ListItem>
primary={LL.ADDRESS_OF('IP')} <Divider variant="inset" component="li" />
secondary={data.ip_address} <ListItem>
/> <ListItemAvatar>
</ListItem> <Avatar>
<Divider variant="inset" component="li" /> <DeviceHubIcon />
<ListItem> </Avatar>
<ListItemAvatar> </ListItemAvatar>
<Avatar> <ListItemText
<DeviceHubIcon /> primary={LL.ADDRESS_OF('MAC')}
</Avatar> secondary={data.mac_address}
</ListItemAvatar> />
<ListItemText </ListItem>
primary={LL.ADDRESS_OF('MAC')} <Divider variant="inset" component="li" />
secondary={data.mac_address} <ListItem>
/> <ListItemAvatar>
</ListItem> <Avatar>
<Divider variant="inset" component="li" /> <ComputerIcon />
<ListItem> </Avatar>
<ListItemAvatar> </ListItemAvatar>
<Avatar> <ListItemText primary={LL.AP_CLIENTS()} secondary={data.station_num} />
<ComputerIcon /> </ListItem>
</Avatar> <Divider variant="inset" component="li" />
</ListItemAvatar> </List>
<ListItemText primary={LL.AP_CLIENTS()} secondary={data.station_num} />
</ListItem>
<Divider variant="inset" component="li" />
</List>
<ButtonRow>
<Button
startIcon={<RefreshIcon />}
variant="outlined"
color="secondary"
onClick={loadData}
>
{LL.REFRESH()}
</Button>
</ButtonRow>
</>
); );
}; };

View File

@@ -1,8 +1,5 @@
import { useEffect } from 'react'; import { useEffect } from 'react';
import RefreshIcon from '@mui/icons-material/Refresh';
import { Button } from '@mui/material';
import { import {
Body, Body,
Cell, Cell,
@@ -13,16 +10,20 @@ import {
Table Table
} from '@table-library/react-table-library/table'; } from '@table-library/react-table-library/table';
import { useTheme as tableTheme } from '@table-library/react-table-library/theme'; import { useTheme as tableTheme } from '@table-library/react-table-library/theme';
import { useRequest } from 'alova/client'; import { useAutoRequest } from 'alova/client';
import { ButtonRow, FormLoader, SectionContent, useLayoutTitle } from 'components'; import { FormLoader, SectionContent, useLayoutTitle } from 'components';
import { useI18nContext } from 'i18n/i18n-react'; import { useI18nContext } from 'i18n/i18n-react';
import type { Translation } from 'i18n/i18n-types'; import type { Translation } from 'i18n/i18n-types';
import * as EMSESP from '../../api/app'; import { readActivity } from '../../api/app';
import type { Stat } from '../main/types'; import type { Stat } from '../main/types';
const SystemActivity = () => { const SystemActivity = () => {
const { data: data, send: loadData, error } = useRequest(EMSESP.readActivity); const {
data: data,
send: loadData,
error
} = useAutoRequest(readActivity, { pollingTime: 2000 });
const { LL } = useI18nContext(); const { LL } = useI18nContext();
@@ -98,46 +99,34 @@ const SystemActivity = () => {
} }
return ( return (
<> <Table
<Table data={{ nodes: data.stats }}
data={{ nodes: data.stats }} theme={stats_theme}
theme={stats_theme} layout={{ custom: true }}
layout={{ custom: true }} >
> {(tableList: Stat[]) => (
{(tableList: Stat[]) => ( <>
<> <Header>
<Header> <HeaderRow>
<HeaderRow> <HeaderCell resize />
<HeaderCell resize /> <HeaderCell stiff>{LL.SUCCESS()}</HeaderCell>
<HeaderCell stiff>{LL.SUCCESS()}</HeaderCell> <HeaderCell stiff>{LL.FAIL()}</HeaderCell>
<HeaderCell stiff>{LL.FAIL()}</HeaderCell> <HeaderCell stiff>{LL.QUALITY()}</HeaderCell>
<HeaderCell stiff>{LL.QUALITY()}</HeaderCell> </HeaderRow>
</HeaderRow> </Header>
</Header> <Body>
<Body> {tableList.map((stat: Stat) => (
{tableList.map((stat: Stat) => ( <Row key={stat.id} item={stat}>
<Row key={stat.id} item={stat}> <Cell>{showName(stat.id)}</Cell>
<Cell>{showName(stat.id)}</Cell> <Cell stiff>{Intl.NumberFormat().format(stat.s)}</Cell>
<Cell stiff>{Intl.NumberFormat().format(stat.s)}</Cell> <Cell stiff>{Intl.NumberFormat().format(stat.f)}</Cell>
<Cell stiff>{Intl.NumberFormat().format(stat.f)}</Cell> <Cell stiff>{showQuality(stat)}</Cell>
<Cell stiff>{showQuality(stat)}</Cell> </Row>
</Row> ))}
))} </Body>
</Body> </>
</> )}
)} </Table>
</Table>
<ButtonRow mt={1}>
<Button
startIcon={<RefreshIcon />}
variant="outlined"
color="secondary"
onClick={loadData}
>
{LL.REFRESH()}
</Button>
</ButtonRow>
</>
); );
}; };

View File

@@ -3,14 +3,11 @@ import DeveloperBoardIcon from '@mui/icons-material/DeveloperBoard';
import DevicesIcon from '@mui/icons-material/Devices'; import DevicesIcon from '@mui/icons-material/Devices';
import FolderIcon from '@mui/icons-material/Folder'; import FolderIcon from '@mui/icons-material/Folder';
import MemoryIcon from '@mui/icons-material/Memory'; import MemoryIcon from '@mui/icons-material/Memory';
import RefreshIcon from '@mui/icons-material/Refresh';
import SdCardAlertIcon from '@mui/icons-material/SdCardAlert'; import SdCardAlertIcon from '@mui/icons-material/SdCardAlert';
import SdStorageIcon from '@mui/icons-material/SdStorage'; import SdStorageIcon from '@mui/icons-material/SdStorage';
import TapAndPlayIcon from '@mui/icons-material/TapAndPlay'; import TapAndPlayIcon from '@mui/icons-material/TapAndPlay';
import { import {
Avatar, Avatar,
Box,
Button,
Divider, Divider,
List, List,
ListItem, ListItem,
@@ -20,8 +17,8 @@ import {
import * as SystemApi from 'api/system'; import * as SystemApi from 'api/system';
import { useRequest } from 'alova/client'; import { useAutoRequest } from 'alova/client';
import { ButtonRow, FormLoader, SectionContent, useLayoutTitle } from 'components'; import { FormLoader, SectionContent, useLayoutTitle } from 'components';
import { useI18nContext } from 'i18n/i18n-react'; import { useI18nContext } from 'i18n/i18n-react';
import BBQKeesIcon from './bbqkees.svg'; import BBQKeesIcon from './bbqkees.svg';
@@ -39,7 +36,7 @@ const HardwareStatus = () => {
data: data, data: data,
send: loadData, send: loadData,
error error
} = useRequest(SystemApi.readHardwareStatus); } = useAutoRequest(SystemApi.readHardwareStatus, { pollingTime: 2000 });
const content = () => { const content = () => {
if (!data) { if (!data) {
@@ -47,171 +44,155 @@ const HardwareStatus = () => {
} }
return ( return (
<> <List>
<List> <ListItem>
<ListItem> <ListItemAvatar>
<ListItemAvatar> <Avatar sx={{ bgcolor: '#003289', color: 'white' }}>
<Avatar sx={{ bgcolor: '#003289', color: 'white' }}> {data.model ? (
{data.model ? ( <img
<img src={BBQKeesIcon}
src={BBQKeesIcon} style={{ width: 16, verticalAlign: 'middle' }}
style={{ width: 16, verticalAlign: 'middle' }}
/>
) : (
<TapAndPlayIcon />
)}
</Avatar>
</ListItemAvatar>
<ListItemText
primary={LL.HARDWARE() + ' ' + LL.DEVICE()}
secondary={data.model ? data.model : data.cpu_type}
/>
</ListItem>
<Divider variant="inset" component="li" />
<ListItem>
<ListItemAvatar>
<Avatar sx={{ bgcolor: '#5f9a5f', color: 'white' }}>
<DevicesIcon />
</Avatar>
</ListItemAvatar>
<ListItemText
primary="SDK"
secondary={data.arduino_version + ' / ESP-IDF ' + data.sdk_version}
/>
</ListItem>
<Divider variant="inset" component="li" />
<ListItem>
<ListItemAvatar>
<Avatar sx={{ bgcolor: '#5f9a5f', color: 'white' }}>
<DeveloperBoardIcon />
</Avatar>
</ListItemAvatar>
<ListItemText
primary="CPU"
secondary={
data.esp_platform +
'/' +
data.cpu_type +
' (rev.' +
data.cpu_rev +
', ' +
(data.cpu_cores == 1 ? 'single-core)' : 'dual-core)') +
' @ ' +
data.cpu_freq_mhz +
' Mhz'
}
/>
</ListItem>
<Divider variant="inset" component="li" />
<ListItem>
<ListItemAvatar>
<Avatar sx={{ bgcolor: '#5f9a5f', color: 'white' }}>
<MemoryIcon />
</Avatar>
</ListItemAvatar>
<ListItemText
primary={LL.FREE_MEMORY()}
secondary={
formatNumber(data.free_heap) +
' KB (' +
formatNumber(data.max_alloc_heap) +
' KB max alloc, ' +
formatNumber(data.free_caps) +
' KB caps)'
}
/>
</ListItem>
{data.psram_size !== undefined && data.free_psram !== undefined && (
<>
<Divider variant="inset" component="li" />
<ListItem>
<ListItemAvatar>
<Avatar sx={{ bgcolor: '#5f9a5f', color: 'white' }}>
<AppsIcon />
</Avatar>
</ListItemAvatar>
<ListItemText
primary={LL.PSRAM()}
secondary={
formatNumber(data.psram_size) +
' KB / ' +
formatNumber(data.free_psram) +
' KB'
}
/> />
</ListItem> ) : (
</> <TapAndPlayIcon />
)} )}
<Divider variant="inset" component="li" /> </Avatar>
<ListItem> </ListItemAvatar>
<ListItemAvatar> <ListItemText
<Avatar sx={{ bgcolor: '#5f9a5f', color: 'white' }}> primary={LL.HARDWARE() + ' ' + LL.DEVICE()}
<SdStorageIcon /> secondary={data.model ? data.model : data.cpu_type}
</Avatar> />
</ListItemAvatar> </ListItem>
<ListItemText <Divider variant="inset" component="li" />
primary={LL.FLASH()} <ListItem>
secondary={ <ListItemAvatar>
formatNumber(data.flash_chip_size) + <Avatar sx={{ bgcolor: '#5f9a5f', color: 'white' }}>
' KB , ' + <DevicesIcon />
(data.flash_chip_speed / 1000000).toFixed(0) + </Avatar>
' MHz' </ListItemAvatar>
} <ListItemText
/> primary="SDK"
</ListItem> secondary={data.arduino_version + ' / ESP-IDF ' + data.sdk_version}
<Divider variant="inset" component="li" /> />
<ListItem> </ListItem>
<ListItemAvatar> <Divider variant="inset" component="li" />
<Avatar sx={{ bgcolor: '#5f9a5f', color: 'white' }}> <ListItem>
<SdCardAlertIcon /> <ListItemAvatar>
</Avatar> <Avatar sx={{ bgcolor: '#5f9a5f', color: 'white' }}>
</ListItemAvatar> <DeveloperBoardIcon />
<ListItemText </Avatar>
primary={LL.APPSIZE()} </ListItemAvatar>
secondary={ <ListItemText
data.partition + primary="CPU"
': ' + secondary={
formatNumber(data.app_used) + data.esp_platform +
' KB / ' + '/' +
formatNumber(data.app_free) + data.cpu_type +
' KB' ' (rev.' +
} data.cpu_rev +
/> ', ' +
</ListItem> (data.cpu_cores == 1 ? 'single-core)' : 'dual-core)') +
<Divider variant="inset" component="li" /> ' @ ' +
<ListItem> data.cpu_freq_mhz +
<ListItemAvatar> ' Mhz'
<Avatar sx={{ bgcolor: '#5f9a5f', color: 'white' }}> }
<FolderIcon /> />
</Avatar> </ListItem>
</ListItemAvatar> <Divider variant="inset" component="li" />
<ListItemText <ListItem>
primary={LL.FILESYSTEM()} <ListItemAvatar>
secondary={ <Avatar sx={{ bgcolor: '#5f9a5f', color: 'white' }}>
formatNumber(data.fs_used) + <MemoryIcon />
' KB / ' + </Avatar>
formatNumber(data.fs_free) + </ListItemAvatar>
' KB' <ListItemText
} primary={LL.FREE_MEMORY()}
/> secondary={
</ListItem> formatNumber(data.free_heap) +
<Divider variant="inset" component="li" /> ' KB (' +
</List> formatNumber(data.max_alloc_heap) +
<Box display="flex" flexWrap="wrap"> ' KB max alloc, ' +
<Box flexGrow={1} sx={{ '& button': { mt: 2 } }}> formatNumber(data.free_caps) +
<ButtonRow> ' KB caps)'
<Button }
startIcon={<RefreshIcon />} />
variant="outlined" </ListItem>
color="secondary" {data.psram_size !== undefined && data.free_psram !== undefined && (
onClick={loadData} <>
> <Divider variant="inset" component="li" />
{LL.REFRESH()} <ListItem>
</Button> <ListItemAvatar>
</ButtonRow> <Avatar sx={{ bgcolor: '#5f9a5f', color: 'white' }}>
</Box> <AppsIcon />
</Box> </Avatar>
</> </ListItemAvatar>
<ListItemText
primary={LL.PSRAM()}
secondary={
formatNumber(data.psram_size) +
' KB / ' +
formatNumber(data.free_psram) +
' KB'
}
/>
</ListItem>
</>
)}
<Divider variant="inset" component="li" />
<ListItem>
<ListItemAvatar>
<Avatar sx={{ bgcolor: '#5f9a5f', color: 'white' }}>
<SdStorageIcon />
</Avatar>
</ListItemAvatar>
<ListItemText
primary={LL.FLASH()}
secondary={
formatNumber(data.flash_chip_size) +
' KB , ' +
(data.flash_chip_speed / 1000000).toFixed(0) +
' MHz'
}
/>
</ListItem>
<Divider variant="inset" component="li" />
<ListItem>
<ListItemAvatar>
<Avatar sx={{ bgcolor: '#5f9a5f', color: 'white' }}>
<SdCardAlertIcon />
</Avatar>
</ListItemAvatar>
<ListItemText
primary={LL.APPSIZE()}
secondary={
data.partition +
': ' +
formatNumber(data.app_used) +
' KB / ' +
formatNumber(data.app_free) +
' KB'
}
/>
</ListItem>
<Divider variant="inset" component="li" />
<ListItem>
<ListItemAvatar>
<Avatar sx={{ bgcolor: '#5f9a5f', color: 'white' }}>
<FolderIcon />
</Avatar>
</ListItemAvatar>
<ListItemText
primary={LL.FILESYSTEM()}
secondary={
formatNumber(data.fs_used) +
' KB / ' +
formatNumber(data.fs_free) +
' KB'
}
/>
</ListItem>
<Divider variant="inset" component="li" />
</List>
); );
}; };

View File

@@ -1,11 +1,9 @@
import AutoAwesomeMotionIcon from '@mui/icons-material/AutoAwesomeMotion'; import AutoAwesomeMotionIcon from '@mui/icons-material/AutoAwesomeMotion';
import DeviceHubIcon from '@mui/icons-material/DeviceHub'; import DeviceHubIcon from '@mui/icons-material/DeviceHub';
import RefreshIcon from '@mui/icons-material/Refresh';
import ReportIcon from '@mui/icons-material/Report'; import ReportIcon from '@mui/icons-material/Report';
import SpeakerNotesOffIcon from '@mui/icons-material/SpeakerNotesOff'; import SpeakerNotesOffIcon from '@mui/icons-material/SpeakerNotesOff';
import { import {
Avatar, Avatar,
Button,
Divider, Divider,
List, List,
ListItem, ListItem,
@@ -17,8 +15,8 @@ import type { Theme } from '@mui/material';
import * as MqttApi from 'api/mqtt'; import * as MqttApi from 'api/mqtt';
import { useRequest } from 'alova/client'; import { useAutoRequest } from 'alova/client';
import { ButtonRow, FormLoader, SectionContent, useLayoutTitle } from 'components'; import { FormLoader, SectionContent, useLayoutTitle } from 'components';
import { useI18nContext } from 'i18n/i18n-react'; import { useI18nContext } from 'i18n/i18n-react';
import type { MqttStatusType } from 'types'; import type { MqttStatusType } from 'types';
import { MqttDisconnectReason } from 'types'; import { MqttDisconnectReason } from 'types';
@@ -56,7 +54,11 @@ export const mqttQueueHighlight = (
}; };
const MqttStatus = () => { const MqttStatus = () => {
const { data: data, send: loadData, error } = useRequest(MqttApi.readMqttStatus); const {
data: data,
send: loadData,
error
} = useAutoRequest(MqttApi.readMqttStatus, { pollingTime: 5000 });
const { LL } = useI18nContext(); const { LL } = useI18nContext();
useLayoutTitle(LL.STATUS_OF('MQTT')); useLayoutTitle(LL.STATUS_OF('MQTT'));
@@ -146,30 +148,18 @@ const MqttStatus = () => {
); );
return ( return (
<> <List>
<List> <ListItem>
<ListItem> <ListItemAvatar>
<ListItemAvatar> <Avatar sx={{ bgcolor: mqttStatusHighlight(data, theme) }}>
<Avatar sx={{ bgcolor: mqttStatusHighlight(data, theme) }}> <DeviceHubIcon />
<DeviceHubIcon /> </Avatar>
</Avatar> </ListItemAvatar>
</ListItemAvatar> <ListItemText primary={LL.STATUS_OF('')} secondary={mqttStatus(data)} />
<ListItemText primary={LL.STATUS_OF('')} secondary={mqttStatus(data)} /> </ListItem>
</ListItem> <Divider variant="inset" component="li" />
<Divider variant="inset" component="li" /> {data.enabled && renderConnectionStatus()}
{data.enabled && renderConnectionStatus()} </List>
</List>
<ButtonRow>
<Button
startIcon={<RefreshIcon />}
variant="outlined"
color="secondary"
onClick={loadData}
>
{LL.REFRESH()}
</Button>
</ButtonRow>
</>
); );
}; };

View File

@@ -4,7 +4,6 @@ import { toast } from 'react-toastify';
import AccessTimeIcon from '@mui/icons-material/AccessTime'; import AccessTimeIcon from '@mui/icons-material/AccessTime';
import CancelIcon from '@mui/icons-material/Cancel'; import CancelIcon from '@mui/icons-material/Cancel';
import DnsIcon from '@mui/icons-material/Dns'; import DnsIcon from '@mui/icons-material/Dns';
import RefreshIcon from '@mui/icons-material/Refresh';
import SwapVerticalCircleIcon from '@mui/icons-material/SwapVerticalCircle'; import SwapVerticalCircleIcon from '@mui/icons-material/SwapVerticalCircle';
import UpdateIcon from '@mui/icons-material/Update'; import UpdateIcon from '@mui/icons-material/Update';
import { import {
@@ -29,7 +28,7 @@ import type { Theme } from '@mui/material';
import * as NTPApi from 'api/ntp'; import * as NTPApi from 'api/ntp';
import { dialogStyle } from 'CustomTheme'; import { dialogStyle } from 'CustomTheme';
import { useRequest } from 'alova/client'; import { useAutoRequest, useRequest } from 'alova/client';
import { ButtonRow, FormLoader, SectionContent, useLayoutTitle } from 'components'; import { ButtonRow, FormLoader, SectionContent, useLayoutTitle } from 'components';
import { useI18nContext } from 'i18n/i18n-react'; import { useI18nContext } from 'i18n/i18n-react';
import type { NTPStatusType, Time } from 'types'; import type { NTPStatusType, Time } from 'types';
@@ -37,7 +36,11 @@ import { NTPSyncStatus } from 'types';
import { formatDateTime, formatLocalDateTime } from 'utils'; import { formatDateTime, formatLocalDateTime } from 'utils';
const NTPStatus = () => { const NTPStatus = () => {
const { data: data, send: loadData, error } = useRequest(NTPApi.readNTPStatus); const {
data: data,
send: loadData,
error
} = useAutoRequest(NTPApi.readNTPStatus, { pollingTime: 5000 });
const [localTime, setLocalTime] = useState<string>(''); const [localTime, setLocalTime] = useState<string>('');
const [settingTime, setSettingTime] = useState<boolean>(false); const [settingTime, setSettingTime] = useState<boolean>(false);
@@ -214,18 +217,6 @@ const NTPStatus = () => {
<Divider variant="inset" component="li" /> <Divider variant="inset" component="li" />
</List> </List>
<Box display="flex" flexWrap="wrap"> <Box display="flex" flexWrap="wrap">
<Box flexGrow={1}>
<ButtonRow>
<Button
startIcon={<RefreshIcon />}
variant="outlined"
color="secondary"
onClick={loadData}
>
{LL.REFRESH()}
</Button>
</ButtonRow>
</Box>
{data && !isNtpActive(data) && ( {data && !isNtpActive(data) && (
<Box flexWrap="nowrap" whiteSpace="nowrap"> <Box flexWrap="nowrap" whiteSpace="nowrap">
<ButtonRow> <ButtonRow>

View File

@@ -1,14 +1,12 @@
import DeviceHubIcon from '@mui/icons-material/DeviceHub'; import DeviceHubIcon from '@mui/icons-material/DeviceHub';
import DnsIcon from '@mui/icons-material/Dns'; import DnsIcon from '@mui/icons-material/Dns';
import GiteIcon from '@mui/icons-material/Gite'; import GiteIcon from '@mui/icons-material/Gite';
import RefreshIcon from '@mui/icons-material/Refresh';
import RouterIcon from '@mui/icons-material/Router'; import RouterIcon from '@mui/icons-material/Router';
import SettingsInputAntennaIcon from '@mui/icons-material/SettingsInputAntenna'; import SettingsInputAntennaIcon from '@mui/icons-material/SettingsInputAntenna';
import SettingsInputComponentIcon from '@mui/icons-material/SettingsInputComponent'; import SettingsInputComponentIcon from '@mui/icons-material/SettingsInputComponent';
import WifiIcon from '@mui/icons-material/Wifi'; import WifiIcon from '@mui/icons-material/Wifi';
import { import {
Avatar, Avatar,
Button,
Divider, Divider,
List, List,
ListItem, ListItem,
@@ -20,8 +18,8 @@ import type { Theme } from '@mui/material';
import * as NetworkApi from 'api/network'; import * as NetworkApi from 'api/network';
import { useRequest } from 'alova/client'; import { useAutoRequest } from 'alova/client';
import { ButtonRow, FormLoader, SectionContent, useLayoutTitle } from 'components'; import { FormLoader, SectionContent, useLayoutTitle } from 'components';
import { useI18nContext } from 'i18n/i18n-react'; import { useI18nContext } from 'i18n/i18n-react';
import type { NetworkStatusType } from 'types'; import type { NetworkStatusType } from 'types';
import { NetworkConnectionStatus } from 'types'; import { NetworkConnectionStatus } from 'types';
@@ -87,7 +85,7 @@ const NetworkStatus = () => {
data: data, data: data,
send: loadData, send: loadData,
error error
} = useRequest(NetworkApi.readNetworkStatus); } = useAutoRequest(NetworkApi.readNetworkStatus, { pollingTime: 5000 });
const { LL } = useI18nContext(); const { LL } = useI18nContext();
useLayoutTitle(LL.STATUS_OF(LL.NETWORK(1))); useLayoutTitle(LL.STATUS_OF(LL.NETWORK(1)));
@@ -123,112 +121,99 @@ const NetworkStatus = () => {
} }
return ( return (
<> <List>
<List> <ListItem>
<ListItem> <ListItemAvatar>
<ListItemAvatar> <Avatar sx={{ bgcolor: networkStatusHighlight(data, theme) }}>
<Avatar sx={{ bgcolor: networkStatusHighlight(data, theme) }}> {isWiFi(data) && <WifiIcon />}
{isWiFi(data) && <WifiIcon />} {isEthernet(data) && <RouterIcon />}
{isEthernet(data) && <RouterIcon />} </Avatar>
</Avatar> </ListItemAvatar>
</ListItemAvatar> <ListItemText primary="Status" secondary={networkStatus(data)} />
<ListItemText primary="Status" secondary={networkStatus(data)} /> </ListItem>
</ListItem> <Divider variant="inset" component="li" />
<Divider variant="inset" component="li" /> <ListItem>
<ListItem> <ListItemAvatar>
<ListItemAvatar> <Avatar sx={{ bgcolor: networkStatusHighlight(data, theme) }}>
<Avatar sx={{ bgcolor: networkStatusHighlight(data, theme) }}> <GiteIcon />
<GiteIcon /> </Avatar>
</Avatar> </ListItemAvatar>
</ListItemAvatar> <ListItemText primary={LL.HOSTNAME()} secondary={data.hostname} />
<ListItemText primary={LL.HOSTNAME()} secondary={data.hostname} /> </ListItem>
</ListItem> <Divider variant="inset" component="li" />
<Divider variant="inset" component="li" /> {isWiFi(data) && (
{isWiFi(data) && ( <>
<> <ListItem>
<ListItem> <ListItemAvatar>
<ListItemAvatar> <Avatar sx={{ bgcolor: networkQualityHighlight(data, theme) }}>
<Avatar sx={{ bgcolor: networkQualityHighlight(data, theme) }}> <SettingsInputAntennaIcon />
<SettingsInputAntennaIcon /> </Avatar>
</Avatar> </ListItemAvatar>
</ListItemAvatar> <ListItemText
<ListItemText primary="SSID (RSSI)"
primary="SSID (RSSI)" secondary={data.ssid + ' (' + data.rssi + ' dBm)'}
secondary={data.ssid + ' (' + data.rssi + ' dBm)'} />
/> </ListItem>
</ListItem> <Divider variant="inset" component="li" />
<Divider variant="inset" component="li" /> </>
</> )}
)} {isConnected(data) && (
{isConnected(data) && ( <>
<> <ListItem>
<ListItem> <ListItemAvatar>
<ListItemAvatar> <Avatar>IP</Avatar>
<Avatar>IP</Avatar> </ListItemAvatar>
</ListItemAvatar> <ListItemText primary={LL.ADDRESS_OF('IP')} secondary={IPs(data)} />
<ListItemText primary={LL.ADDRESS_OF('IP')} secondary={IPs(data)} /> </ListItem>
</ListItem> <Divider variant="inset" component="li" />
<Divider variant="inset" component="li" /> <ListItem>
<ListItem> <ListItemAvatar>
<ListItemAvatar> <Avatar>
<Avatar> <DeviceHubIcon />
<DeviceHubIcon /> </Avatar>
</Avatar> </ListItemAvatar>
</ListItemAvatar> <ListItemText
<ListItemText primary={LL.ADDRESS_OF('MAC')}
primary={LL.ADDRESS_OF('MAC')} secondary={data.mac_address}
secondary={data.mac_address} />
/> </ListItem>
</ListItem> <Divider variant="inset" component="li" />
<Divider variant="inset" component="li" /> <ListItem>
<ListItem> <ListItemAvatar>
<ListItemAvatar> <Avatar>#</Avatar>
<Avatar>#</Avatar> </ListItemAvatar>
</ListItemAvatar> <ListItemText
<ListItemText primary={LL.NETWORK_SUBNET()}
primary={LL.NETWORK_SUBNET()} secondary={data.subnet_mask}
secondary={data.subnet_mask} />
/> </ListItem>
</ListItem> <Divider variant="inset" component="li" />
<Divider variant="inset" component="li" /> <ListItem>
<ListItem> <ListItemAvatar>
<ListItemAvatar> <Avatar>
<Avatar> <SettingsInputComponentIcon />
<SettingsInputComponentIcon /> </Avatar>
</Avatar> </ListItemAvatar>
</ListItemAvatar> <ListItemText
<ListItemText primary={LL.NETWORK_GATEWAY()}
primary={LL.NETWORK_GATEWAY()} secondary={data.gateway_ip || 'none'}
secondary={data.gateway_ip || 'none'} />
/> </ListItem>
</ListItem> <Divider variant="inset" component="li" />
<Divider variant="inset" component="li" /> <ListItem>
<ListItem> <ListItemAvatar>
<ListItemAvatar> <Avatar>
<Avatar> <DnsIcon />
<DnsIcon /> </Avatar>
</Avatar> </ListItemAvatar>
</ListItemAvatar> <ListItemText
<ListItemText primary={LL.NETWORK_DNS()}
primary={LL.NETWORK_DNS()} secondary={dnsServers(data)}
secondary={dnsServers(data)} />
/> </ListItem>
</ListItem> </>
<Divider variant="inset" component="li" /> )}
</> </List>
)}
</List>
<ButtonRow>
<Button
startIcon={<RefreshIcon />}
variant="outlined"
color="secondary"
onClick={loadData}
>
{LL.REFRESH()}
</Button>
</ButtonRow>
</>
); );
}; };

View File

@@ -10,7 +10,6 @@ import DirectionsBusIcon from '@mui/icons-material/DirectionsBus';
import LogoDevIcon from '@mui/icons-material/LogoDev'; import LogoDevIcon from '@mui/icons-material/LogoDev';
import MemoryIcon from '@mui/icons-material/Memory'; import MemoryIcon from '@mui/icons-material/Memory';
import PowerSettingsNewIcon from '@mui/icons-material/PowerSettingsNew'; import PowerSettingsNewIcon from '@mui/icons-material/PowerSettingsNew';
import RefreshIcon from '@mui/icons-material/Refresh';
import RouterIcon from '@mui/icons-material/Router'; import RouterIcon from '@mui/icons-material/Router';
import SettingsInputAntennaIcon from '@mui/icons-material/SettingsInputAntenna'; import SettingsInputAntennaIcon from '@mui/icons-material/SettingsInputAntenna';
import TimerIcon from '@mui/icons-material/Timer'; import TimerIcon from '@mui/icons-material/Timer';
@@ -18,7 +17,6 @@ import UpgradeIcon from '@mui/icons-material/Upgrade';
import WifiIcon from '@mui/icons-material/Wifi'; import WifiIcon from '@mui/icons-material/Wifi';
import { import {
Avatar, Avatar,
Box,
Button, Button,
Dialog, Dialog,
DialogActions, DialogActions,
@@ -34,7 +32,7 @@ import {
import * as SystemApi from 'api/system'; import * as SystemApi from 'api/system';
import { dialogStyle } from 'CustomTheme'; import { dialogStyle } from 'CustomTheme';
import { useRequest } from 'alova/client'; import { useAutoRequest, useRequest } from 'alova/client';
import { busConnectionStatus } from 'app/main/types'; import { busConnectionStatus } from 'app/main/types';
import { FormLoader, SectionContent, useLayoutTitle } from 'components'; import { FormLoader, SectionContent, useLayoutTitle } from 'components';
import ListMenuItem from 'components/layout/ListMenuItem'; import ListMenuItem from 'components/layout/ListMenuItem';
@@ -69,8 +67,9 @@ const SystemStatus = () => {
data: data, data: data,
send: loadData, send: loadData,
error error
} = useRequest(SystemApi.readSystemStatus, { } = useAutoRequest(SystemApi.readSystemStatus, {
initialData: [] initialData: [],
pollingTime: 5000
}); });
const theme = useTheme(); const theme = useTheme();
@@ -392,17 +391,6 @@ const SystemStatus = () => {
</List> </List>
{renderRestartDialog()} {renderRestartDialog()}
<Box mt={2} display="flex" flexWrap="wrap">
<Button
startIcon={<RefreshIcon />}
variant="outlined"
color="secondary"
onClick={loadData}
>
{LL.REFRESH()}
</Button>
</Box>
</> </>
); );
}; };