From 24ea97557581bae228be7f82b34d47d89b502d50 Mon Sep 17 00:00:00 2001 From: proddy Date: Wed, 20 Mar 2024 23:57:19 +0100 Subject: [PATCH] added status and renamed components --- interface/package.json | 8 +- interface/src/AuthenticatedRouting.tsx | 12 +- interface/src/api/mqtt.ts | 9 +- .../src/components/layout/LayoutMenu.tsx | 80 ++++- .../src/components/layout/LayoutMenuItem.tsx | 16 +- .../src/components/layout/ListMenuItem.tsx | 52 ++++ interface/src/framework/Settings.tsx | 226 ++++---------- .../ap/{APSettingsForm.tsx => APSettings.tsx} | 10 +- .../ap/{APStatusForm.tsx => APStatus.tsx} | 10 +- interface/src/framework/ap/AccessPoint.tsx | 8 +- interface/src/framework/mqtt/Mqtt.tsx | 8 +- ...{MqttSettingsForm.tsx => MqttSettings.tsx} | 8 +- .../{MqttStatusForm.tsx => MqttStatus.tsx} | 16 +- .../{NetworkConnection.tsx => Network.tsx} | 14 +- ...rkSettingsForm.tsx => NetworkSettings.tsx} | 10 +- ...etworkStatusForm.tsx => NetworkStatus.tsx} | 23 +- .../{NTPSettingsForm.tsx => NTPSettings.tsx} | 8 +- .../ntp/{NTPStatusForm.tsx => NTPStatus.tsx} | 40 +-- interface/src/framework/ntp/NetworkTime.tsx | 8 +- .../{OTASettingsForm.tsx => OTASettings.tsx} | 8 +- .../{ManageUsersForm.tsx => ManageUsers.tsx} | 18 +- interface/src/framework/security/Security.tsx | 8 +- ...ySettingsForm.tsx => SecuritySettings.tsx} | 8 +- .../security/{UserForm.tsx => User.tsx} | 10 +- .../src/framework/system/ESPSystemStatus.tsx | 1 + .../system/{Status.tsx => System.tsx} | 12 +- interface/src/framework/system/SystemLog.tsx | 4 +- .../src/framework/system/SystemStatus.tsx | 122 ++++++-- interface/src/i18n/de/index.ts | 4 +- interface/src/i18n/en/index.ts | 3 +- interface/src/i18n/fr/index.ts | 3 +- interface/src/i18n/it/index.ts | 3 +- interface/src/i18n/nl/index.ts | 25 +- interface/src/i18n/no/index.ts | 3 +- interface/src/i18n/pl/index.ts | 5 +- interface/src/i18n/sk/index.ts | 5 +- interface/src/i18n/sv/index.ts | 3 +- interface/src/i18n/tr/index.ts | 3 +- interface/src/project/ApplicationSettings.tsx | 2 +- interface/src/project/Sensors.tsx | 2 +- .../{Activity.tsx => SystemActivity.tsx} | 8 +- interface/src/types/ap.ts | 4 +- interface/src/types/mqtt.ts | 4 +- interface/src/types/network.ts | 4 +- interface/src/types/ntp.ts | 4 +- interface/src/types/security.ts | 6 +- interface/src/types/system.ts | 7 +- interface/src/validators/ap.ts | 6 +- interface/src/validators/mqtt.ts | 4 +- interface/src/validators/network.ts | 4 +- interface/src/validators/security.ts | 6 +- interface/yarn.lock | 282 ++++++++++-------- mock-api/handler.ts | 12 +- 53 files changed, 633 insertions(+), 536 deletions(-) create mode 100644 interface/src/components/layout/ListMenuItem.tsx rename interface/src/framework/ap/{APSettingsForm.tsx => APSettings.tsx} (96%) rename interface/src/framework/ap/{APStatusForm.tsx => APStatus.tsx} (93%) rename interface/src/framework/mqtt/{MqttSettingsForm.tsx => MqttSettings.tsx} (99%) rename interface/src/framework/mqtt/{MqttStatusForm.tsx => MqttStatus.tsx} (92%) rename interface/src/framework/network/{NetworkConnection.tsx => Network.tsx} (86%) rename interface/src/framework/network/{NetworkSettingsForm.tsx => NetworkSettings.tsx} (98%) rename interface/src/framework/network/{NetworkStatusForm.tsx => NetworkStatus.tsx} (90%) rename interface/src/framework/ntp/{NTPSettingsForm.tsx => NTPSettings.tsx} (96%) rename interface/src/framework/ntp/{NTPStatusForm.tsx => NTPStatus.tsx} (89%) rename interface/src/framework/ota/{OTASettingsForm.tsx => OTASettings.tsx} (95%) rename interface/src/framework/security/{ManageUsersForm.tsx => ManageUsers.tsx} (95%) rename interface/src/framework/security/{SecuritySettingsForm.tsx => SecuritySettings.tsx} (94%) rename interface/src/framework/security/{UserForm.tsx => User.tsx} (92%) rename interface/src/framework/system/{Status.tsx => System.tsx} (76%) rename interface/src/project/{Activity.tsx => SystemActivity.tsx} (95%) diff --git a/interface/package.json b/interface/package.json index 9e9c0c46c..22c5ed7e7 100644 --- a/interface/package.json +++ b/interface/package.json @@ -23,7 +23,7 @@ }, "dependencies": { "@alova/adapter-xhr": "^1.0.3", - "@babel/core": "^7.24.1", + "@babel/core": "^7.24.3", "@emotion/react": "^11.11.4", "@emotion/styled": "^11.11.0", "@mui/icons-material": "^5.15.14", @@ -35,7 +35,7 @@ "@types/react": "^18.2.67", "@types/react-dom": "^18.2.22", "@types/react-router-dom": "^5.3.3", - "alova": "^2.17.1", + "alova": "^2.18.0", "async-validator": "^4.2.5", "history": "^5.3.0", "jwt-decode": "^4.0.0", @@ -66,11 +66,11 @@ "eslint-plugin-prettier": "alpha", "eslint-plugin-react": "^7.34.1", "eslint-plugin-react-hooks": "^4.6.0", - "preact": "^10.19.7", + "preact": "^10.20.0", "prettier": "^3.2.5", "rollup-plugin-visualizer": "^5.12.0", "terser": "^5.29.2", - "vite": "^5.1.6", + "vite": "^5.2.2", "vite-plugin-imagemin": "^0.6.1", "vite-tsconfig-paths": "^4.3.2" }, diff --git a/interface/src/AuthenticatedRouting.tsx b/interface/src/AuthenticatedRouting.tsx index 7ba75209f..29cf65449 100644 --- a/interface/src/AuthenticatedRouting.tsx +++ b/interface/src/AuthenticatedRouting.tsx @@ -6,12 +6,12 @@ import { AuthenticatedContext } from 'contexts/authentication'; import Settings from 'framework/Settings'; import AccessPoint from 'framework/ap/AccessPoint'; import Mqtt from 'framework/mqtt/Mqtt'; -import NetworkConnection from 'framework/network/NetworkConnection'; +import Network from 'framework/network/Network'; import NetworkTime from 'framework/ntp/NetworkTime'; -import OTASettingsForm from 'framework/ota/OTASettingsForm'; +import OTASettings from 'framework/ota/OTASettings'; import Security from 'framework/security/Security'; import ESPSystemStatus from 'framework/system/ESPSystemStatus'; -import Status from 'framework/system/Status'; +import System from 'framework/system/System'; import UploadDownload from 'framework/system/UploadDownload'; import ApplicationSettings from 'project/ApplicationSettings'; import CustomEntities from 'project/CustomEntities'; @@ -27,7 +27,7 @@ const AuthenticatedRouting: FC = () => { } /> } /> - } /> + } /> } /> } /> {me.admin && ( @@ -36,12 +36,12 @@ const AuthenticatedRouting: FC = () => { } /> } /> } /> - } /> + } /> } /> } /> } /> } /> - } /> + } /> } /> } /> } /> diff --git a/interface/src/api/mqtt.ts b/interface/src/api/mqtt.ts index d75dc4134..9605d843d 100644 --- a/interface/src/api/mqtt.ts +++ b/interface/src/api/mqtt.ts @@ -1,6 +1,7 @@ import { alovaInstance } from './endpoints'; -import type { MqttSettings, MqttStatus } from 'types'; +import type { MqttSettingsType, MqttStatusType } from 'types'; -export const readMqttStatus = () => alovaInstance.Get('/rest/mqttStatus'); -export const readMqttSettings = () => alovaInstance.Get('/rest/mqttSettings'); -export const updateMqttSettings = (data: MqttSettings) => alovaInstance.Post('/rest/mqttSettings', data); +export const readMqttStatus = () => alovaInstance.Get('/rest/mqttStatus'); +export const readMqttSettings = () => alovaInstance.Get('/rest/mqttSettings'); +export const updateMqttSettings = (data: MqttSettingsType) => + alovaInstance.Post('/rest/mqttSettings', data); diff --git a/interface/src/components/layout/LayoutMenu.tsx b/interface/src/components/layout/LayoutMenu.tsx index ec1ca6e92..026a3497a 100644 --- a/interface/src/components/layout/LayoutMenu.tsx +++ b/interface/src/components/layout/LayoutMenu.tsx @@ -2,12 +2,14 @@ import AccountCircleIcon from '@mui/icons-material/AccountCircle'; import AssessmentIcon from '@mui/icons-material/Assessment'; import CategoryIcon from '@mui/icons-material/Category'; import ConstructionIcon from '@mui/icons-material/Construction'; +import KeyboardArrowDown from '@mui/icons-material/KeyboardArrowDown'; import LiveHelpIcon from '@mui/icons-material/LiveHelp'; import MoreTimeIcon from '@mui/icons-material/MoreTime'; import PersonIcon from '@mui/icons-material/Person'; import PlaylistAddIcon from '@mui/icons-material/PlaylistAdd'; import SensorsIcon from '@mui/icons-material/Sensors'; import SettingsIcon from '@mui/icons-material/Settings'; + import { Divider, List, @@ -52,6 +54,8 @@ const LayoutMenu: FC = () => { const open = Boolean(anchorEl); const id = anchorEl ? 'app-menu-popover' : undefined; + const [menuOpen, setMenuOpen] = useState(true); + const onLocaleSelected: ChangeEventHandler = async ({ target }) => { const loc = target.value as Locales; localStorage.setItem('lang', loc); @@ -73,22 +77,70 @@ const LayoutMenu: FC = () => { - - - + + + setMenuOpen(!menuOpen)} + sx={{ + pt: 2.5, + pb: menuOpen ? 0 : 2.5, + '&:hover, &:focus': { '& svg': { opacity: 1 } } + }} + > + + + + {menuOpen && ( + <> + + + + + )} + + - + diff --git a/interface/src/components/layout/LayoutMenuItem.tsx b/interface/src/components/layout/LayoutMenuItem.tsx index d9bb46ca2..02899d406 100644 --- a/interface/src/components/layout/LayoutMenuItem.tsx +++ b/interface/src/components/layout/LayoutMenuItem.tsx @@ -1,4 +1,4 @@ -import { ListItem, ListItemButton, ListItemIcon, ListItemText } from '@mui/material'; +import { ListItemButton, ListItemIcon, ListItemText } from '@mui/material'; import { Link, useLocation } from 'react-router-dom'; import type { SvgIconProps } from '@mui/material'; import type { FC } from 'react'; @@ -18,14 +18,12 @@ const LayoutMenuItem: FC = ({ icon: Icon, label, to, disabl const selected = routeMatches(to, pathname); return ( - - - - - - {label} - - + + + + + {label} + ); }; diff --git a/interface/src/components/layout/ListMenuItem.tsx b/interface/src/components/layout/ListMenuItem.tsx new file mode 100644 index 000000000..b324c69a5 --- /dev/null +++ b/interface/src/components/layout/ListMenuItem.tsx @@ -0,0 +1,52 @@ +import NavigateNextIcon from '@mui/icons-material/NavigateNext'; +import { Avatar, ListItem, ListItemAvatar, ListItemButton, ListItemIcon, ListItemText } from '@mui/material'; +import { Fragment, type FC } from 'react'; +import { Link } from 'react-router-dom'; +import type { SvgIconProps } from '@mui/material'; + +interface ListMenuItemProps { + icon: React.ComponentType; + bgcolor?: string; + label: string; + text: string; + to: string; + disabled?: boolean; +} + +function RenderIcon({ icon: Icon, bgcolor, label, text }: ListMenuItemProps) { + return ( + <> + + + + + + + + ); +} + +const LayoutMenuItem: FC = ({ icon, bgcolor, label, text, to, disabled }) => ( + + {disabled ? ( + + + + ) : ( + + + + } + > + + + + + )} + +); + +export default LayoutMenuItem; diff --git a/interface/src/framework/Settings.tsx b/interface/src/framework/Settings.tsx index ce84066a1..21cd4a777 100644 --- a/interface/src/framework/Settings.tsx +++ b/interface/src/framework/Settings.tsx @@ -5,37 +5,20 @@ 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 NavigateNextIcon from '@mui/icons-material/NavigateNext'; 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'; import TuneIcon from '@mui/icons-material/Tune'; -import { - List, - ListItem, - ListItemAvatar, - ListItemText, - Avatar, - ListItemButton, - ListItemIcon, - Button, - Dialog, - DialogActions, - DialogContent, - DialogTitle, - Box, - Divider -} from '@mui/material'; +import { List, Button, Dialog, DialogActions, DialogContent, DialogTitle, Box } from '@mui/material'; import { useRequest } from 'alova'; import { useState, type FC } from 'react'; -import { Link } from 'react-router-dom'; import { toast } from 'react-toastify'; import RestartMonitor from './system/RestartMonitor'; import { dialogStyle } from 'CustomTheme'; import * as SystemApi from 'api/system'; import { ButtonRow, SectionContent, useLayoutTitle } from 'components'; +import ListMenuItem from 'components/layout/ListMenuItem'; import { useI18nContext } from 'i18n/i18n-react'; const Settings: FC = () => { @@ -134,7 +117,7 @@ const Settings: FC = () => { disabled={processing} color="primary" > - EMS-ESP-Loader + EMS-ESP Loader @@ -170,169 +153,62 @@ const Settings: FC = () => { const content = () => ( <> - - - - } - > - - - - - - - - - + {/* TODO: translate */} + - - - - } - > - - - - - - - - - + - - - - } - > - - - - - - - - - + - - - - } - > - - - - - - - - - + - - - - } - > - - - - - - - - - + - - - - } - > - - - - - - - - - + - - - - } - > - - - - - - - - - + {/* TODO: translate */} + - + - - - - } - > - - - - - - - - - - - - - - } - > - - - - - - - - - + {/* TODO: translate */} + {renderRestartDialog()} diff --git a/interface/src/framework/ap/APSettingsForm.tsx b/interface/src/framework/ap/APSettings.tsx similarity index 96% rename from interface/src/framework/ap/APSettingsForm.tsx rename to interface/src/framework/ap/APSettings.tsx index 95acbc36f..67d56c30e 100644 --- a/interface/src/framework/ap/APSettingsForm.tsx +++ b/interface/src/framework/ap/APSettings.tsx @@ -6,7 +6,7 @@ import { useState } from 'react'; import type { ValidateFieldsError } from 'async-validator'; import type { FC } from 'react'; -import type { APSettings } from 'types'; +import type { APSettingsType } from 'types'; import * as APApi from 'api/ap'; import { BlockFormControlLabel, @@ -24,10 +24,10 @@ import { numberValue, updateValueDirty, useRest } from 'utils'; import { createAPSettingsValidator, validate } from 'validators'; -export const isAPEnabled = ({ provision_mode }: APSettings) => +export const isAPEnabled = ({ provision_mode }: APSettingsType) => provision_mode === APProvisionMode.AP_MODE_ALWAYS || provision_mode === APProvisionMode.AP_MODE_DISCONNECTED; -const APSettingsForm: FC = () => { +const APSettings: FC = () => { const { loadData, saving, @@ -39,7 +39,7 @@ const APSettingsForm: FC = () => { blocker, saveData, errorMessage - } = useRest({ + } = useRest({ read: APApi.readAPSettings, update: APApi.updateAPSettings }); @@ -212,4 +212,4 @@ const APSettingsForm: FC = () => { ); }; -export default APSettingsForm; +export default APSettings; diff --git a/interface/src/framework/ap/APStatusForm.tsx b/interface/src/framework/ap/APStatus.tsx similarity index 93% rename from interface/src/framework/ap/APStatusForm.tsx rename to interface/src/framework/ap/APStatus.tsx index af66de784..4eba54f17 100644 --- a/interface/src/framework/ap/APStatusForm.tsx +++ b/interface/src/framework/ap/APStatus.tsx @@ -7,14 +7,14 @@ import { useRequest } from 'alova'; import type { Theme } from '@mui/material'; import type { FC } from 'react'; -import type { APStatus } from 'types'; +import type { APStatusType } from 'types'; import * as APApi from 'api/ap'; import { ButtonRow, FormLoader, SectionContent } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; import { APNetworkStatus } from 'types'; -export const apStatusHighlight = ({ status }: APStatus, theme: Theme) => { +export const apStatusHighlight = ({ status }: APStatusType, theme: Theme) => { switch (status) { case APNetworkStatus.ACTIVE: return theme.palette.success.main; @@ -27,14 +27,14 @@ export const apStatusHighlight = ({ status }: APStatus, theme: Theme) => { } }; -const APStatusForm: FC = () => { +const APStatus: FC = () => { const { data: data, send: loadData, error } = useRequest(APApi.readAPStatus); const { LL } = useI18nContext(); const theme = useTheme(); - const apStatus = ({ status }: APStatus) => { + const apStatus = ({ status }: APStatusType) => { switch (status) { case APNetworkStatus.ACTIVE: return LL.ACTIVE(); @@ -102,4 +102,4 @@ const APStatusForm: FC = () => { return {content()}; }; -export default APStatusForm; +export default APStatus; diff --git a/interface/src/framework/ap/AccessPoint.tsx b/interface/src/framework/ap/AccessPoint.tsx index e8b14bbf2..f344580fd 100644 --- a/interface/src/framework/ap/AccessPoint.tsx +++ b/interface/src/framework/ap/AccessPoint.tsx @@ -1,8 +1,8 @@ import { Tab } from '@mui/material'; import { Navigate, Routes, Route } from 'react-router-dom'; -import APSettingsForm from './APSettingsForm'; -import APStatusForm from './APStatusForm'; +import APSettings from './APSettings'; +import APStatus from './APStatus'; import type { FC } from 'react'; import { RequireAdmin, RouterTabs, useLayoutTitle, useRouterTab } from 'components'; @@ -22,12 +22,12 @@ const AccessPoint: FC = () => { - } /> + } /> - + } /> diff --git a/interface/src/framework/mqtt/Mqtt.tsx b/interface/src/framework/mqtt/Mqtt.tsx index 0ef430924..aa89fea32 100644 --- a/interface/src/framework/mqtt/Mqtt.tsx +++ b/interface/src/framework/mqtt/Mqtt.tsx @@ -1,7 +1,7 @@ import { Tab } from '@mui/material'; import { Navigate, Route, Routes } from 'react-router-dom'; -import MqttSettingsForm from './MqttSettingsForm'; -import MqttStatusForm from './MqttStatusForm'; +import MqttSettings from './MqttSettings'; +import MqttStatus from './MqttStatus'; import type { FC } from 'react'; import { RequireAdmin, RouterTabs, useLayoutTitle, useRouterTab } from 'components'; @@ -22,12 +22,12 @@ const Mqtt: FC = () => { - } /> + } /> - + } /> diff --git a/interface/src/framework/mqtt/MqttSettingsForm.tsx b/interface/src/framework/mqtt/MqttSettings.tsx similarity index 99% rename from interface/src/framework/mqtt/MqttSettingsForm.tsx rename to interface/src/framework/mqtt/MqttSettings.tsx index 2a5b774ad..53b30822a 100644 --- a/interface/src/framework/mqtt/MqttSettingsForm.tsx +++ b/interface/src/framework/mqtt/MqttSettings.tsx @@ -5,7 +5,7 @@ import { useState } from 'react'; import type { ValidateFieldsError } from 'async-validator'; import type { FC } from 'react'; -import type { MqttSettings } from 'types'; +import type { MqttSettingsType } from 'types'; import * as MqttApi from 'api/mqtt'; import { BlockFormControlLabel, @@ -21,7 +21,7 @@ import { numberValue, updateValueDirty, useRest } from 'utils'; import { createMqttSettingsValidator, validate } from 'validators'; -const MqttSettingsForm: FC = () => { +const MqttSettings: FC = () => { const { loadData, saving, @@ -33,7 +33,7 @@ const MqttSettingsForm: FC = () => { blocker, saveData, errorMessage - } = useRest({ + } = useRest({ read: MqttApi.readMqttSettings, update: MqttApi.updateMqttSettings }); @@ -456,4 +456,4 @@ const MqttSettingsForm: FC = () => { ); }; -export default MqttSettingsForm; +export default MqttSettings; diff --git a/interface/src/framework/mqtt/MqttStatusForm.tsx b/interface/src/framework/mqtt/MqttStatus.tsx similarity index 92% rename from interface/src/framework/mqtt/MqttStatusForm.tsx rename to interface/src/framework/mqtt/MqttStatus.tsx index 25cf86ef0..26a300b88 100644 --- a/interface/src/framework/mqtt/MqttStatusForm.tsx +++ b/interface/src/framework/mqtt/MqttStatus.tsx @@ -8,13 +8,13 @@ import { useRequest } from 'alova'; import type { Theme } from '@mui/material'; import type { FC } from 'react'; -import type { MqttStatus } from 'types'; +import type { MqttStatusType } from 'types'; import * as MqttApi from 'api/mqtt'; import { ButtonRow, FormLoader, SectionContent } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; import { MqttDisconnectReason } from 'types'; -export const mqttStatusHighlight = ({ enabled, connected }: MqttStatus, theme: Theme) => { +export const mqttStatusHighlight = ({ enabled, connected }: MqttStatusType, theme: Theme) => { if (!enabled) { return theme.palette.info.main; } @@ -24,27 +24,27 @@ export const mqttStatusHighlight = ({ enabled, connected }: MqttStatus, theme: T return theme.palette.error.main; }; -export const mqttPublishHighlight = ({ mqtt_fails }: MqttStatus, theme: Theme) => { +export const mqttPublishHighlight = ({ mqtt_fails }: MqttStatusType, theme: Theme) => { if (mqtt_fails === 0) return theme.palette.success.main; if (mqtt_fails < 10) return theme.palette.warning.main; return theme.palette.error.main; }; -export const mqttQueueHighlight = ({ mqtt_queued }: MqttStatus, theme: Theme) => { +export const mqttQueueHighlight = ({ mqtt_queued }: MqttStatusType, theme: Theme) => { if (mqtt_queued <= 1) return theme.palette.success.main; return theme.palette.warning.main; }; -const MqttStatusForm: FC = () => { +const MqttStatus: FC = () => { const { data: data, send: loadData, error } = useRequest(MqttApi.readMqttStatus); const { LL } = useI18nContext(); const theme = useTheme(); - const mqttStatus = ({ enabled, connected, connect_count }: MqttStatus) => { + const mqttStatus = ({ enabled, connected, connect_count }: MqttStatusType) => { if (!enabled) { return LL.NOT_ENABLED(); } @@ -54,7 +54,7 @@ const MqttStatusForm: FC = () => { return LL.DISCONNECTED() + (connect_count > 1 ? ' (' + connect_count + ')' : ''); }; - const disconnectReason = ({ disconnect_reason }: MqttStatus) => { + const disconnectReason = ({ disconnect_reason }: MqttStatusType) => { switch (disconnect_reason) { case MqttDisconnectReason.TCP_DISCONNECTED: return 'TCP disconnected'; @@ -149,4 +149,4 @@ const MqttStatusForm: FC = () => { return {content()}; }; -export default MqttStatusForm; +export default MqttStatus; diff --git a/interface/src/framework/network/NetworkConnection.tsx b/interface/src/framework/network/Network.tsx similarity index 86% rename from interface/src/framework/network/NetworkConnection.tsx rename to interface/src/framework/network/Network.tsx index 2e093ac3b..7dd90a2d7 100644 --- a/interface/src/framework/network/NetworkConnection.tsx +++ b/interface/src/framework/network/Network.tsx @@ -1,8 +1,8 @@ import { Tab } from '@mui/material'; import { useCallback, useState } from 'react'; import { Navigate, Routes, Route, useNavigate } from 'react-router-dom'; -import NetworkSettingsForm from './NetworkSettingsForm'; -import NetworkStatusForm from './NetworkStatusForm'; +import NetworkSettings from './NetworkSettings'; +import NetworkStatus from './NetworkStatus'; import { WiFiConnectionContext } from './WiFiConnectionContext'; import WiFiNetworkScanner from './WiFiNetworkScanner'; import type { FC } from 'react'; @@ -11,7 +11,7 @@ import type { WiFiNetwork } from 'types'; import { RequireAdmin, RouterTabs, useLayoutTitle, useRouterTab } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; -const NetworkConnection: FC = () => { +const Network: FC = () => { const { LL } = useI18nContext(); useLayoutTitle(LL.NETWORK(0)); @@ -43,11 +43,11 @@ const NetworkConnection: FC = () => { > - + - } /> + } /> { path="settings" element={ - + } /> @@ -70,4 +70,4 @@ const NetworkConnection: FC = () => { ); }; -export default NetworkConnection; +export default Network; diff --git a/interface/src/framework/network/NetworkSettingsForm.tsx b/interface/src/framework/network/NetworkSettings.tsx similarity index 98% rename from interface/src/framework/network/NetworkSettingsForm.tsx rename to interface/src/framework/network/NetworkSettings.tsx index 39786f087..83f1addaa 100644 --- a/interface/src/framework/network/NetworkSettingsForm.tsx +++ b/interface/src/framework/network/NetworkSettings.tsx @@ -28,7 +28,7 @@ import { isNetworkOpen, networkSecurityMode } from './WiFiNetworkSelector'; import type { ValidateFieldsError } from 'async-validator'; import type { FC } from 'react'; -import type { NetworkSettings } from 'types'; +import type { NetworkSettingsType } from 'types'; import * as NetworkApi from 'api/network'; import * as SystemApi from 'api/system'; import { @@ -48,7 +48,7 @@ import { updateValueDirty, useRest } from 'utils'; import { validate } from 'validators'; import { createNetworkSettingsValidator } from 'validators/network'; -const WiFiSettingsForm: FC = () => { +const NetworkSettings: FC = () => { const { LL } = useI18nContext(); const { selectedNetwork, deselectNetwork } = useContext(WiFiConnectionContext); @@ -68,7 +68,7 @@ const WiFiSettingsForm: FC = () => { saveData, errorMessage, restartNeeded - } = useRest({ + } = useRest({ read: NetworkApi.readNetworkSettings, update: NetworkApi.updateNetworkSettings }); @@ -135,7 +135,7 @@ const WiFiSettingsForm: FC = () => { return ( <> - + WiFi {selectedNetwork ? ( @@ -367,4 +367,4 @@ const WiFiSettingsForm: FC = () => { ); }; -export default WiFiSettingsForm; +export default NetworkSettings; diff --git a/interface/src/framework/network/NetworkStatusForm.tsx b/interface/src/framework/network/NetworkStatus.tsx similarity index 90% rename from interface/src/framework/network/NetworkStatusForm.tsx rename to interface/src/framework/network/NetworkStatus.tsx index a84f97df8..55dfe1fb9 100644 --- a/interface/src/framework/network/NetworkStatusForm.tsx +++ b/interface/src/framework/network/NetworkStatus.tsx @@ -11,18 +11,18 @@ import { useRequest } from 'alova'; import type { Theme } from '@mui/material'; import type { FC } from 'react'; -import type { NetworkStatus } from 'types'; +import type { NetworkStatusType } from 'types'; import * as NetworkApi from 'api/network'; import { ButtonRow, FormLoader, SectionContent } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; import { NetworkConnectionStatus } from 'types'; -const isConnected = ({ status }: NetworkStatus) => +const isConnected = ({ status }: NetworkStatusType) => status === NetworkConnectionStatus.WIFI_STATUS_CONNECTED || status === NetworkConnectionStatus.ETHERNET_STATUS_CONNECTED; -const networkStatusHighlight = ({ status }: NetworkStatus, theme: Theme) => { +const networkStatusHighlight = ({ status }: NetworkStatusType, theme: Theme) => { switch (status) { case NetworkConnectionStatus.WIFI_STATUS_IDLE: case NetworkConnectionStatus.WIFI_STATUS_DISCONNECTED: @@ -39,7 +39,7 @@ const networkStatusHighlight = ({ status }: NetworkStatus, theme: Theme) => { } }; -const networkQualityHighlight = ({ rssi }: NetworkStatus, theme: Theme) => { +const networkQualityHighlight = ({ rssi }: NetworkStatusType, theme: Theme) => { if (rssi <= -85) { return theme.palette.error.main; } else if (rssi <= -75) { @@ -48,17 +48,18 @@ const networkQualityHighlight = ({ rssi }: NetworkStatus, theme: Theme) => { return theme.palette.success.main; }; -export const isWiFi = ({ status }: NetworkStatus) => status === NetworkConnectionStatus.WIFI_STATUS_CONNECTED; -export const isEthernet = ({ status }: NetworkStatus) => status === NetworkConnectionStatus.ETHERNET_STATUS_CONNECTED; +export const isWiFi = ({ status }: NetworkStatusType) => status === NetworkConnectionStatus.WIFI_STATUS_CONNECTED; +export const isEthernet = ({ status }: NetworkStatusType) => + status === NetworkConnectionStatus.ETHERNET_STATUS_CONNECTED; -const dnsServers = ({ dns_ip_1, dns_ip_2 }: NetworkStatus) => { +const dnsServers = ({ dns_ip_1, dns_ip_2 }: NetworkStatusType) => { if (!dns_ip_1) { return 'none'; } return dns_ip_1 + (!dns_ip_2 || dns_ip_2 === '0.0.0.0' ? '' : ',' + dns_ip_2); }; -const IPs = (status: NetworkStatus) => { +const IPs = (status: NetworkStatusType) => { if (!status.local_ipv6 || status.local_ipv6 === '0000:0000:0000:0000:0000:0000:0000:0000') { return status.local_ip; } @@ -68,14 +69,14 @@ const IPs = (status: NetworkStatus) => { return status.local_ip + ', ' + status.local_ipv6; }; -const NetworkStatusForm: FC = () => { +const NetworkStatus: FC = () => { const { data: data, send: loadData, error } = useRequest(NetworkApi.readNetworkStatus); const { LL } = useI18nContext(); const theme = useTheme(); - const networkStatus = ({ status }: NetworkStatus) => { + const networkStatus = ({ status }: NetworkStatusType) => { switch (status) { case NetworkConnectionStatus.WIFI_STATUS_NO_SHIELD: return LL.INACTIVE(1); @@ -196,4 +197,4 @@ const NetworkStatusForm: FC = () => { return {content()}; }; -export default NetworkStatusForm; +export default NetworkStatus; diff --git a/interface/src/framework/ntp/NTPSettingsForm.tsx b/interface/src/framework/ntp/NTPSettings.tsx similarity index 96% rename from interface/src/framework/ntp/NTPSettingsForm.tsx rename to interface/src/framework/ntp/NTPSettings.tsx index 1eb855462..27df6a361 100644 --- a/interface/src/framework/ntp/NTPSettingsForm.tsx +++ b/interface/src/framework/ntp/NTPSettings.tsx @@ -8,7 +8,7 @@ import { selectedTimeZone, timeZoneSelectItems, TIME_ZONES } from './TZ'; import type { ValidateFieldsError } from 'async-validator'; import type { FC } from 'react'; -import type { NTPSettings } from 'types'; +import type { NTPSettingsType } from 'types'; import * as NTPApi from 'api/ntp'; import { BlockFormControlLabel, @@ -23,7 +23,7 @@ import { updateValueDirty, useRest } from 'utils'; import { validate } from 'validators'; import { NTP_SETTINGS_VALIDATOR } from 'validators/ntp'; -const NTPSettingsForm: FC = () => { +const NTPSettings: FC = () => { const { loadData, saving, @@ -35,7 +35,7 @@ const NTPSettingsForm: FC = () => { blocker, saveData, errorMessage - } = useRest({ + } = useRest({ read: NTPApi.readNTPSettings, update: NTPApi.updateNTPSettings }); @@ -137,4 +137,4 @@ const NTPSettingsForm: FC = () => { ); }; -export default NTPSettingsForm; +export default NTPSettings; diff --git a/interface/src/framework/ntp/NTPStatusForm.tsx b/interface/src/framework/ntp/NTPStatus.tsx similarity index 89% rename from interface/src/framework/ntp/NTPStatusForm.tsx rename to interface/src/framework/ntp/NTPStatus.tsx index 1db783802..5c508892d 100644 --- a/interface/src/framework/ntp/NTPStatusForm.tsx +++ b/interface/src/framework/ntp/NTPStatus.tsx @@ -27,7 +27,7 @@ import { toast } from 'react-toastify'; import type { Theme } from '@mui/material'; import type { FC } from 'react'; -import type { NTPStatus } from 'types'; +import type { NTPStatusType } from 'types'; import { dialogStyle } from 'CustomTheme'; import * as NTPApi from 'api/ntp'; import { ButtonRow, FormLoader, SectionContent } from 'components'; @@ -36,23 +36,7 @@ import { useI18nContext } from 'i18n/i18n-react'; import { NTPSyncStatus } from 'types'; import { formatDateTime, formatLocalDateTime } from 'utils'; -export const isNtpActive = ({ status }: NTPStatus) => status === NTPSyncStatus.NTP_ACTIVE; -export const isNtpEnabled = ({ status }: NTPStatus) => status !== NTPSyncStatus.NTP_DISABLED; - -export const ntpStatusHighlight = ({ status }: NTPStatus, theme: Theme) => { - switch (status) { - case NTPSyncStatus.NTP_DISABLED: - return theme.palette.info.main; - case NTPSyncStatus.NTP_INACTIVE: - return theme.palette.error.main; - case NTPSyncStatus.NTP_ACTIVE: - return theme.palette.success.main; - default: - return theme.palette.error.main; - } -}; - -const NTPStatusForm: FC = () => { +const NTPStatus: FC = () => { const { data: data, send: loadData, error } = useRequest(NTPApi.readNTPStatus); const [localTime, setLocalTime] = useState(''); @@ -67,6 +51,22 @@ const NTPStatusForm: FC = () => { NTPApi.updateTime; + const isNtpActive = ({ status }: NTPStatusType) => status === NTPSyncStatus.NTP_ACTIVE; + const isNtpEnabled = ({ status }: NTPStatusType) => status !== NTPSyncStatus.NTP_DISABLED; + + const ntpStatusHighlight = ({ status }: NTPStatusType, theme: Theme) => { + switch (status) { + case NTPSyncStatus.NTP_DISABLED: + return theme.palette.info.main; + case NTPSyncStatus.NTP_INACTIVE: + return theme.palette.error.main; + case NTPSyncStatus.NTP_ACTIVE: + return theme.palette.success.main; + default: + return theme.palette.error.main; + } + }; + const updateLocalTime = (event: React.ChangeEvent) => setLocalTime(event.target.value); const openSetTime = () => { @@ -76,7 +76,7 @@ const NTPStatusForm: FC = () => { const theme = useTheme(); - const ntpStatus = ({ status }: NTPStatus) => { + const ntpStatus = ({ status }: NTPStatusType) => { switch (status) { case NTPSyncStatus.NTP_DISABLED: return LL.NOT_ENABLED(); @@ -217,4 +217,4 @@ const NTPStatusForm: FC = () => { return {content()}; }; -export default NTPStatusForm; +export default NTPStatus; diff --git a/interface/src/framework/ntp/NetworkTime.tsx b/interface/src/framework/ntp/NetworkTime.tsx index 1b3196e42..b3e0d9db6 100644 --- a/interface/src/framework/ntp/NetworkTime.tsx +++ b/interface/src/framework/ntp/NetworkTime.tsx @@ -1,7 +1,7 @@ import { Tab } from '@mui/material'; import { Navigate, Route, Routes } from 'react-router-dom'; -import NTPSettingsForm from './NTPSettingsForm'; -import NTPStatusForm from './NTPStatusForm'; +import NTPSettings from './NTPSettings'; +import NTPStatus from './NTPStatus'; import type { FC } from 'react'; import { RequireAdmin, RouterTabs, useLayoutTitle, useRouterTab } from 'components'; @@ -21,12 +21,12 @@ const NetworkTime: FC = () => { - } /> + } /> - + } /> diff --git a/interface/src/framework/ota/OTASettingsForm.tsx b/interface/src/framework/ota/OTASettings.tsx similarity index 95% rename from interface/src/framework/ota/OTASettingsForm.tsx rename to interface/src/framework/ota/OTASettings.tsx index 2441aacea..d6ca2b539 100644 --- a/interface/src/framework/ota/OTASettingsForm.tsx +++ b/interface/src/framework/ota/OTASettings.tsx @@ -5,7 +5,7 @@ import { useState } from 'react'; import type { ValidateFieldsError } from 'async-validator'; import type { FC } from 'react'; -import type { OTASettings } from 'types'; +import type { OTASettingsType } from 'types'; import * as SystemApi from 'api/system'; import { BlockFormControlLabel, @@ -24,7 +24,7 @@ import { numberValue, updateValueDirty, useRest } from 'utils'; import { validate } from 'validators'; import { OTA_SETTINGS_VALIDATOR } from 'validators/system'; -const OTASettingsForm: FC = () => { +const OTASettings: FC = () => { const { loadData, saveData, @@ -36,7 +36,7 @@ const OTASettingsForm: FC = () => { setDirtyFlags, blocker, errorMessage - } = useRest({ + } = useRest({ read: SystemApi.readOTASettings, update: SystemApi.updateOTASettings }); @@ -127,4 +127,4 @@ const OTASettingsForm: FC = () => { ); }; -export default OTASettingsForm; +export default OTASettings; diff --git a/interface/src/framework/security/ManageUsersForm.tsx b/interface/src/framework/security/ManageUsers.tsx similarity index 95% rename from interface/src/framework/security/ManageUsersForm.tsx rename to interface/src/framework/security/ManageUsers.tsx index bd0012660..185bf5625 100644 --- a/interface/src/framework/security/ManageUsersForm.tsx +++ b/interface/src/framework/security/ManageUsers.tsx @@ -14,9 +14,9 @@ import { useContext, useState } from 'react'; import { useBlocker } from 'react-router-dom'; import GenerateToken from './GenerateToken'; -import UserForm from './UserForm'; +import User from './User'; import type { FC } from 'react'; -import type { SecuritySettings, User } from 'types'; +import type { SecuritySettingsType, UserType } from 'types'; import * as SecurityApi from 'api/security'; import { ButtonRow, FormLoader, MessageBox, SectionContent, BlockNavigation } from 'components'; import { AuthenticatedContext } from 'contexts/authentication'; @@ -24,13 +24,13 @@ import { useI18nContext } from 'i18n/i18n-react'; import { useRest } from 'utils'; import { createUserValidator } from 'validators'; -const ManageUsersForm: FC = () => { - const { loadData, saveData, saving, data, updateDataValue, errorMessage } = useRest({ +const ManageUsers: FC = () => { + const { loadData, saveData, saving, data, updateDataValue, errorMessage } = useRest({ read: SecurityApi.readSecuritySettings, update: SecurityApi.updateSecuritySettings }); - const [user, setUser] = useState(); + const [user, setUser] = useState(); const [creating, setCreating] = useState(false); const [changed, setChanged] = useState(0); const [generatingToken, setGeneratingToken] = useState(); @@ -86,7 +86,7 @@ const ManageUsersForm: FC = () => { const noAdminConfigured = () => !data.users.find((u) => u.admin); - const removeUser = (toRemove: User) => { + const removeUser = (toRemove: UserType) => { const users = data.users.filter((u) => u.username !== toRemove.username); updateDataValue({ ...data, users }); setChanged(changed + 1); @@ -101,7 +101,7 @@ const ManageUsersForm: FC = () => { }); }; - const editUser = (toEdit: User) => { + const editUser = (toEdit: UserType) => { setCreating(false); setUser({ ...toEdit }); }; @@ -219,7 +219,7 @@ const ManageUsersForm: FC = () => { - { ); }; -export default ManageUsersForm; +export default ManageUsers; diff --git a/interface/src/framework/security/Security.tsx b/interface/src/framework/security/Security.tsx index a2b18d5ea..362b11d1f 100644 --- a/interface/src/framework/security/Security.tsx +++ b/interface/src/framework/security/Security.tsx @@ -1,7 +1,7 @@ import { Tab } from '@mui/material'; import { Navigate, Routes, Route } from 'react-router-dom'; -import ManageUsersForm from './ManageUsersForm'; -import SecuritySettingsForm from './SecuritySettingsForm'; +import ManageUsers from './ManageUsers'; +import SecuritySettings from './SecuritySettings'; import type { FC } from 'react'; import { RouterTabs, useRouterTab, useLayoutTitle } from 'components'; @@ -21,8 +21,8 @@ const Security: FC = () => { - } /> - } /> + } /> + } /> } /> diff --git a/interface/src/framework/security/SecuritySettingsForm.tsx b/interface/src/framework/security/SecuritySettings.tsx similarity index 94% rename from interface/src/framework/security/SecuritySettingsForm.tsx rename to interface/src/framework/security/SecuritySettings.tsx index 4750209bf..5a0981abb 100644 --- a/interface/src/framework/security/SecuritySettingsForm.tsx +++ b/interface/src/framework/security/SecuritySettings.tsx @@ -5,7 +5,7 @@ import { useContext, useState } from 'react'; import type { ValidateFieldsError } from 'async-validator'; import type { FC } from 'react'; -import type { SecuritySettings } from 'types'; +import type { SecuritySettingsType } from 'types'; import * as SecurityApi from 'api/security'; import { ButtonRow, FormLoader, MessageBox, SectionContent, ValidatedPasswordField, BlockNavigation } from 'components'; @@ -14,7 +14,7 @@ import { useI18nContext } from 'i18n/i18n-react'; import { updateValueDirty, useRest } from 'utils'; import { SECURITY_SETTINGS_VALIDATOR, validate } from 'validators'; -const SecuritySettingsForm: FC = () => { +const SecuritySettings: FC = () => { const { LL } = useI18nContext(); const [fieldErrors, setFieldErrors] = useState(); @@ -29,7 +29,7 @@ const SecuritySettingsForm: FC = () => { blocker, saveData, errorMessage - } = useRest({ + } = useRest({ read: SecurityApi.readSecuritySettings, update: SecurityApi.updateSecuritySettings }); @@ -103,4 +103,4 @@ const SecuritySettingsForm: FC = () => { ); }; -export default SecuritySettingsForm; +export default SecuritySettings; diff --git a/interface/src/framework/security/UserForm.tsx b/interface/src/framework/security/User.tsx similarity index 92% rename from interface/src/framework/security/UserForm.tsx rename to interface/src/framework/security/User.tsx index 3416b5dd4..f5c9037c7 100644 --- a/interface/src/framework/security/UserForm.tsx +++ b/interface/src/framework/security/User.tsx @@ -8,7 +8,7 @@ import type Schema from 'async-validator'; import type { ValidateFieldsError } from 'async-validator'; import type { FC } from 'react'; -import type { User } from 'types'; +import type { UserType } from 'types'; import { dialogStyle } from 'CustomTheme'; import { BlockFormControlLabel, ValidatedPasswordField, ValidatedTextField } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; @@ -19,14 +19,14 @@ interface UserFormProps { creating: boolean; validator: Schema; - user?: User; - setUser: React.Dispatch>; + user?: UserType; + setUser: React.Dispatch>; onDoneEditing: () => void; onCancelEditing: () => void; } -const UserForm: FC = ({ creating, validator, user, setUser, onDoneEditing, onCancelEditing }) => { +const User: FC = ({ creating, validator, user, setUser, onDoneEditing, onCancelEditing }) => { const { LL } = useI18nContext(); const updateFormValue = updateValue(setUser); @@ -104,4 +104,4 @@ const UserForm: FC = ({ creating, validator, user, setUser, onDon ); }; -export default UserForm; +export default User; diff --git a/interface/src/framework/system/ESPSystemStatus.tsx b/interface/src/framework/system/ESPSystemStatus.tsx index eea66a8bf..95b22b77c 100644 --- a/interface/src/framework/system/ESPSystemStatus.tsx +++ b/interface/src/framework/system/ESPSystemStatus.tsx @@ -133,6 +133,7 @@ const ESPSystemStatus: FC = () => { secondary={formatNumber(data.fs_used) + ' KB / ' + formatNumber(data.fs_free) + ' KB'} /> + diff --git a/interface/src/framework/system/Status.tsx b/interface/src/framework/system/System.tsx similarity index 76% rename from interface/src/framework/system/Status.tsx rename to interface/src/framework/system/System.tsx index e692163ab..32d929475 100644 --- a/interface/src/framework/system/Status.tsx +++ b/interface/src/framework/system/System.tsx @@ -7,25 +7,25 @@ import type { FC } from 'react'; import { useRouterTab, RouterTabs, useLayoutTitle } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; -import Activity from 'project/Activity'; +import SystemActivity from 'project/SystemActivity'; -const Status: FC = () => { +const System: FC = () => { const { LL } = useI18nContext(); - useLayoutTitle(LL.STATUS_OF('')); + useLayoutTitle(LL.SYSTEM(0)); const { routerTab } = useRouterTab(); return ( <> - + } /> - } /> + } /> } /> } /> @@ -33,4 +33,4 @@ const Status: FC = () => { ); }; -export default Status; +export default System; diff --git a/interface/src/framework/system/SystemLog.tsx b/interface/src/framework/system/SystemLog.tsx index e944283a4..3b81b5963 100644 --- a/interface/src/framework/system/SystemLog.tsx +++ b/interface/src/framework/system/SystemLog.tsx @@ -11,7 +11,7 @@ import { addAccessTokenParameter } from 'api/authentication'; import { EVENT_SOURCE_ROOT } from 'api/endpoints'; import * as SystemApi from 'api/system'; -import { SectionContent, FormLoader, BlockFormControlLabel, BlockNavigation } from 'components'; +import { SectionContent, FormLoader, BlockFormControlLabel, BlockNavigation, useLayoutTitle } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; import { LogLevel } from 'types'; @@ -50,6 +50,8 @@ const levelLabel = (level: LogLevel) => { const SystemLog: FC = () => { const { LL } = useI18nContext(); + useLayoutTitle(LL.LOG_OF('')); + const { loadData, data, updateDataValue, origData, dirtyFlags, setDirtyFlags, blocker, saveData, errorMessage } = useRest({ read: SystemApi.readLogSettings, diff --git a/interface/src/framework/system/SystemStatus.tsx b/interface/src/framework/system/SystemStatus.tsx index 1ed23ee69..c244dc5ce 100644 --- a/interface/src/framework/system/SystemStatus.tsx +++ b/interface/src/framework/system/SystemStatus.tsx @@ -1,7 +1,9 @@ import BuildIcon from '@mui/icons-material/Build'; import CancelIcon from '@mui/icons-material/Cancel'; +import CastIcon from '@mui/icons-material/Cast'; 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 RefreshIcon from '@mui/icons-material/Refresh'; import TimerIcon from '@mui/icons-material/Timer'; @@ -29,10 +31,12 @@ import { toast } from 'react-toastify'; import { dialogStyle } from 'CustomTheme'; import * as SystemApi from 'api/system'; import { FormLoader, SectionContent, useLayoutTitle } from 'components'; +import ListMenuItem from 'components/layout/ListMenuItem'; import { AuthenticatedContext } from 'contexts/authentication'; import { useI18nContext } from 'i18n/i18n-react'; import * as EMSESP from 'project/api'; import { busConnectionStatus } from 'project/types'; +import { NTPSyncStatus } from 'types'; const SystemStatus: FC = () => { const { LL } = useI18nContext(); @@ -71,6 +75,10 @@ const SystemStatus: FC = () => { return formatted; }; + function formatNumber(num: number) { + return new Intl.NumberFormat().format(num); + } + const busStatus = () => { if (data) { switch (data.status) { @@ -85,8 +93,6 @@ const SystemStatus: FC = () => { return 'Unknown'; }; - // export const isConnected = ({ status }: Status) => status !== busConnectionStatus.BUS_STATUS_OFFLINE; - const busStatusHighlight = () => { switch (data.status) { case busConnectionStatus.BUS_STATUS_TX_ERRORS: @@ -100,6 +106,34 @@ const SystemStatus: FC = () => { } }; + const ntpStatus = () => { + switch (data.ntp_status) { + case NTPSyncStatus.NTP_DISABLED: + return LL.NOT_ENABLED(); + case NTPSyncStatus.NTP_INACTIVE: + return LL.INACTIVE(0); + case NTPSyncStatus.NTP_ACTIVE: + return LL.ACTIVE(); + default: + return LL.UNKNOWN(); + } + }; + + const ntpStatusHighlight = () => { + switch (data.ntp_status) { + case NTPSyncStatus.NTP_DISABLED: + return theme.palette.info.main; + case NTPSyncStatus.NTP_INACTIVE: + return theme.palette.error.main; + case NTPSyncStatus.NTP_ACTIVE: + return theme.palette.success.main; + default: + return theme.palette.error.main; + } + }; + + const activeHighlight = (value: boolean) => (value ? theme.palette.success.main : theme.palette.info.main); + const scan = async () => { await scanDevices() .then(() => { @@ -136,27 +170,7 @@ const SystemStatus: FC = () => { - - - - - - - - - - - - - - - - - - - - - + @@ -166,7 +180,7 @@ const SystemStatus: FC = () => { - + @@ -191,7 +205,67 @@ const SystemStatus: FC = () => { )} + + + + + + + + + + + + + + + {/* TODO: translate */} + + + + + + + + + + diff --git a/interface/src/i18n/de/index.ts b/interface/src/i18n/de/index.ts index 77c3e0685..fa20bef85 100644 --- a/interface/src/i18n/de/index.ts +++ b/interface/src/i18n/de/index.ts @@ -322,8 +322,8 @@ const de: Translation = { ACTIVELOW: 'Aktiv Negativ', UNCHANGED: 'Unverändert', ALWAYS: 'Immer', - ACTIVITY: 'Activity' // TODO translate - + ACTIVITY: 'Activity', // TODO translate + CONFIGURE: 'Configure {0}' // TODO translate }; export default de; diff --git a/interface/src/i18n/en/index.ts b/interface/src/i18n/en/index.ts index d1ecd25aa..61db4b47a 100644 --- a/interface/src/i18n/en/index.ts +++ b/interface/src/i18n/en/index.ts @@ -322,7 +322,8 @@ const en: Translation = { ACTIVELOW: 'Active Low', UNCHANGED: 'Unchanged', ALWAYS: 'Always', - ACTIVITY: 'Activity' + ACTIVITY: 'Activity', + CONFIGURE: 'Configure {0}' }; export default en; diff --git a/interface/src/i18n/fr/index.ts b/interface/src/i18n/fr/index.ts index 8187f0dea..261cc33c6 100644 --- a/interface/src/i18n/fr/index.ts +++ b/interface/src/i18n/fr/index.ts @@ -322,7 +322,8 @@ const fr: Translation = { ACTIVELOW: 'Active Low', // TODO translate UNCHANGED: 'Unchanged', // TODO translate ALWAYS: 'Always', // TODO translate - ACTIVITY: 'Activity' // TODO translate + ACTIVITY: 'Activity', // TODO translate + CONFIGURE: 'Configure {0}' // TODO translate }; export default fr; diff --git a/interface/src/i18n/it/index.ts b/interface/src/i18n/it/index.ts index 85e1c806c..ec1a4b4d7 100644 --- a/interface/src/i18n/it/index.ts +++ b/interface/src/i18n/it/index.ts @@ -322,7 +322,8 @@ const it: Translation = { ACTIVELOW: 'Active Low', // TODO translate UNCHANGED: 'Unchanged', // TODO translate ALWAYS: 'Always', // TODO translate - ACTIVITY: 'Activity' // TODO translate + ACTIVITY: 'Activity', // TODO translate + CONFIGURE: 'Configure {0}' // TODO translate }; export default it; diff --git a/interface/src/i18n/nl/index.ts b/interface/src/i18n/nl/index.ts index 55f1651c5..5c07b35f8 100644 --- a/interface/src/i18n/nl/index.ts +++ b/interface/src/i18n/nl/index.ts @@ -122,7 +122,7 @@ const nl: Translation = { BYPASS_TOKEN: 'API Access Token authenticatie uitschakelen', READONLY: 'Activeer read-only modus (blokkeert alle outgaande EMS Tx schrijf commandos)', UNDERCLOCK_CPU: 'Underclock CPU snelheid', - HEATINGOFF: 'Start boiler with forced heating off', // TODO translate + HEATINGOFF: 'Start ketel met geforceerde verwarming uit', ENABLE_SHOWER_TIMER: 'Activeer Douche Timer (tijdmeting)', ENABLE_SHOWER_ALERT: 'Activeer Douchemelding', TRIGGER_TIME: 'Trigger tijd', @@ -272,7 +272,7 @@ const nl: Translation = { NETWORK_SCANNER: 'Netwerk Scanner', NETWORK_NO_WIFI: 'Geen WiFi networken gevonden', NETWORK_BLANK_SSID: 'laat leeg om WiFi uit te schakelen', - NETWORK_BLANK_BSSID: 'leave blank to use only SSID', // TODO translate + NETWORK_BLANK_BSSID: 'laat leeg om alleen SSID te bebruiken', TX_POWER: 'Tx Vermogen', HOSTNAME: 'Hostname', NETWORK_DISABLE_SLEEP: 'WiFi Sleep Mode uitzetten', @@ -308,21 +308,22 @@ const nl: Translation = { SCHEDULE_TIMER_2: 'elke minuut', SCHEDULE_TIMER_3: 'elke huur', CUSTOM_ENTITIES: 'Aangepaste Entiteiten', - ENTITIES_HELP_1: 'Aangepaste entiteiten ophalen uit de EMS-bus', // TODO translate + ENTITIES_HELP_1: 'Aangepaste entiteiten ophalen uit de EMS-bus', ENTITIES_UPDATED: 'Entiteiten bijgewerkt', WRITEABLE: 'Beschrijfbare', SHOWING: 'Tonen', SEARCH: 'Zoek', - CERT: 'TLS rootcertificaat (laat leeg om TLS-insecure)', // TODO translate + CERT: 'TLS rootcertificaat (laat leeg om TLS-insecure)', ENABLE_TLS: 'Activeer TLS', - ON: 'On', // TODO translate - OFF: 'Off', // TODO translate - POLARITY: 'Polarity', // TODO translate - ACTIVEHIGH: 'Active High', // TODO translate - ACTIVELOW: 'Active Low', // TODO translate - UNCHANGED: 'Unchanged', // TODO translate - ALWAYS: 'Always', // TODO translate - ACTIVITY: 'Activity' // TODO translate + ON: 'Aan', + OFF: 'Uit', + POLARITY: 'Polariteit', + ACTIVEHIGH: 'Actiev Hoog', + ACTIVELOW: 'Actiev Laag', + UNCHANGED: 'Ongewijzigd', + ALWAYS: 'Altijd', + ACTIVITY: 'Activiteit', + CONFIGURE: '{0} Configureren' }; export default nl; diff --git a/interface/src/i18n/no/index.ts b/interface/src/i18n/no/index.ts index 533ac2713..d7fa2103e 100644 --- a/interface/src/i18n/no/index.ts +++ b/interface/src/i18n/no/index.ts @@ -322,7 +322,8 @@ const no: Translation = { ACTIVELOW: 'Active Low', // TODO translate UNCHANGED: 'Unchanged', // TODO translate ALWAYS: 'Always', // TODO translate - ACTIVITY: 'Activity' // TODO translate + ACTIVITY: 'Activity', // TODO translate + CONFIGURE: 'Configure {0}' // TODO translate }; export default no; diff --git a/interface/src/i18n/pl/index.ts b/interface/src/i18n/pl/index.ts index fd2f641b8..e5ca84bf7 100644 --- a/interface/src/i18n/pl/index.ts +++ b/interface/src/i18n/pl/index.ts @@ -308,7 +308,7 @@ const pl: BaseTranslation = { SCHEDULE_TIMER_2: 'co minutę', SCHEDULE_TIMER_3: 'co godzinę', CUSTOM_ENTITIES: '{{N|n|}}iestandardowe{{|j|}} encj{{e|i|}}', - ENTITIES_HELP_1: 'Zdefiniuj niestandardowe encje dla magistrali EMS.', // TODO translate + ENTITIES_HELP_1: 'Zdefiniuj niestandardowe encje dla magistrali EMS.', ENTITIES_UPDATED: 'Niestandardowe encje zostały uaktualnione.', WRITEABLE: 'Zapisywalna', SHOWING: 'Wyświetlane', @@ -322,7 +322,8 @@ const pl: BaseTranslation = { ACTIVELOW: 'Wyzwalany stanem niskim', UNCHANGED: 'Zachowaj stan', ALWAYS: 'Zawsze', - ACTIVITY: 'Activity' // TODO translate + ACTIVITY: 'Aktywność', + CONFIGURE: 'Konfiguracja {0}' }; export default pl; diff --git a/interface/src/i18n/sk/index.ts b/interface/src/i18n/sk/index.ts index 2b0399ba3..2128f2d86 100644 --- a/interface/src/i18n/sk/index.ts +++ b/interface/src/i18n/sk/index.ts @@ -308,7 +308,7 @@ const sk: Translation = { SCHEDULE_TIMER_2: 'každú minútu', SCHEDULE_TIMER_3: 'každú hodinu', CUSTOM_ENTITIES: 'Vlastné entity', - ENTITIES_HELP_1: 'Získavanie vlastných entít zo zbernice EMS', // TODO translate + ENTITIES_HELP_1: 'Získavanie vlastných entít zo zbernice EMS', ENTITIES_UPDATED: 'Aktualizované entity', WRITEABLE: 'Zapísateľný', SHOWING: 'Zobrazenie', @@ -322,7 +322,8 @@ const sk: Translation = { ACTIVELOW: 'Aktívny Nízky', UNCHANGED: 'Nezmenené', ALWAYS: 'Vždy', - ACTIVITY: 'Activity' // TODO translate + ACTIVITY: 'Activity', // TODO translate + CONFIGURE: 'Configure {0}' // TODO translate }; export default sk; diff --git a/interface/src/i18n/sv/index.ts b/interface/src/i18n/sv/index.ts index 13f2d86b0..e2c7bc002 100644 --- a/interface/src/i18n/sv/index.ts +++ b/interface/src/i18n/sv/index.ts @@ -322,7 +322,8 @@ const sv: Translation = { ACTIVELOW: 'Active Low', // TODO translate UNCHANGED: 'Unchanged', // TODO translate ALWAYS: 'Always', // TODO translate - ACTIVITY: 'Activity' // TODO translate + ACTIVITY: 'Activity', // TODO translate + CONFIGURE: 'Configure {0}' // TODO translate }; export default sv; diff --git a/interface/src/i18n/tr/index.ts b/interface/src/i18n/tr/index.ts index f6c84fece..8952acecc 100644 --- a/interface/src/i18n/tr/index.ts +++ b/interface/src/i18n/tr/index.ts @@ -322,7 +322,8 @@ const tr: Translation = { ACTIVELOW: 'Active Low', // TODO translate UNCHANGED: 'Unchanged', // TODO translate ALWAYS: 'Always', // TODO translate - ACTIVITY: 'Activity' // TODO translate + ACTIVITY: 'Activity', // TODO translate + CONFIGURE: 'Configure {0}' // TODO translate }; export default tr; diff --git a/interface/src/project/ApplicationSettings.tsx b/interface/src/project/ApplicationSettings.tsx index 4817094e0..3b7d267a0 100644 --- a/interface/src/project/ApplicationSettings.tsx +++ b/interface/src/project/ApplicationSettings.tsx @@ -139,7 +139,7 @@ const ApplicationSettings: FC = () => { return ( <> - + {LL.INTERFACE_BOARD_PROFILE()} diff --git a/interface/src/project/Sensors.tsx b/interface/src/project/Sensors.tsx index d74b88131..6ff34de0c 100644 --- a/interface/src/project/Sensors.tsx +++ b/interface/src/project/Sensors.tsx @@ -410,7 +410,7 @@ const Sensors: FC = () => { {sensorData.ts.length > 0 && ( <> - + {LL.TEMP_SENSORS()} diff --git a/interface/src/project/Activity.tsx b/interface/src/project/SystemActivity.tsx similarity index 95% rename from interface/src/project/Activity.tsx rename to interface/src/project/SystemActivity.tsx index 7320270cc..b335fa570 100644 --- a/interface/src/project/Activity.tsx +++ b/interface/src/project/SystemActivity.tsx @@ -10,14 +10,16 @@ import type { Stat } from './types'; import type { Translation } from 'i18n/i18n-types'; import type { FC } from 'react'; -import { FormLoader, SectionContent } from 'components'; +import { FormLoader, SectionContent, useLayoutTitle } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; -const Activity: FC = () => { +const SystemActivity: FC = () => { const { data: data, send: loadData, error } = useRequest(EMSESP.readActivity); const { LL } = useI18nContext(); + useLayoutTitle(LL.ACTIVITY()); + const stats_theme = tableTheme({ Table: ` --data-table-library_grid-template-columns: repeat(1, minmax(0, 1fr)) 90px 90px 80px; @@ -125,4 +127,4 @@ const Activity: FC = () => { return {content()}; }; -export default Activity; +export default SystemActivity; diff --git a/interface/src/types/ap.ts b/interface/src/types/ap.ts index f2d81cd6f..de5fe64ad 100644 --- a/interface/src/types/ap.ts +++ b/interface/src/types/ap.ts @@ -10,14 +10,14 @@ export enum APNetworkStatus { LINGERING = 2 } -export interface APStatus { +export interface APStatusType { status: APNetworkStatus; ip_address: string; mac_address: string; station_num: number; } -export interface APSettings { +export interface APSettingsType { provision_mode: APProvisionMode; ssid: string; password: string; diff --git a/interface/src/types/mqtt.ts b/interface/src/types/mqtt.ts index 9b5db1458..6c9ad377e 100644 --- a/interface/src/types/mqtt.ts +++ b/interface/src/types/mqtt.ts @@ -9,7 +9,7 @@ export enum MqttDisconnectReason { TCP_DISCONNECTED = 7 } -export interface MqttStatus { +export interface MqttStatusType { enabled: boolean; connected: boolean; client_id: string; @@ -19,7 +19,7 @@ export interface MqttStatus { connect_count: number; } -export interface MqttSettings { +export interface MqttSettingsType { enabled: boolean; host: string; port: number; diff --git a/interface/src/types/network.ts b/interface/src/types/network.ts index c5d8795df..c1c1ad560 100644 --- a/interface/src/types/network.ts +++ b/interface/src/types/network.ts @@ -20,7 +20,7 @@ export enum WiFiEncryptionType { WIFI_AUTH_WPA2_WPA3_PSK = 7 } -export interface NetworkStatus { +export interface NetworkStatusType { status: NetworkConnectionStatus; local_ip: string; local_ipv6: string; @@ -36,7 +36,7 @@ export interface NetworkStatus { hostname: string; } -export interface NetworkSettings { +export interface NetworkSettingsType { ssid: string; bssid: string; password: string; diff --git a/interface/src/types/ntp.ts b/interface/src/types/ntp.ts index b783cfb80..8f86303b6 100644 --- a/interface/src/types/ntp.ts +++ b/interface/src/types/ntp.ts @@ -4,14 +4,14 @@ export enum NTPSyncStatus { NTP_ACTIVE = 2 } -export interface NTPStatus { +export interface NTPStatusType { status: NTPSyncStatus; utc_time: string; local_time: string; server: string; } -export interface NTPSettings { +export interface NTPSettingsType { enabled: boolean; server: string; tz_label: string; diff --git a/interface/src/types/security.ts b/interface/src/types/security.ts index 90db06a1e..d08d64aaf 100644 --- a/interface/src/types/security.ts +++ b/interface/src/types/security.ts @@ -1,11 +1,11 @@ -export interface User { +export interface UserType { username: string; password: string; admin: boolean; } -export interface SecuritySettings { - users: User[]; +export interface SecuritySettingsType { + users: UserType[]; jwt_secret: string; } diff --git a/interface/src/types/system.ts b/interface/src/types/system.ts index 3a7721178..3ba224219 100644 --- a/interface/src/types/system.ts +++ b/interface/src/types/system.ts @@ -28,14 +28,17 @@ export interface SystemStatus { emsesp_version: string; esp_platform: string; status: busConnectionStatus; - tx_mode: number; uptime: number; num_devices: number; num_sensors: number; num_analogs: number; + free_heap: number; + ntp_status: number; + ota_status: boolean; + mqtt_status: boolean; } -export interface OTASettings { +export interface OTASettingsType { enabled: boolean; port: number; password: string; diff --git a/interface/src/validators/ap.ts b/interface/src/validators/ap.ts index cd5812e8b..d66a5ff14 100644 --- a/interface/src/validators/ap.ts +++ b/interface/src/validators/ap.ts @@ -1,9 +1,9 @@ import Schema from 'async-validator'; import { IP_ADDRESS_VALIDATOR } from './shared'; -import type { APSettings } from 'types'; -import { isAPEnabled } from 'framework/ap/APSettingsForm'; +import type { APSettingsType } from 'types'; +import { isAPEnabled } from 'framework/ap/APSettings'; -export const createAPSettingsValidator = (apSettings: APSettings) => +export const createAPSettingsValidator = (apSettings: APSettingsType) => new Schema({ provision_mode: { required: true, message: 'Please provide a provision mode' }, ...(isAPEnabled(apSettings) && { diff --git a/interface/src/validators/mqtt.ts b/interface/src/validators/mqtt.ts index d8f841baa..bb6a5d46e 100644 --- a/interface/src/validators/mqtt.ts +++ b/interface/src/validators/mqtt.ts @@ -1,8 +1,8 @@ import Schema from 'async-validator'; import { IP_OR_HOSTNAME_VALIDATOR } from './shared'; -import type { MqttSettings } from 'types'; +import type { MqttSettingsType } from 'types'; -export const createMqttSettingsValidator = (mqttSettings: MqttSettings) => +export const createMqttSettingsValidator = (mqttSettings: MqttSettingsType) => new Schema({ ...(mqttSettings.enabled && { host: [{ required: true, message: 'Host is required' }, IP_OR_HOSTNAME_VALIDATOR], diff --git a/interface/src/validators/network.ts b/interface/src/validators/network.ts index 7582d7af7..1e98838ae 100644 --- a/interface/src/validators/network.ts +++ b/interface/src/validators/network.ts @@ -1,8 +1,8 @@ import Schema from 'async-validator'; import { HOSTNAME_VALIDATOR, IP_ADDRESS_VALIDATOR } from './shared'; -import type { NetworkSettings } from 'types'; +import type { NetworkSettingsType } from 'types'; -export const createNetworkSettingsValidator = (networkSettings: NetworkSettings) => +export const createNetworkSettingsValidator = (networkSettings: NetworkSettingsType) => new Schema({ ssid: [{ type: 'string', max: 32, message: 'SSID must be 32 characters or less' }], bssid: [{ type: 'string', max: 17, message: 'BSSID must be 17 characters or empty' }], diff --git a/interface/src/validators/security.ts b/interface/src/validators/security.ts index d1843ac90..b5a59f540 100644 --- a/interface/src/validators/security.ts +++ b/interface/src/validators/security.ts @@ -1,6 +1,6 @@ import Schema from 'async-validator'; import type { InternalRuleItem } from 'async-validator'; -import type { User } from 'types'; +import type { UserType } from 'types'; export const SECURITY_SETTINGS_VALIDATOR = new Schema({ jwt_secret: [ @@ -9,7 +9,7 @@ export const SECURITY_SETTINGS_VALIDATOR = new Schema({ ] }); -export const createUniqueUsernameValidator = (users: User[]) => ({ +export const createUniqueUsernameValidator = (users: UserType[]) => ({ validator(rule: InternalRuleItem, username: string, callback: (error?: string) => void) { if (username && users.find((u) => u.username === username)) { callback('Username already in use'); @@ -19,7 +19,7 @@ export const createUniqueUsernameValidator = (users: User[]) => ({ } }); -export const createUserValidator = (users: User[], creating: boolean) => +export const createUserValidator = (users: UserType[], creating: boolean) => new Schema({ username: [ { required: true, message: 'Username is required' }, diff --git a/interface/yarn.lock b/interface/yarn.lock index 390fa43ae..92e73f1c1 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -49,6 +49,16 @@ __metadata: languageName: node linkType: hard +"@babel/code-frame@npm:^7.24.2": + version: 7.24.2 + resolution: "@babel/code-frame@npm:7.24.2" + dependencies: + "@babel/highlight": "npm:^7.24.2" + picocolors: "npm:^1.0.0" + checksum: 10/7db8f5b36ffa3f47a37f58f61e3d130b9ecad21961f3eede7e2a4ac2c7e4a5efb6e9d03a810c669bc986096831b6c0dfc2c3082673d93351b82359c1b03e0590 + languageName: node + linkType: hard + "@babel/compat-data@npm:^7.23.5": version: 7.23.5 resolution: "@babel/compat-data@npm:7.23.5" @@ -79,12 +89,12 @@ __metadata: languageName: node linkType: hard -"@babel/core@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/core@npm:7.24.1" +"@babel/core@npm:^7.24.3": + version: 7.24.3 + resolution: "@babel/core@npm:7.24.3" dependencies: "@ampproject/remapping": "npm:^2.2.0" - "@babel/code-frame": "npm:^7.24.1" + "@babel/code-frame": "npm:^7.24.2" "@babel/generator": "npm:^7.24.1" "@babel/helper-compilation-targets": "npm:^7.23.6" "@babel/helper-module-transforms": "npm:^7.23.3" @@ -98,7 +108,7 @@ __metadata: gensync: "npm:^1.0.0-beta.2" json5: "npm:^2.2.3" semver: "npm:^6.3.1" - checksum: 10/f8c153acd619a5d17caee7aff052a2aa306ceda280ffc07182d7b5dd40c41c7511ae89d64bc23ec5555e4639fc9c87ceb7b4afc12252acab548ebb7654397680 + checksum: 10/3a7b9931fe0d93c500dcdb6b36f038b0f9d5090c048818e62aa8321c8f6e8ccc3d47373f0b40591c1fe3b13e5096bacabb1ade83f9f4d86f57878c39a9d1ade1 languageName: node linkType: hard @@ -289,6 +299,18 @@ __metadata: languageName: node linkType: hard +"@babel/highlight@npm:^7.24.2": + version: 7.24.2 + resolution: "@babel/highlight@npm:7.24.2" + dependencies: + "@babel/helper-validator-identifier": "npm:^7.22.20" + chalk: "npm:^2.4.2" + js-tokens: "npm:^4.0.0" + picocolors: "npm:^1.0.0" + checksum: 10/4555124235f34403bb28f55b1de58edf598491cc181c75f8afc8fe529903cb598cd52fe3bf2faab9bc1f45c299681ef0e44eea7a848bb85c500c5a4fe13f54f6 + languageName: node + linkType: hard + "@babel/parser@npm:^7.24.0": version: 7.24.0 resolution: "@babel/parser@npm:7.24.0" @@ -557,79 +579,79 @@ __metadata: languageName: node linkType: hard -"@esbuild/aix-ppc64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/aix-ppc64@npm:0.19.12" +"@esbuild/aix-ppc64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/aix-ppc64@npm:0.20.2" conditions: os=aix & cpu=ppc64 languageName: node linkType: hard -"@esbuild/android-arm64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/android-arm64@npm:0.19.12" +"@esbuild/android-arm64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/android-arm64@npm:0.20.2" conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@esbuild/android-arm@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/android-arm@npm:0.19.12" +"@esbuild/android-arm@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/android-arm@npm:0.20.2" conditions: os=android & cpu=arm languageName: node linkType: hard -"@esbuild/android-x64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/android-x64@npm:0.19.12" +"@esbuild/android-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/android-x64@npm:0.20.2" conditions: os=android & cpu=x64 languageName: node linkType: hard -"@esbuild/darwin-arm64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/darwin-arm64@npm:0.19.12" +"@esbuild/darwin-arm64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/darwin-arm64@npm:0.20.2" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@esbuild/darwin-x64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/darwin-x64@npm:0.19.12" +"@esbuild/darwin-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/darwin-x64@npm:0.20.2" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@esbuild/freebsd-arm64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/freebsd-arm64@npm:0.19.12" +"@esbuild/freebsd-arm64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/freebsd-arm64@npm:0.20.2" conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard -"@esbuild/freebsd-x64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/freebsd-x64@npm:0.19.12" +"@esbuild/freebsd-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/freebsd-x64@npm:0.20.2" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"@esbuild/linux-arm64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-arm64@npm:0.19.12" +"@esbuild/linux-arm64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-arm64@npm:0.20.2" conditions: os=linux & cpu=arm64 languageName: node linkType: hard -"@esbuild/linux-arm@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-arm@npm:0.19.12" +"@esbuild/linux-arm@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-arm@npm:0.20.2" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@esbuild/linux-ia32@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-ia32@npm:0.19.12" +"@esbuild/linux-ia32@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-ia32@npm:0.20.2" conditions: os=linux & cpu=ia32 languageName: node linkType: hard @@ -641,86 +663,86 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-loong64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-loong64@npm:0.19.12" +"@esbuild/linux-loong64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-loong64@npm:0.20.2" conditions: os=linux & cpu=loong64 languageName: node linkType: hard -"@esbuild/linux-mips64el@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-mips64el@npm:0.19.12" +"@esbuild/linux-mips64el@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-mips64el@npm:0.20.2" conditions: os=linux & cpu=mips64el languageName: node linkType: hard -"@esbuild/linux-ppc64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-ppc64@npm:0.19.12" +"@esbuild/linux-ppc64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-ppc64@npm:0.20.2" conditions: os=linux & cpu=ppc64 languageName: node linkType: hard -"@esbuild/linux-riscv64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-riscv64@npm:0.19.12" +"@esbuild/linux-riscv64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-riscv64@npm:0.20.2" conditions: os=linux & cpu=riscv64 languageName: node linkType: hard -"@esbuild/linux-s390x@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-s390x@npm:0.19.12" +"@esbuild/linux-s390x@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-s390x@npm:0.20.2" conditions: os=linux & cpu=s390x languageName: node linkType: hard -"@esbuild/linux-x64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-x64@npm:0.19.12" +"@esbuild/linux-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-x64@npm:0.20.2" conditions: os=linux & cpu=x64 languageName: node linkType: hard -"@esbuild/netbsd-x64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/netbsd-x64@npm:0.19.12" +"@esbuild/netbsd-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/netbsd-x64@npm:0.20.2" conditions: os=netbsd & cpu=x64 languageName: node linkType: hard -"@esbuild/openbsd-x64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/openbsd-x64@npm:0.19.12" +"@esbuild/openbsd-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/openbsd-x64@npm:0.20.2" conditions: os=openbsd & cpu=x64 languageName: node linkType: hard -"@esbuild/sunos-x64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/sunos-x64@npm:0.19.12" +"@esbuild/sunos-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/sunos-x64@npm:0.20.2" conditions: os=sunos & cpu=x64 languageName: node linkType: hard -"@esbuild/win32-arm64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/win32-arm64@npm:0.19.12" +"@esbuild/win32-arm64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/win32-arm64@npm:0.20.2" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@esbuild/win32-ia32@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/win32-ia32@npm:0.19.12" +"@esbuild/win32-ia32@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/win32-ia32@npm:0.20.2" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@esbuild/win32-x64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/win32-x64@npm:0.19.12" +"@esbuild/win32-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/win32-x64@npm:0.20.2" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -1751,7 +1773,7 @@ __metadata: resolution: "EMS-ESP@workspace:." dependencies: "@alova/adapter-xhr": "npm:^1.0.3" - "@babel/core": "npm:^7.24.1" + "@babel/core": "npm:^7.24.3" "@emotion/react": "npm:^11.11.4" "@emotion/styled": "npm:^11.11.0" "@mui/icons-material": "npm:^5.15.14" @@ -1767,7 +1789,7 @@ __metadata: "@types/react-router-dom": "npm:^5.3.3" "@typescript-eslint/eslint-plugin": "npm:^7.3.1" "@typescript-eslint/parser": "npm:^7.3.1" - alova: "npm:^2.17.1" + alova: "npm:^2.18.0" async-validator: "npm:^4.2.5" concurrently: "npm:^8.2.2" eslint: "npm:^8.57.0" @@ -1783,7 +1805,7 @@ __metadata: jwt-decode: "npm:^4.0.0" lodash-es: "npm:^4.17.21" mime-types: "npm:^2.1.35" - preact: "npm:^10.19.7" + preact: "npm:^10.20.0" prettier: "npm:^3.2.5" react: "npm:latest" react-dom: "npm:latest" @@ -1796,7 +1818,7 @@ __metadata: terser: "npm:^5.29.2" typesafe-i18n: "npm:^5.26.2" typescript: "npm:^5.4.2" - vite: "npm:^5.1.6" + vite: "npm:^5.2.2" vite-plugin-imagemin: "npm:^0.6.1" vite-tsconfig-paths: "npm:^4.3.2" languageName: unknown @@ -1858,10 +1880,10 @@ __metadata: languageName: node linkType: hard -"alova@npm:^2.17.1": - version: 2.17.1 - resolution: "alova@npm:2.17.1" - checksum: 10/8ad39e0847157cbff285be078a7f490ddcfacc4a0de8a2d5976607206e29c8fa232fcf088079bc87ef26eea2bc432a2bda835bc0d996e02a526990ef93f7a6d3 +"alova@npm:^2.18.0": + version: 2.18.0 + resolution: "alova@npm:2.18.0" + checksum: 10/6edf15157f4bce4239ba3461bf71a653fd4e904c80e5e7d4574328bb30d5704d5e4fc9c024b60f886bb010ee3e29e56cfb6ab7fc235a6a2aa4ee879cae35e387 languageName: node linkType: hard @@ -3554,33 +3576,33 @@ __metadata: languageName: node linkType: hard -"esbuild@npm:^0.19.3": - version: 0.19.12 - resolution: "esbuild@npm:0.19.12" +"esbuild@npm:^0.20.1": + version: 0.20.2 + resolution: "esbuild@npm:0.20.2" dependencies: - "@esbuild/aix-ppc64": "npm:0.19.12" - "@esbuild/android-arm": "npm:0.19.12" - "@esbuild/android-arm64": "npm:0.19.12" - "@esbuild/android-x64": "npm:0.19.12" - "@esbuild/darwin-arm64": "npm:0.19.12" - "@esbuild/darwin-x64": "npm:0.19.12" - "@esbuild/freebsd-arm64": "npm:0.19.12" - "@esbuild/freebsd-x64": "npm:0.19.12" - "@esbuild/linux-arm": "npm:0.19.12" - "@esbuild/linux-arm64": "npm:0.19.12" - "@esbuild/linux-ia32": "npm:0.19.12" - "@esbuild/linux-loong64": "npm:0.19.12" - "@esbuild/linux-mips64el": "npm:0.19.12" - "@esbuild/linux-ppc64": "npm:0.19.12" - "@esbuild/linux-riscv64": "npm:0.19.12" - "@esbuild/linux-s390x": "npm:0.19.12" - "@esbuild/linux-x64": "npm:0.19.12" - "@esbuild/netbsd-x64": "npm:0.19.12" - "@esbuild/openbsd-x64": "npm:0.19.12" - "@esbuild/sunos-x64": "npm:0.19.12" - "@esbuild/win32-arm64": "npm:0.19.12" - "@esbuild/win32-ia32": "npm:0.19.12" - "@esbuild/win32-x64": "npm:0.19.12" + "@esbuild/aix-ppc64": "npm:0.20.2" + "@esbuild/android-arm": "npm:0.20.2" + "@esbuild/android-arm64": "npm:0.20.2" + "@esbuild/android-x64": "npm:0.20.2" + "@esbuild/darwin-arm64": "npm:0.20.2" + "@esbuild/darwin-x64": "npm:0.20.2" + "@esbuild/freebsd-arm64": "npm:0.20.2" + "@esbuild/freebsd-x64": "npm:0.20.2" + "@esbuild/linux-arm": "npm:0.20.2" + "@esbuild/linux-arm64": "npm:0.20.2" + "@esbuild/linux-ia32": "npm:0.20.2" + "@esbuild/linux-loong64": "npm:0.20.2" + "@esbuild/linux-mips64el": "npm:0.20.2" + "@esbuild/linux-ppc64": "npm:0.20.2" + "@esbuild/linux-riscv64": "npm:0.20.2" + "@esbuild/linux-s390x": "npm:0.20.2" + "@esbuild/linux-x64": "npm:0.20.2" + "@esbuild/netbsd-x64": "npm:0.20.2" + "@esbuild/openbsd-x64": "npm:0.20.2" + "@esbuild/sunos-x64": "npm:0.20.2" + "@esbuild/win32-arm64": "npm:0.20.2" + "@esbuild/win32-ia32": "npm:0.20.2" + "@esbuild/win32-x64": "npm:0.20.2" dependenciesMeta: "@esbuild/aix-ppc64": optional: true @@ -3630,7 +3652,7 @@ __metadata: optional: true bin: esbuild: bin/esbuild - checksum: 10/861fa8eb2428e8d6521a4b7c7930139e3f45e8d51a86985cc29408172a41f6b18df7b3401e7e5e2d528cdf83742da601ddfdc77043ddc4f1c715a8ddb2d8a255 + checksum: 10/663215ab7e599651e00d61b528a63136e1f1d397db8b9c3712540af928c9476d61da95aefa81b7a8dfc7a9fdd7616fcf08395c27be68be8c99953fb461863ce4 languageName: node linkType: hard @@ -6762,21 +6784,21 @@ __metadata: languageName: node linkType: hard -"postcss@npm:^8.4.35": - version: 8.4.35 - resolution: "postcss@npm:8.4.35" +"postcss@npm:^8.4.36": + version: 8.4.37 + resolution: "postcss@npm:8.4.37" dependencies: nanoid: "npm:^3.3.7" picocolors: "npm:^1.0.0" - source-map-js: "npm:^1.0.2" - checksum: 10/93a7ce50cd6188f5f486a9ca98950ad27c19dfed996c45c414fa242944497e4d084a8760d3537f078630226f2bd3c6ab84b813b488740f4432e7c7039cd73a20 + source-map-js: "npm:^1.2.0" + checksum: 10/9acf36dfeaa350aab1100518af2da8cabebbbaf7d28356d0f81e1c30c9307f5ecb7356515585c63e5b011895ce3f5c7265df2cb9fce2e812b462aaf308199ffe languageName: node linkType: hard -"preact@npm:^10.19.7": - version: 10.19.7 - resolution: "preact@npm:10.19.7" - checksum: 10/3f64d5a0c7c01f773d5fa35ee408aa7efa87cccab75fbce2db413111815054eadef0329c65725b8f0d78d3116d6a576a6d0d4f9772450849cdd60bf325280a2a +"preact@npm:^10.20.0": + version: 10.20.0 + resolution: "preact@npm:10.20.0" + checksum: 10/fb8cfc1ab1b4b8f2bd483b9fdd2f8614cc7e099d741ec33f41d95d9056aefbe3fe5897201ef0f37c76238e7657ecd38afdef377e171cb1477068aae1dcf020d6 languageName: node linkType: hard @@ -7267,7 +7289,7 @@ __metadata: languageName: node linkType: hard -"rollup@npm:^4.2.0": +"rollup@npm:^4.13.0": version: 4.13.0 resolution: "rollup@npm:4.13.0" dependencies: @@ -7609,10 +7631,10 @@ __metadata: languageName: node linkType: hard -"source-map-js@npm:^1.0.2": - version: 1.0.2 - resolution: "source-map-js@npm:1.0.2" - checksum: 10/38e2d2dd18d2e331522001fc51b54127ef4a5d473f53b1349c5cca2123562400e0986648b52e9407e348eaaed53bce49248b6e2641e6d793ca57cb2c360d6d51 +"source-map-js@npm:^1.2.0": + version: 1.2.0 + resolution: "source-map-js@npm:1.2.0" + checksum: 10/74f331cfd2d121c50790c8dd6d3c9de6be21926de80583b23b37029b0f37aefc3e019fa91f9a10a5e120c08135297e1ecf312d561459c45908cb1e0e365f49e5 languageName: node linkType: hard @@ -8469,14 +8491,14 @@ __metadata: languageName: node linkType: hard -"vite@npm:^5.1.6": - version: 5.1.6 - resolution: "vite@npm:5.1.6" +"vite@npm:^5.2.2": + version: 5.2.2 + resolution: "vite@npm:5.2.2" dependencies: - esbuild: "npm:^0.19.3" + esbuild: "npm:^0.20.1" fsevents: "npm:~2.3.3" - postcss: "npm:^8.4.35" - rollup: "npm:^4.2.0" + postcss: "npm:^8.4.36" + rollup: "npm:^4.13.0" peerDependencies: "@types/node": ^18.0.0 || >=20.0.0 less: "*" @@ -8505,7 +8527,7 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 10/f48073e93ead62fa58034398442de4517c824b3e50184f8b4059fb24077a26f2c04e910e29d7fb7ec51ea53eb61b9c7d94d56b14a38851de80c67480094cc79d + checksum: 10/8e7f1e79e00a092b43378565898b5b60f66738d55fdcd2bb3a17b07183d32c3bfda30135490956ad8eb5eb77b0e56d4377655bf9478898616edbb20645477edb languageName: node linkType: hard diff --git a/mock-api/handler.ts b/mock-api/handler.ts index 38f310d5a..e0cacbe08 100644 --- a/mock-api/handler.ts +++ b/mock-api/handler.ts @@ -187,7 +187,7 @@ let ntp_settings = { tz_format: 'CET-1CEST,M3.5.0,M10.5.0/3' }; const ntp_status = { - status: 1, + status: 2, utc_time: '2021-04-01T14:25:42Z', local_time: '2021-04-01T16:25:42', server: 'time.google.com', @@ -316,7 +316,7 @@ const list_networks = { // OTA const OTA_SETTINGS_ENDPOINT = REST_ENDPOINT_ROOT + 'otaSettings'; let ota_settings = { - enabled: true, + enabled: false, port: 8266, password: 'ems-esp-neo' }; @@ -400,16 +400,20 @@ const ESPsystem_status = { arduino_version: 'ESP32 Arduino v2.0.14' }; +// TODO fix this const system_status = { emsesp_version: '3.6-demo', esp_platform: 'ESP32', status: 0, // status: 2, - tx_mode: 1, uptime: 77186, num_devices: 2, num_sensors: 1, - num_analogs: 1 + num_analogs: 1, + free_heap: 143, + ntp_status: 2, + ota_status: false, + mqtt_status: true }; let security_settings = {