This commit is contained in:
MichaelDvP
2024-05-06 16:51:27 +02:00
18 changed files with 313 additions and 166 deletions

View File

@@ -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 />} />
</>
)}

View File

@@ -15,8 +15,7 @@ export const dialogStyle = {
borderColor: '#565656',
borderStyle: 'solid',
borderWidth: '1px'
},
backdropFilter: 'blur(1px)'
}
};
const theme = responsiveFontSizes(

View File

@@ -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;

View File

@@ -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;

View File

@@ -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',

View File

@@ -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',

View File

@@ -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",

View File

@@ -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',

View File

@@ -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',

View File

@@ -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',

View File

@@ -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',

View File

@@ -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',

View File

@@ -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',

View File

@@ -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',

View File

@@ -115,7 +115,7 @@ const ApplicationSettings: FC = () => {
});
};
useLayoutTitle(LL.APPLICATION_SETTINGS());
useLayoutTitle(LL.APPLICATION());
const content = () => {
if (!data) {