mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-07 08:19:52 +03:00
Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev
This commit is contained in:
@@ -43,10 +43,7 @@ const AuthenticatedRouting: FC = () => {
|
||||
<Route path="/settings/ntp/*" element={<NetworkTime />} />
|
||||
<Route path="/settings/mqtt/*" element={<Mqtt />} />
|
||||
<Route path="/settings/security/*" element={<Security />} />
|
||||
<Route
|
||||
path="/settings/espsystemstatus/*"
|
||||
element={<ESPSystemStatus />}
|
||||
/>
|
||||
<Route path="/system/espsystemstatus/*" element={<ESPSystemStatus />} />
|
||||
<Route path="/settings/upload/*" element={<UploadDownload />} />
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -15,8 +15,7 @@ export const dialogStyle = {
|
||||
borderColor: '#565656',
|
||||
borderStyle: 'solid',
|
||||
borderWidth: '1px'
|
||||
},
|
||||
backdropFilter: 'blur(1px)'
|
||||
}
|
||||
};
|
||||
|
||||
const theme = responsiveFontSizes(
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { type FC, useState } from 'react';
|
||||
import { toast } from 'react-toastify';
|
||||
|
||||
import AccessTimeIcon from '@mui/icons-material/AccessTime';
|
||||
import CancelIcon from '@mui/icons-material/Cancel';
|
||||
@@ -7,7 +6,6 @@ import DeviceHubIcon from '@mui/icons-material/DeviceHub';
|
||||
import ImportExportIcon from '@mui/icons-material/ImportExport';
|
||||
import LockIcon from '@mui/icons-material/Lock';
|
||||
import MemoryIcon from '@mui/icons-material/Memory';
|
||||
import PowerSettingsNewIcon from '@mui/icons-material/PowerSettingsNew';
|
||||
import SettingsBackupRestoreIcon from '@mui/icons-material/SettingsBackupRestore';
|
||||
import SettingsEthernetIcon from '@mui/icons-material/SettingsEthernet';
|
||||
import SettingsInputAntennaIcon from '@mui/icons-material/SettingsInputAntenna';
|
||||
@@ -19,6 +17,7 @@ import {
|
||||
DialogActions,
|
||||
DialogContent,
|
||||
DialogTitle,
|
||||
Divider,
|
||||
List
|
||||
} from '@mui/material';
|
||||
|
||||
@@ -26,118 +25,25 @@ import * as SystemApi from 'api/system';
|
||||
|
||||
import { dialogStyle } from 'CustomTheme';
|
||||
import { useRequest } from 'alova';
|
||||
import { ButtonRow, SectionContent, useLayoutTitle } from 'components';
|
||||
import { SectionContent, useLayoutTitle } from 'components';
|
||||
import ListMenuItem from 'components/layout/ListMenuItem';
|
||||
import { useI18nContext } from 'i18n/i18n-react';
|
||||
|
||||
import RestartMonitor from './system/RestartMonitor';
|
||||
|
||||
const Settings: FC = () => {
|
||||
const { LL } = useI18nContext();
|
||||
useLayoutTitle(LL.SETTINGS(0));
|
||||
|
||||
const [confirmRestart, setConfirmRestart] = useState<boolean>(false);
|
||||
const [confirmFactoryReset, setConfirmFactoryReset] = useState<boolean>(false);
|
||||
const [processing, setProcessing] = useState<boolean>(false);
|
||||
const [restarting, setRestarting] = useState<boolean>();
|
||||
|
||||
const { send: restartCommand } = useRequest(SystemApi.restart(), {
|
||||
immediate: false
|
||||
});
|
||||
|
||||
const { send: factoryResetCommand } = useRequest(SystemApi.factoryReset(), {
|
||||
immediate: false
|
||||
});
|
||||
|
||||
const { send: partitionCommand } = useRequest(SystemApi.partition(), {
|
||||
immediate: false
|
||||
});
|
||||
|
||||
const restart = async () => {
|
||||
setProcessing(true);
|
||||
await restartCommand()
|
||||
.then(() => {
|
||||
setRestarting(true);
|
||||
})
|
||||
.catch((error: Error) => {
|
||||
toast.error(error.message);
|
||||
})
|
||||
.finally(() => {
|
||||
setConfirmRestart(false);
|
||||
setProcessing(false);
|
||||
});
|
||||
};
|
||||
|
||||
const factoryReset = async () => {
|
||||
setProcessing(true);
|
||||
await factoryResetCommand()
|
||||
.then(() => {
|
||||
setRestarting(true);
|
||||
})
|
||||
.catch((error: Error) => {
|
||||
toast.error(error.message);
|
||||
})
|
||||
.finally(() => {
|
||||
setConfirmFactoryReset(false);
|
||||
setProcessing(false);
|
||||
});
|
||||
await factoryResetCommand();
|
||||
setConfirmFactoryReset(false);
|
||||
};
|
||||
|
||||
const partition = async () => {
|
||||
setProcessing(true);
|
||||
await partitionCommand()
|
||||
.then(() => {
|
||||
setRestarting(true);
|
||||
})
|
||||
.catch((error: Error) => {
|
||||
toast.error(error.message);
|
||||
})
|
||||
.finally(() => {
|
||||
setConfirmRestart(false);
|
||||
setProcessing(false);
|
||||
});
|
||||
};
|
||||
|
||||
const renderRestartDialog = () => (
|
||||
<Dialog
|
||||
sx={dialogStyle}
|
||||
open={confirmRestart}
|
||||
onClose={() => setConfirmRestart(false)}
|
||||
>
|
||||
<DialogTitle>{LL.RESTART()}</DialogTitle>
|
||||
<DialogContent dividers>{LL.RESTART_CONFIRM()}</DialogContent>
|
||||
<DialogActions>
|
||||
<Button
|
||||
startIcon={<CancelIcon />}
|
||||
variant="outlined"
|
||||
onClick={() => setConfirmRestart(false)}
|
||||
disabled={processing}
|
||||
color="secondary"
|
||||
>
|
||||
{LL.CANCEL()}
|
||||
</Button>
|
||||
<Button
|
||||
startIcon={<PowerSettingsNewIcon />}
|
||||
variant="outlined"
|
||||
onClick={restart}
|
||||
disabled={processing}
|
||||
color="primary"
|
||||
>
|
||||
{LL.RESTART()}
|
||||
</Button>
|
||||
<Button
|
||||
startIcon={<PowerSettingsNewIcon />}
|
||||
variant="outlined"
|
||||
onClick={partition}
|
||||
disabled={processing}
|
||||
color="primary"
|
||||
>
|
||||
EMS-ESP Loader
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
);
|
||||
|
||||
const renderFactoryResetDialog = () => (
|
||||
<Dialog
|
||||
sx={dialogStyle}
|
||||
@@ -151,7 +57,6 @@ const Settings: FC = () => {
|
||||
startIcon={<CancelIcon />}
|
||||
variant="outlined"
|
||||
onClick={() => setConfirmFactoryReset(false)}
|
||||
disabled={processing}
|
||||
color="secondary"
|
||||
>
|
||||
{LL.CANCEL()}
|
||||
@@ -160,7 +65,6 @@ const Settings: FC = () => {
|
||||
startIcon={<SettingsBackupRestoreIcon />}
|
||||
variant="outlined"
|
||||
onClick={factoryReset}
|
||||
disabled={processing}
|
||||
color="error"
|
||||
>
|
||||
{LL.FACTORY_RESET()}
|
||||
@@ -175,7 +79,7 @@ const Settings: FC = () => {
|
||||
<ListMenuItem
|
||||
icon={TuneIcon}
|
||||
bgcolor="#134ba2"
|
||||
label={LL.APPLICATION_SETTINGS()}
|
||||
label={LL.APPLICATION()}
|
||||
text={LL.APPLICATION_SETTINGS_1()}
|
||||
to="ems-esp"
|
||||
/>
|
||||
@@ -219,13 +123,7 @@ const Settings: FC = () => {
|
||||
to="security"
|
||||
/>
|
||||
|
||||
<ListMenuItem
|
||||
icon={MemoryIcon}
|
||||
bgcolor="#b1395f"
|
||||
label={LL.STATUS_OF('ESP32')}
|
||||
text="ESP32 Information"
|
||||
to="espsystemstatus"
|
||||
/>
|
||||
<Divider />
|
||||
|
||||
<ListMenuItem
|
||||
icon={ImportExportIcon}
|
||||
@@ -236,41 +134,22 @@ const Settings: FC = () => {
|
||||
/>
|
||||
</List>
|
||||
|
||||
{renderRestartDialog()}
|
||||
{renderFactoryResetDialog()}
|
||||
|
||||
<Box mt={1} display="flex" flexWrap="wrap">
|
||||
<Box flexGrow={1} sx={{ '& button': { mt: 2 } }}>
|
||||
<ButtonRow>
|
||||
<Button
|
||||
startIcon={<PowerSettingsNewIcon />}
|
||||
variant="outlined"
|
||||
color="primary"
|
||||
onClick={() => setConfirmRestart(true)}
|
||||
>
|
||||
{LL.RESTART()}
|
||||
</Button>
|
||||
</ButtonRow>
|
||||
</Box>
|
||||
<Box flexWrap="nowrap" whiteSpace="nowrap">
|
||||
<ButtonRow>
|
||||
<Button
|
||||
startIcon={<SettingsBackupRestoreIcon />}
|
||||
variant="outlined"
|
||||
onClick={() => setConfirmFactoryReset(true)}
|
||||
color="error"
|
||||
>
|
||||
{LL.FACTORY_RESET()}
|
||||
</Button>
|
||||
</ButtonRow>
|
||||
</Box>
|
||||
<Box mt={2} display="flex" flexWrap="wrap">
|
||||
<Button
|
||||
startIcon={<SettingsBackupRestoreIcon />}
|
||||
variant="outlined"
|
||||
onClick={() => setConfirmFactoryReset(true)}
|
||||
color="error"
|
||||
>
|
||||
{LL.FACTORY_RESET()}
|
||||
</Button>
|
||||
</Box>
|
||||
</>
|
||||
);
|
||||
|
||||
return (
|
||||
<SectionContent>{restarting ? <RestartMonitor /> : content()}</SectionContent>
|
||||
);
|
||||
return <SectionContent>{content()}</SectionContent>;
|
||||
};
|
||||
|
||||
export default Settings;
|
||||
|
||||
@@ -8,6 +8,7 @@ import DeviceHubIcon from '@mui/icons-material/DeviceHub';
|
||||
import DirectionsBusIcon from '@mui/icons-material/DirectionsBus';
|
||||
import MemoryIcon from '@mui/icons-material/Memory';
|
||||
import PermScanWifiIcon from '@mui/icons-material/PermScanWifi';
|
||||
import PowerSettingsNewIcon from '@mui/icons-material/PowerSettingsNew';
|
||||
import RefreshIcon from '@mui/icons-material/Refresh';
|
||||
import SettingsInputAntennaIcon from '@mui/icons-material/SettingsInputAntenna';
|
||||
import TimerIcon from '@mui/icons-material/Timer';
|
||||
@@ -39,6 +40,8 @@ import { useI18nContext } from 'i18n/i18n-react';
|
||||
import { busConnectionStatus } from 'project/types';
|
||||
import { NTPSyncStatus } from 'types';
|
||||
|
||||
import RestartMonitor from './RestartMonitor';
|
||||
|
||||
const SystemStatus: FC = () => {
|
||||
const { LL } = useI18nContext();
|
||||
|
||||
@@ -46,7 +49,18 @@ const SystemStatus: FC = () => {
|
||||
|
||||
const { me } = useContext(AuthenticatedContext);
|
||||
|
||||
const [confirmRestart, setConfirmRestart] = useState<boolean>(false);
|
||||
const [confirmScan, setConfirmScan] = useState<boolean>(false);
|
||||
const [processing, setProcessing] = useState<boolean>(false);
|
||||
const [restarting, setRestarting] = useState<boolean>();
|
||||
|
||||
const { send: restartCommand } = useRequest(SystemApi.restart(), {
|
||||
immediate: false
|
||||
});
|
||||
|
||||
const { send: partitionCommand } = useRequest(SystemApi.partition(), {
|
||||
immediate: false
|
||||
});
|
||||
|
||||
const {
|
||||
data: data,
|
||||
@@ -180,6 +194,76 @@ const SystemStatus: FC = () => {
|
||||
</Dialog>
|
||||
);
|
||||
|
||||
const restart = async () => {
|
||||
setProcessing(true);
|
||||
await restartCommand()
|
||||
.then(() => {
|
||||
setRestarting(true);
|
||||
})
|
||||
.catch((error: Error) => {
|
||||
toast.error(error.message);
|
||||
})
|
||||
.finally(() => {
|
||||
setConfirmRestart(false);
|
||||
setProcessing(false);
|
||||
});
|
||||
};
|
||||
|
||||
const partition = async () => {
|
||||
setProcessing(true);
|
||||
await partitionCommand()
|
||||
.then(() => {
|
||||
setRestarting(true);
|
||||
})
|
||||
.catch((error: Error) => {
|
||||
toast.error(error.message);
|
||||
})
|
||||
.finally(() => {
|
||||
setConfirmRestart(false);
|
||||
setProcessing(false);
|
||||
});
|
||||
};
|
||||
|
||||
const renderRestartDialog = () => (
|
||||
<Dialog
|
||||
sx={dialogStyle}
|
||||
open={confirmRestart}
|
||||
onClose={() => setConfirmRestart(false)}
|
||||
>
|
||||
<DialogTitle>{LL.RESTART()}</DialogTitle>
|
||||
<DialogContent dividers>{LL.RESTART_CONFIRM()}</DialogContent>
|
||||
<DialogActions>
|
||||
<Button
|
||||
startIcon={<CancelIcon />}
|
||||
variant="outlined"
|
||||
onClick={() => setConfirmRestart(false)}
|
||||
disabled={processing}
|
||||
color="secondary"
|
||||
>
|
||||
{LL.CANCEL()}
|
||||
</Button>
|
||||
<Button
|
||||
startIcon={<PowerSettingsNewIcon />}
|
||||
variant="outlined"
|
||||
onClick={restart}
|
||||
disabled={processing}
|
||||
color="primary"
|
||||
>
|
||||
{LL.RESTART()}
|
||||
</Button>
|
||||
<Button
|
||||
startIcon={<PowerSettingsNewIcon />}
|
||||
variant="outlined"
|
||||
onClick={partition}
|
||||
disabled={processing}
|
||||
color="primary"
|
||||
>
|
||||
EMS-ESP Loader
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
);
|
||||
|
||||
const content = () => {
|
||||
if (!data) {
|
||||
return <FormLoader onRetry={loadData} errorMessage={error?.message} />;
|
||||
@@ -198,13 +282,28 @@ const SystemStatus: FC = () => {
|
||||
</ListItem>
|
||||
<Divider variant="inset" component="li" />
|
||||
|
||||
<ListMenuItem
|
||||
disabled={!me.admin}
|
||||
icon={TimerIcon}
|
||||
bgcolor="#c5572c"
|
||||
label={LL.UPTIME()}
|
||||
text={formatDurationSec(data.uptime)}
|
||||
/>
|
||||
<ListItem>
|
||||
<ListItemAvatar>
|
||||
<Avatar sx={{ bgcolor: '#c5572c', color: 'white' }}>
|
||||
<TimerIcon />
|
||||
</Avatar>
|
||||
</ListItemAvatar>
|
||||
<ListItemText
|
||||
primary={LL.UPTIME()}
|
||||
secondary={formatDurationSec(data.uptime)}
|
||||
/>
|
||||
{me.admin && (
|
||||
<Button
|
||||
startIcon={<PowerSettingsNewIcon />}
|
||||
variant="outlined"
|
||||
color="primary"
|
||||
onClick={() => setConfirmRestart(true)}
|
||||
>
|
||||
{LL.RESTART()}
|
||||
</Button>
|
||||
)}
|
||||
</ListItem>
|
||||
|
||||
<Divider variant="inset" component="li" />
|
||||
|
||||
<ListItem>
|
||||
@@ -252,7 +351,7 @@ const SystemStatus: FC = () => {
|
||||
bgcolor="#68374d"
|
||||
label={LL.SYSTEM_MEMORY()}
|
||||
text={formatNumber(data.free_heap) + ' KB'}
|
||||
to="/settings/espsystemstatus"
|
||||
to="/system/espsystemstatus"
|
||||
/>
|
||||
<Divider variant="inset" component="li" />
|
||||
|
||||
@@ -288,6 +387,7 @@ const SystemStatus: FC = () => {
|
||||
</List>
|
||||
|
||||
{renderScanDialog()}
|
||||
{renderRestartDialog()}
|
||||
|
||||
<Box mt={2} display="flex" flexWrap="wrap">
|
||||
<Button
|
||||
@@ -303,7 +403,9 @@ const SystemStatus: FC = () => {
|
||||
);
|
||||
};
|
||||
|
||||
return <SectionContent>{content()}</SectionContent>;
|
||||
return (
|
||||
<SectionContent>{restarting ? <RestartMonitor /> : content()}</SectionContent>
|
||||
);
|
||||
};
|
||||
|
||||
export default SystemStatus;
|
||||
|
||||
@@ -96,7 +96,7 @@ const de: Translation = {
|
||||
NUM_SECONDS: '{num} Sekunde{{n}}',
|
||||
NUM_HOURS: '{num} Stunde{{n}}',
|
||||
NUM_MINUTES: '{num} Minute{{n}}',
|
||||
APPLICATION_SETTINGS: 'Anwendungseinstellungen',
|
||||
APPLICATION: 'Anwendungseinstellungen',
|
||||
CUSTOMIZATIONS: 'Anpassungen',
|
||||
APPLICATION_RESTARTING: 'EMS-ESP startet neu',
|
||||
INTERFACE_BOARD_PROFILE: 'Interface Platinenprofil',
|
||||
|
||||
@@ -96,7 +96,7 @@ const en: Translation = {
|
||||
NUM_SECONDS: '{num} second{{s}}',
|
||||
NUM_HOURS: '{num} hour{{s}}',
|
||||
NUM_MINUTES: '{num} minute{{s}}',
|
||||
APPLICATION_SETTINGS: 'Application Settings',
|
||||
APPLICATION: 'Application',
|
||||
CUSTOMIZATIONS: 'Customizations',
|
||||
APPLICATION_RESTARTING: 'EMS-ESP is restarting',
|
||||
INTERFACE_BOARD_PROFILE: 'Interface Board Profile',
|
||||
|
||||
@@ -96,7 +96,7 @@ const fr: Translation = {
|
||||
NUM_SECONDS: '{num} seconde{{s}}',
|
||||
NUM_HOURS: '{num} heure{{s}}',
|
||||
NUM_MINUTES: '{num} minute{{s}}',
|
||||
APPLICATION_SETTINGS: "Paramètres de l'application",
|
||||
APPLICATION: "l'application",
|
||||
CUSTOMIZATIONS: 'Personnalisation',
|
||||
APPLICATION_RESTARTING: 'EMS-ESP redémarre',
|
||||
INTERFACE_BOARD_PROFILE: "Profile de carte d'interface",
|
||||
|
||||
@@ -96,7 +96,7 @@ const it: Translation = {
|
||||
NUM_SECONDS: '{num} secondi {{s}}',
|
||||
NUM_HOURS: '{num} ore {{s}}',
|
||||
NUM_MINUTES: '{num} minuti {{s}}',
|
||||
APPLICATION_SETTINGS: 'Impostazione Applicazione',
|
||||
APPLICATION: 'Applicazione',
|
||||
CUSTOMIZATIONS: 'Personalizzazione',
|
||||
APPLICATION_RESTARTING: 'EMS-ESP sta riavviando',
|
||||
INTERFACE_BOARD_PROFILE: 'Profilo scheda di interfaccia',
|
||||
|
||||
@@ -96,7 +96,7 @@ const nl: Translation = {
|
||||
NUM_SECONDS: '{num} second{{en}}',
|
||||
NUM_HOURS: '{num} {{uur|uren}}',
|
||||
NUM_MINUTES: '{num} {{minuut|minuten}}',
|
||||
APPLICATION_SETTINGS: 'Applicatieinstellingen',
|
||||
APPLICATION: 'Applicatie',
|
||||
CUSTOMIZATIONS: 'Aanpassingen van entiteiten',
|
||||
APPLICATION_RESTARTING: 'EMS-ESP herstarten',
|
||||
INTERFACE_BOARD_PROFILE: 'Interface Apparaatprofiel',
|
||||
|
||||
@@ -96,7 +96,7 @@ const no: Translation = {
|
||||
NUM_SECONDS: '{num} Sekund{{er}}',
|
||||
NUM_HOURS: '{num} Time{{r}}',
|
||||
NUM_MINUTES: '{num} Minutt{{er}}',
|
||||
APPLICATION_SETTINGS: 'Innstillinger',
|
||||
APPLICATION: 'Søknad',
|
||||
CUSTOMIZATIONS: 'Tilpasninger',
|
||||
APPLICATION_RESTARTING: 'EMS-ESP restarter',
|
||||
INTERFACE_BOARD_PROFILE: 'Interface Prosessor Profil',
|
||||
|
||||
@@ -96,7 +96,7 @@ const pl: BaseTranslation = {
|
||||
NUM_SECONDS: '{num} sekun{{d|da|dy|dy|d}}',
|
||||
NUM_HOURS: '{num} godzi{{n|na|ny|ny|n}}',
|
||||
NUM_MINUTES: '{num} minu{{t|ta|ty|ty|t}}',
|
||||
APPLICATION_SETTINGS: 'Ustawienia aplikacji',
|
||||
APPLICATION: 'Aplikacji',
|
||||
CUSTOMIZATIONS: 'Personalizacja',
|
||||
APPLICATION_RESTARTING: 'Trwa ponowne uruchamianie',
|
||||
INTERFACE_BOARD_PROFILE: 'Profil płytki interfejsu',
|
||||
|
||||
@@ -96,7 +96,7 @@ const sk: Translation = {
|
||||
NUM_SECONDS: '{num} sek{{únd|unda|undy|undy|únd|únd}}',
|
||||
NUM_HOURS: '{num} hod{{ín|ina|iny|iny|ín|ín}}',
|
||||
NUM_MINUTES: '{num} minú{{t|ta|ty|ty|t|t}}',
|
||||
APPLICATION_SETTINGS: 'Nastavenia aplikácie',
|
||||
APPLICATION: 'Aplikácie',
|
||||
CUSTOMIZATIONS: 'Prispôsobenia',
|
||||
APPLICATION_RESTARTING: 'EMS-ESP sa reštartuje',
|
||||
INTERFACE_BOARD_PROFILE: 'Profil dosky rozhrania',
|
||||
|
||||
@@ -96,7 +96,7 @@ const sv: Translation = {
|
||||
NUM_SECONDS: '{num} sekund{{er}}',
|
||||
NUM_HOURS: '{num} timmar',
|
||||
NUM_MINUTES: '{num} minut{{er}}',
|
||||
APPLICATION_SETTINGS: 'Inställningar',
|
||||
APPLICATION: 'Apliká',
|
||||
CUSTOMIZATIONS: 'Anpassningr',
|
||||
APPLICATION_RESTARTING: 'EMS-ESP startar om',
|
||||
INTERFACE_BOARD_PROFILE: 'Interface Hårdvaruprofil',
|
||||
|
||||
@@ -96,7 +96,7 @@ const tr: Translation = {
|
||||
NUM_SECONDS: '{num} saniye{{ler}}',
|
||||
NUM_HOURS: '{num} saat{{ler}}',
|
||||
NUM_MINUTES: '{num} dakika{{lar}}',
|
||||
APPLICATION_SETTINGS: 'Uygulama Ayarları',
|
||||
APPLICATION: 'Uygulama',
|
||||
CUSTOMIZATIONS: 'Özelleştirme',
|
||||
APPLICATION_RESTARTING: 'EMS-ESP yeniden başlatılıyor',
|
||||
INTERFACE_BOARD_PROFILE: 'Arabirim Kart Profili',
|
||||
|
||||
@@ -115,7 +115,7 @@ const ApplicationSettings: FC = () => {
|
||||
});
|
||||
};
|
||||
|
||||
useLayoutTitle(LL.APPLICATION_SETTINGS());
|
||||
useLayoutTitle(LL.APPLICATION());
|
||||
|
||||
const content = () => {
|
||||
if (!data) {
|
||||
|
||||
Reference in New Issue
Block a user