diff --git a/interface/package.json b/interface/package.json index 3dfbd7dfb..e95c95621 100644 --- a/interface/package.json +++ b/interface/package.json @@ -22,13 +22,14 @@ "lint": "eslint . --fix" }, "dependencies": { - "@alova/adapter-xhr": "^2.0.4", + "@alova/adapter-xhr": "1.0.6", + "@alova/scene-react": "1.6.2", "@emotion/react": "^11.13.0", "@emotion/styled": "^11.13.0", "@mui/icons-material": "^5.16.7", "@mui/material": "^5.16.7", "@table-library/react-table-library": "4.1.7", - "alova": "^3.0.5", + "alova": "2.21.4", "async-validator": "^4.2.5", "jwt-decode": "^4.0.0", "mime-types": "^2.1.35", @@ -44,17 +45,17 @@ }, "devDependencies": { "@babel/core": "^7.25.2", - "@eslint/js": "^9.8.0", + "@eslint/js": "^9.9.0", "@preact/compat": "^17.1.2", "@preact/preset-vite": "^2.9.0", "@trivago/prettier-plugin-sort-imports": "^4.3.0", "@types/babel__core": "^7", - "@types/node": "^22.1.0", + "@types/node": "^22.2.0", "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", "@types/react-router-dom": "^5.3.3", "concurrently": "^8.2.2", - "eslint": "^9.8.0", + "eslint": "^9.9.0", "eslint-config-prettier": "^9.1.0", "prettier": "^3.3.3", "rollup-plugin-visualizer": "^5.12.0", diff --git a/interface/src/AppRouting.tsx b/interface/src/AppRouting.tsx index f7d6eac62..b8122c813 100644 --- a/interface/src/AppRouting.tsx +++ b/interface/src/AppRouting.tsx @@ -22,7 +22,7 @@ const RootRedirect = ({ message, signOut }: SecurityRedirectProps) => { return ; }; -export default function AppRouting() { +const AppRouting = () => { const { LL } = useI18nContext(); return ( @@ -55,4 +55,6 @@ export default function AppRouting() { ); -} +}; + +export default AppRouting; diff --git a/interface/src/SignIn.tsx b/interface/src/SignIn.tsx index 409cb36e2..9be23b693 100644 --- a/interface/src/SignIn.tsx +++ b/interface/src/SignIn.tsx @@ -5,7 +5,8 @@ import ForwardIcon from '@mui/icons-material/Forward'; import { Box, Button, Paper, Typography } from '@mui/material'; import * as AuthenticationApi from 'components/routing/authentication'; -import { useRequest } from 'alova/client'; +// import { useRequest } from 'alova/client' // TODO replace when Alova 3 is released +import { useRequest } from 'alova'; import type { ValidateFieldsError } from 'async-validator'; import { LanguageSelector, @@ -31,12 +32,26 @@ const SignIn = () => { const [processing, setProcessing] = useState(false); const [fieldErrors, setFieldErrors] = useState(); - const { send: callSignIn } = useRequest( + // TODO ALova 3 code... + // const { send: callSignIn } = useRequest( + // (request: SignInRequest) => AuthenticationApi.signIn(request), + // { + // immediate: false + // } + // ).onSuccess((response) => { + // if (response.data) { + // authenticationContext.signIn(response.data.access_token); + // } + // }); + + const { send: callSignIn, onSuccess } = useRequest( (request: SignInRequest) => AuthenticationApi.signIn(request), { immediate: false } - ).onSuccess((response) => { + ); + + onSuccess((response) => { if (response.data) { authenticationContext.signIn(response.data.access_token); } diff --git a/interface/src/api/app.ts b/interface/src/api/app.ts index 3e605e656..3d7228d6a 100644 --- a/interface/src/api/app.ts +++ b/interface/src/api/app.ts @@ -65,7 +65,8 @@ export const readDeviceEntities = (id: number) => alovaInstance.Get(`/rest/deviceEntities`, { params: { id }, responseType: 'arraybuffer', - transform(data) { + // transform(data) { // TODO alova 3 + transformData(data) { return (data as DeviceEntity[]).map((de: DeviceEntity) => ({ ...de, o_m: de.m, @@ -88,7 +89,8 @@ export const writeDeviceName = (data: { id: number; name: string }) => // SettingsScheduler export const readSchedule = () => alovaInstance.Get('/rest/schedule', { - transform(data) { + // transform(data) { // TODO alova 3 + transformData(data) { return (data as Schedule).schedule.map((si: ScheduleItem) => ({ ...si, o_id: si.id, @@ -108,7 +110,8 @@ export const writeSchedule = (data: Schedule) => // Modules export const readModules = () => alovaInstance.Get('/rest/modules', { - transform(data) { + // transform(data) { // TODO alova 3 + transformData(data) { return (data as Modules).modules.map((mi: ModuleItem) => ({ ...mi, o_enabled: mi.enabled, @@ -125,7 +128,8 @@ export const writeModules = (data: { // SettingsEntities export const readCustomEntities = () => alovaInstance.Get('/rest/customEntities', { - transform(data) { + // transform(data) { // TODO alova 3 + transformData(data) { return (data as Entities).entities.map((ei: EntityItem) => ({ ...ei, o_id: ei.id, diff --git a/interface/src/api/endpoints.ts b/interface/src/api/endpoints.ts index 6a8f1d412..e104f1ee6 100644 --- a/interface/src/api/endpoints.ts +++ b/interface/src/api/endpoints.ts @@ -8,25 +8,10 @@ export const ACCESS_TOKEN = 'access_token'; export const alovaInstance = createAlova({ statesHook: ReactHook, - cacheFor: null, - // TODO fix cache - // cacheFor: { - // // Set the cache mode for POST uniformly - // POST: { - // mode: 'restore', - // expire: 60 * 10 * 1000 - // }, - // // Set the cache mode for HEAD requests uniformly - // HEAD: 60 * 10 * 1000 - // }, - // timeout: 3000, // 3 seconds but throwing a timeout error - // localCache: null, - // localCache: { - // GET: { - // mode: 'placeholder', // see https://alova.js.org/learning/response-cache/#cache-replaceholder-mode - // expire: 2000 - // } - // }, + timeout: 3000, // 3 seconds but throwing a timeout error + localCache: null, + // TODO Alova v3 code... + // cacheFor: null, requestAdapter: xhrRequestAdapter(), beforeRequest(method) { if (localStorage.getItem(ACCESS_TOKEN)) { diff --git a/interface/src/api/system.ts b/interface/src/api/system.ts index beabe0125..963e7ca6d 100644 --- a/interface/src/api/system.ts +++ b/interface/src/api/system.ts @@ -24,15 +24,29 @@ export const fetchLog = () => alovaInstance.Post('/rest/fetchLog'); export const fetchLogES = () => alovaInstance.Get('/es/log'); // Get versions from github + +// Alova 3 code... +// export const getStableVersion = () => +// alovaInstanceGH.Get('latest', { +// transform(response: { data: { name: string } }) { +// return response.data.name.substring(1); +// } +// }); +// export const getDevVersion = () => +// alovaInstanceGH.Get('tags/latest', { +// transform(response: { data: { name: string } }) { +// return response.data.name.split(/\s+/).splice(-1)[0].substring(1); +// } +// }); export const getStableVersion = () => alovaInstanceGH.Get('latest', { - transform(response: { data: { name: string } }) { + transformData(response: { data: { name: string } }) { return response.data.name.substring(1); } }); export const getDevVersion = () => alovaInstanceGH.Get('tags/latest', { - transform(response: { data: { name: string } }) { + transformData(response: { data: { name: string } }) { return response.data.name.split(/\s+/).splice(-1)[0].substring(1); } }); diff --git a/interface/src/app/main/CustomEntities.tsx b/interface/src/app/main/CustomEntities.tsx index bbaaa0903..b3000f3f4 100644 --- a/interface/src/app/main/CustomEntities.tsx +++ b/interface/src/app/main/CustomEntities.tsx @@ -19,7 +19,8 @@ import { Table } from '@table-library/react-table-library/table'; import { useTheme } from '@table-library/react-table-library/theme'; -import { updateState, useRequest } from 'alova/client'; +import { updateState, useRequest } from 'alova'; +// import { updateState, useRequest } from 'alova/client'; // TODO replace when Alova 3 is released import { BlockNavigation, ButtonRow, diff --git a/interface/src/app/main/Customizations.tsx b/interface/src/app/main/Customizations.tsx index 5dc5214bc..7c68e60b4 100644 --- a/interface/src/app/main/Customizations.tsx +++ b/interface/src/app/main/Customizations.tsx @@ -39,7 +39,8 @@ import { } from '@table-library/react-table-library/table'; import { useTheme } from '@table-library/react-table-library/theme'; import { dialogStyle } from 'CustomTheme'; -import { useRequest } from 'alova/client'; +import { useRequest } from 'alova'; +// import { useRequest } from 'alova/client' // TODO replace when Alova 3 is released import RestartMonitor from 'app/status/RestartMonitor'; import { BlockNavigation, @@ -110,13 +111,25 @@ const Customizations = () => { } ); - const { send: sendDeviceEntities } = useRequest( + // TODO Alova 3 code... + // const { send: sendDeviceEntities } = useRequest( + // (data: number) => readDeviceEntities(data), + // { + // initialData: [], + // immediate: false + // } + // ).onSuccess((event) => { + // setOriginalSettings(event.data); + // }); + + const { send: sendDeviceEntities, onSuccess } = useRequest( (data: number) => readDeviceEntities(data), { initialData: [], immediate: false } - ).onSuccess((event) => { + ); + onSuccess((event) => { setOriginalSettings(event.data); }); diff --git a/interface/src/app/main/DeviceIcon.tsx b/interface/src/app/main/DeviceIcon.tsx index b4813ff45..a9429b67c 100644 --- a/interface/src/app/main/DeviceIcon.tsx +++ b/interface/src/app/main/DeviceIcon.tsx @@ -15,8 +15,8 @@ import PlaylistAddIcon from '@mui/icons-material/PlaylistAdd'; import { DeviceType } from './types'; -export default function DeviceIcon({ type_id }) { - switch (type_id as DeviceType) { +const DeviceIcon = ({ type_id }: { type_id: DeviceType }) => { + switch (type_id) { case DeviceType.TEMPERATURESENSOR: case DeviceType.ANALOGSENSOR: return ; @@ -55,4 +55,6 @@ export default function DeviceIcon({ type_id }) { default: return null; } -} +}; + +export default DeviceIcon; diff --git a/interface/src/app/main/Devices.tsx b/interface/src/app/main/Devices.tsx index 4d13c09ed..3cfeb7bc7 100644 --- a/interface/src/app/main/Devices.tsx +++ b/interface/src/app/main/Devices.tsx @@ -56,7 +56,8 @@ import { import { useTheme } from '@table-library/react-table-library/theme'; import type { Action, State } from '@table-library/react-table-library/types/common'; import { dialogStyle } from 'CustomTheme'; -import { useRequest } from 'alova/client'; +// import { useRequest } from 'alova/client' // TODO replace when Alova 3 is released +import { useRequest } from 'alova'; import { ButtonRow, MessageBox, SectionContent, useLayoutTitle } from 'components'; import { AuthenticatedContext } from 'contexts/authentication'; import { useI18nContext } from 'i18n/i18n-react'; diff --git a/interface/src/app/main/Help.tsx b/interface/src/app/main/Help.tsx index 4ac0eb1ae..843335ef5 100644 --- a/interface/src/app/main/Help.tsx +++ b/interface/src/app/main/Help.tsx @@ -17,9 +17,8 @@ import { Typography } from '@mui/material'; -import { readSystemStatus } from 'api/system'; - -import { useRequest } from 'alova/client'; +// import { useRequest } from 'alova/client' // TODO replace when Alova 3 is released +import { useRequest } from 'alova'; import { SectionContent, useLayoutTitle } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; @@ -30,24 +29,43 @@ const Help = () => { const { LL } = useI18nContext(); useLayoutTitle(LL.HELP_OF('')); - const { send: getAPI } = useRequest((data: APIcall) => API(data), { - immediate: false - }).onSuccess((event) => { + const { send: getAPI, onSuccess: onGetAPI } = useRequest( + (data: APIcall) => API(data), + { + immediate: false + } + ); + onGetAPI((event) => { const anchor = document.createElement('a'); anchor.href = URL.createObjectURL( new Blob([JSON.stringify(event.data, null, 2)], { type: 'text/plain' }) ); - anchor.download = - 'emsesp_' + event.args[0].device + '_' + event.args[0].entity + '.txt'; + 'emsesp_' + event.sendArgs[0].device + '_' + event.sendArgs[0].entity + '.txt'; anchor.click(); URL.revokeObjectURL(anchor.href); toast.info(LL.DOWNLOAD_SUCCESSFUL()); }); - const { data, loading } = useRequest(readSystemStatus); + // Alova 3 code... + // const { send: getAPI } = useRequest((data: APIcall) => API(data), { + // immediate: false + // }).onSuccess((event) => { + // const anchor = document.createElement('a'); + // anchor.href = URL.createObjectURL( + // new Blob([JSON.stringify(event.data, null, 2)], { + // type: 'text/plain' + // }) + // ); + // + // anchor.download = + // 'emsesp_' + event.args[0].device + '_' + event.args[0].entity + '.txt'; + // anchor.click(); + // URL.revokeObjectURL(anchor.href); + // toast.info(LL.DOWNLOAD_SUCCESSFUL()); + // }); const callAPI = async (device: string, entity: string) => { await getAPI({ device, entity, id: 0 }).catch((error: Error) => { @@ -55,15 +73,8 @@ const Help = () => { }); }; - // TODO remove debug testing useRequest preact hook - console.log('loading: ' + loading + ' data2: ' + data); - if (loading) { - return
Loading...
; - } - return ( <> -
version is {data.emsesp_version}
diff --git a/interface/src/app/main/Modules.tsx b/interface/src/app/main/Modules.tsx index cb366715f..8fba532c6 100644 --- a/interface/src/app/main/Modules.tsx +++ b/interface/src/app/main/Modules.tsx @@ -17,7 +17,8 @@ import { Table } from '@table-library/react-table-library/table'; import { useTheme } from '@table-library/react-table-library/theme'; -import { updateState, useRequest } from 'alova/client'; +import { updateState, useRequest } from 'alova'; +// import { updateState, useRequest } from 'alova/client'; // TODO replace when Alova 3 is released import { BlockNavigation, ButtonRow, diff --git a/interface/src/app/main/OptionIcon.tsx b/interface/src/app/main/OptionIcon.tsx index b40e96d78..5cf08d542 100644 --- a/interface/src/app/main/OptionIcon.tsx +++ b/interface/src/app/main/OptionIcon.tsx @@ -30,11 +30,13 @@ const OPTION_ICONS: { favorite: [StarIcon, StarOutlineIcon] }; -export default function OptionIcon({ type, isSet }) { +const OptionIcon = ({ type, isSet }: { type: OptionType; isSet: boolean }) => { const Icon = OPTION_ICONS[type][isSet ? 0 : 1]; return isSet ? ( ) : ( ); -} +}; + +export default OptionIcon; diff --git a/interface/src/app/main/Scheduler.tsx b/interface/src/app/main/Scheduler.tsx index b2a526560..1594beaf4 100644 --- a/interface/src/app/main/Scheduler.tsx +++ b/interface/src/app/main/Scheduler.tsx @@ -18,7 +18,8 @@ import { Table } from '@table-library/react-table-library/table'; import { useTheme } from '@table-library/react-table-library/theme'; -import { updateState, useRequest } from 'alova/client'; +// import { updateState, useRequest } from 'alova/client'; // TODO replace when Alova 3 is released +import { updateState, useRequest } from 'alova'; import { BlockNavigation, ButtonRow, diff --git a/interface/src/app/main/Sensors.tsx b/interface/src/app/main/Sensors.tsx index 58cdd02c6..cc19b6e90 100644 --- a/interface/src/app/main/Sensors.tsx +++ b/interface/src/app/main/Sensors.tsx @@ -20,7 +20,8 @@ import { } from '@table-library/react-table-library/table'; import { useTheme } from '@table-library/react-table-library/theme'; import type { State } from '@table-library/react-table-library/types/common'; -import { useRequest } from 'alova/client'; +// import { useRequest } from 'alova/client' // TODO replace when Alova 3 is released +import { useRequest } from 'alova'; import { ButtonRow, SectionContent, useLayoutTitle } from 'components'; import { AuthenticatedContext } from 'contexts/authentication'; import { useI18nContext } from 'i18n/i18n-react'; diff --git a/interface/src/app/settings/ApplicationSettings.tsx b/interface/src/app/settings/ApplicationSettings.tsx index b2b4f7b3d..1e5b4766b 100644 --- a/interface/src/app/settings/ApplicationSettings.tsx +++ b/interface/src/app/settings/ApplicationSettings.tsx @@ -18,7 +18,8 @@ import { import { readHardwareStatus, restart } from 'api/system'; -import { useRequest } from 'alova/client'; +// import { useRequest } from 'alova/client' // TODO replace when Alova 3 is released +import { useRequest } from 'alova'; import RestartMonitor from 'app/status/RestartMonitor'; import type { ValidateFieldsError } from 'async-validator'; import { @@ -49,9 +50,7 @@ export function boardProfileSelectItems() { } const ApplicationSettings = () => { - const { data: hardwareData } = useRequest(readHardwareStatus, { - initialData: { psram: false } - }); + const { data: hardwareData } = useRequest(readHardwareStatus); const { loadData, @@ -83,12 +82,15 @@ const ApplicationSettings = () => { const [fieldErrors, setFieldErrors] = useState(); - const { loading: processingBoard, send: readBoardProfile } = useRequest( - (boardProfile: string) => getBoardProfile(boardProfile), - { - immediate: false - } - ).onSuccess((event) => { + const { + loading: processingBoard, + send: readBoardProfile, + onSuccess: onSuccessBoardProfile + } = useRequest((boardProfile: string) => getBoardProfile(boardProfile), { + immediate: false + }); + + onSuccessBoardProfile((event) => { const response = event.data as Settings; updateDataValue({ ...data, @@ -105,6 +107,29 @@ const ApplicationSettings = () => { }); }); + // TODO replace with Alova 3 + // const { loading: processingBoard, send: readBoardProfile } = useRequest( + // (boardProfile: string) => getBoardProfile(boardProfile), + // { + // immediate: false + // } + // ).onSuccess((event) => { + // const response = event.data as Settings; + // updateDataValue({ + // ...data, + // board_profile: response.board_profile, + // led_gpio: response.led_gpio, + // dallas_gpio: response.dallas_gpio, + // rx_gpio: response.rx_gpio, + // tx_gpio: response.tx_gpio, + // pbutton_gpio: response.pbutton_gpio, + // phy_type: response.phy_type, + // eth_power: response.eth_power, + // eth_phy_addr: response.eth_phy_addr, + // eth_clock_mode: response.eth_clock_mode + // }); + // }); + const { send: restartCommand } = useRequest(restart(), { immediate: false }); @@ -118,7 +143,7 @@ const ApplicationSettings = () => { useLayoutTitle(LL.SETTINGS_OF(LL.APPLICATION())); const content = () => { - if (!data) { + if (!data || !hardwareData) { return ; } diff --git a/interface/src/app/settings/NTPSettings.tsx b/interface/src/app/settings/NTPSettings.tsx index 9843ccc0d..aa16dd486 100644 --- a/interface/src/app/settings/NTPSettings.tsx +++ b/interface/src/app/settings/NTPSettings.tsx @@ -7,7 +7,8 @@ import { Button, Checkbox, MenuItem } from '@mui/material'; import * as NTPApi from 'api/ntp'; import { readNTPSettings } from 'api/ntp'; -import { updateState } from 'alova/client'; +// import { updateState } from 'alova/client'; // TODO replace when Alova 3 is released +import { updateState } from 'alova'; import type { ValidateFieldsError } from 'async-validator'; import { BlockFormControlLabel, diff --git a/interface/src/app/settings/Settings.tsx b/interface/src/app/settings/Settings.tsx index 2ccb1b4e6..e5fc5f7ef 100644 --- a/interface/src/app/settings/Settings.tsx +++ b/interface/src/app/settings/Settings.tsx @@ -24,7 +24,8 @@ import { import * as SystemApi from 'api/system'; import { dialogStyle } from 'CustomTheme'; -import { useRequest } from 'alova/client'; +// import { useRequest } from 'alova/client' // TODO replace when Alova 3 is released +import { useRequest } from 'alova'; import { SectionContent, useLayoutTitle } from 'components'; import ListMenuItem from 'components/layout/ListMenuItem'; import { useI18nContext } from 'i18n/i18n-react'; diff --git a/interface/src/app/settings/UploadDownload.tsx b/interface/src/app/settings/UploadDownload.tsx index 75cf120c8..9ee2e0b34 100644 --- a/interface/src/app/settings/UploadDownload.tsx +++ b/interface/src/app/settings/UploadDownload.tsx @@ -14,7 +14,8 @@ import { } from 'api/app'; import { getDevVersion, getStableVersion } from 'api/system'; -import { useRequest } from 'alova/client'; +// import { useRequest } from 'alova/client' // TODO replace when Alova 3 is released +import { useRequest } from 'alova'; import type { APIcall } from 'app/main/types'; import { FormLoader, @@ -31,6 +32,92 @@ const UploadDownload = () => { const [restarting, setRestarting] = useState(); const [md5, setMd5] = useState(); + const { send: sendSettings, onSuccess: onSuccessGetSettings } = useRequest( + getSettings(), + { + immediate: false + } + ); + const { send: sendCustomizations, onSuccess: onSuccessGetCustomizations } = + useRequest(getCustomizations(), { + immediate: false + }); + const { send: sendEntities, onSuccess: onSuccessGetEntities } = useRequest( + getEntities(), + { + immediate: false + } + ); + const { send: sendSchedule, onSuccess: onSuccessGetSchedule } = useRequest( + getSchedule(), + { + immediate: false + } + ); + const { send: getAPI, onSuccess: onGetAPI } = useRequest( + (data: APIcall) => API(data), + { + immediate: false + } + ); + + // Alova 3 code... + // const { + // loading: isUploading, + // uploading: progress, + // send: sendUpload, + // abort: cancelUpload + // } = useRequest(SystemApi.uploadFile, { + // immediate: false + // }).onSuccess(({ data }) => { + // if (data) { + // setMd5(data.md5); + // toast.success(LL.UPLOAD() + ' MD5 ' + LL.SUCCESSFUL()); + // } else { + // setRestarting(true); + // } + // }); + const { + loading: isUploading, + uploading: progress, + send: sendUpload, + onSuccess: onSuccessUpload, + abort: cancelUpload + } = useRequest(SystemApi.uploadFile, { + immediate: false + }); + + onSuccessUpload(({ data }) => { + if (data) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument + setMd5(data.md5); + toast.success(LL.UPLOAD() + ' MD5 ' + LL.SUCCESSFUL()); + } else { + setRestarting(true); + } + }); + onSuccessGetSettings((event) => { + saveFile(event.data, 'settings.json'); + }); + onSuccessGetCustomizations((event) => { + saveFile(event.data, 'customizations.json'); + }); + onSuccessGetEntities((event) => { + saveFile(event.data, 'entities.json'); + }); + onSuccessGetSchedule((event) => { + saveFile(event.data, 'schedule.json'); + }); + onGetAPI((event) => { + saveFile( + event.data, + event.sendArgs[0].device + '_' + event.sendArgs[0].entity + '.txt' + ); + }); + + // TODO Alova 3 code... + /* + const { send: sendSettings } = useRequest(getSettings(), { immediate: false }).onSuccess((event) => { @@ -64,6 +151,8 @@ const UploadDownload = () => { ); }); + */ + const { data: data, send: loadData, @@ -96,22 +185,6 @@ const UploadDownload = () => { return data.esp_platform; }; - const { - loading: isUploading, - uploading: progress, - send: sendUpload, - abort: cancelUpload - } = useRequest(SystemApi.uploadFile, { - immediate: false - }).onSuccess(({ data }) => { - if (data) { - setMd5(data.md5); - toast.success(LL.UPLOAD() + ' MD5 ' + LL.SUCCESSFUL()); - } else { - setRestarting(true); - } - }); - const startUpload = async (files: File[]) => { await sendUpload(files[0]).catch((error: Error) => { if (error.message === 'The user aborted a request') { diff --git a/interface/src/app/settings/network/NetworkSettings.tsx b/interface/src/app/settings/network/NetworkSettings.tsx index 4fc22b358..c0e8b459e 100644 --- a/interface/src/app/settings/network/NetworkSettings.tsx +++ b/interface/src/app/settings/network/NetworkSettings.tsx @@ -25,7 +25,8 @@ import { import * as NetworkApi from 'api/network'; import * as SystemApi from 'api/system'; -import { updateState, useRequest } from 'alova/client'; +import { updateState, useRequest } from 'alova'; +// import { updateState, useRequest } from 'alova/client'; // TODO replace when Alova 3 is released import type { ValidateFieldsError } from 'async-validator'; import { BlockFormControlLabel, diff --git a/interface/src/app/settings/network/WiFiNetworkScanner.tsx b/interface/src/app/settings/network/WiFiNetworkScanner.tsx index a73cdea7a..cff76dc9a 100644 --- a/interface/src/app/settings/network/WiFiNetworkScanner.tsx +++ b/interface/src/app/settings/network/WiFiNetworkScanner.tsx @@ -5,7 +5,8 @@ import { Button } from '@mui/material'; import * as NetworkApi from 'api/network'; -import { updateState, useRequest } from 'alova/client'; +// import { updateState, useRequest } from 'alova/client'; // TODO replace when Alova 3 is released +import { updateState, useRequest } from 'alova'; import { ButtonRow, FormLoader, SectionContent } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; @@ -20,22 +21,18 @@ const WiFiNetworkScanner = () => { const [errorMessage, setErrorMessage] = useState(); // is called on page load to start network scan - const { send: scanNetworks } = useRequest(NetworkApi.scanNetworks).onComplete( - () => { - pollCount.current = 0; - setErrorMessage(undefined); - void updateState(NetworkApi.listNetworks(), () => undefined); - void getNetworkList(); - } - ); - const { data: networkList, send: getNetworkList } = useRequest( - NetworkApi.listNetworks, - { - immediate: false - } - ).onSuccess((event) => { - // is called when network scan is completed + const { send: scanNetworks, onComplete: onCompleteScanNetworks } = useRequest( + NetworkApi.scanNetworks + ); + const { + data: networkList, + send: getNetworkList, + onSuccess: onSuccessNetworkList + } = useRequest(NetworkApi.listNetworks, { + immediate: false + }); + onSuccessNetworkList((event) => { if (!event.data) { const completedPollCount = pollCount.current + 1; if (completedPollCount < NUM_POLLS) { @@ -48,6 +45,42 @@ const WiFiNetworkScanner = () => { } }); + onCompleteScanNetworks(() => { + pollCount.current = 0; + setErrorMessage(undefined); + updateState('listNetworks', () => undefined); + void getNetworkList(); + }); + + // Alova 3 code... + // const { send: scanNetworks } = useRequest(NetworkApi.scanNetworks).onComplete( + // () => { + // pollCount.current = 0; + // setErrorMessage(undefined); + // void updateState(NetworkApi.listNetworks(), () => undefined); + // void getNetworkList(); + // } + // ); + + // const { data: networkList, send: getNetworkList } = useRequest( + // NetworkApi.listNetworks, + // { + // immediate: false + // } + // ).onSuccess((event) => { + // // is called when network scan is completed + // if (!event.data) { + // const completedPollCount = pollCount.current + 1; + // if (completedPollCount < NUM_POLLS) { + // pollCount.current = completedPollCount; + // setTimeout(getNetworkList, POLLING_FREQUENCY); + // } else { + // setErrorMessage(LL.PROBLEM_LOADING()); + // pollCount.current = 0; + // } + // } + // }); + const renderNetworkScanner = () => { if (!networkList) { return ( diff --git a/interface/src/app/settings/network/WiFiNetworkSelector.tsx b/interface/src/app/settings/network/WiFiNetworkSelector.tsx index 974c81c3d..f003ecd38 100644 --- a/interface/src/app/settings/network/WiFiNetworkSelector.tsx +++ b/interface/src/app/settings/network/WiFiNetworkSelector.tsx @@ -17,7 +17,7 @@ import type { Theme } from '@mui/material'; import { MessageBox } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; -import type { WiFiNetwork } from 'types'; +import type { WiFiNetwork, WiFiNetworkList } from 'types'; import { WiFiEncryptionType } from 'types'; import { WiFiConnectionContext } from './WiFiConnectionContext'; @@ -57,7 +57,7 @@ const networkQualityHighlight = ({ rssi }: WiFiNetwork, theme: Theme) => { return theme.palette.success.main; }; -function WiFiNetworkSelector({ networkList }) { +const WiFiNetworkSelector = ({ networkList }: { networkList: WiFiNetworkList }) => { const { LL } = useI18nContext(); const theme = useTheme(); @@ -95,6 +95,6 @@ function WiFiNetworkSelector({ networkList }) { } return {networkList.networks.map(renderNetwork)}; -} +}; export default WiFiNetworkSelector; diff --git a/interface/src/app/settings/security/GenerateToken.tsx b/interface/src/app/settings/security/GenerateToken.tsx index f0bdcea50..b0292a4a5 100644 --- a/interface/src/app/settings/security/GenerateToken.tsx +++ b/interface/src/app/settings/security/GenerateToken.tsx @@ -16,11 +16,17 @@ import { import * as SecurityApi from 'api/security'; import { dialogStyle } from 'CustomTheme'; -import { useRequest } from 'alova/client'; +// import { useRequest } from 'alova/client' // TODO replace when Alova 3 is released +import { useRequest } from 'alova'; import { MessageBox } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; -export default function GenerateToken({ username, onClose }) { +interface GenerateTokenProps { + username?: string; + onClose: () => void; +} + +const GenerateToken = ({ username, onClose }: GenerateTokenProps) => { const { LL } = useI18nContext(); const open = !!username; @@ -79,4 +85,6 @@ export default function GenerateToken({ username, onClose }) { ); -} +}; + +export default GenerateToken; diff --git a/interface/src/app/status/APStatus.tsx b/interface/src/app/status/APStatus.tsx index 44aa25e2e..ebdd61bdd 100644 --- a/interface/src/app/status/APStatus.tsx +++ b/interface/src/app/status/APStatus.tsx @@ -16,7 +16,8 @@ import type { Theme } from '@mui/material'; import * as APApi from 'api/ap'; -import { useRequest } from 'alova/client'; +// import { useRequest } from 'alova/client' // TODO replace when Alova 3 is released +import { useRequest } from 'alova'; import { ButtonRow, FormLoader, SectionContent, useLayoutTitle } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; import type { APStatusType } from 'types'; diff --git a/interface/src/app/status/Activity.tsx b/interface/src/app/status/Activity.tsx index ae43f3d51..993af9d3a 100644 --- a/interface/src/app/status/Activity.tsx +++ b/interface/src/app/status/Activity.tsx @@ -13,7 +13,8 @@ import { Table } from '@table-library/react-table-library/table'; import { useTheme as tableTheme } from '@table-library/react-table-library/theme'; -import { useRequest } from 'alova/client'; +// import { useRequest } from 'alova/client' // TODO replace when Alova 3 is released +import { useRequest } from 'alova'; import { ButtonRow, FormLoader, SectionContent, useLayoutTitle } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; import type { Translation } from 'i18n/i18n-types'; diff --git a/interface/src/app/status/HardwareStatus.tsx b/interface/src/app/status/HardwareStatus.tsx index 32c440d5f..6818abc58 100644 --- a/interface/src/app/status/HardwareStatus.tsx +++ b/interface/src/app/status/HardwareStatus.tsx @@ -20,7 +20,8 @@ import { import * as SystemApi from 'api/system'; -import { useRequest } from 'alova/client'; +// import { useRequest } from 'alova/client' // TODO replace when Alova 3 is released +import { useRequest } from 'alova'; import { ButtonRow, FormLoader, SectionContent, useLayoutTitle } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; diff --git a/interface/src/app/status/MqttStatus.tsx b/interface/src/app/status/MqttStatus.tsx index 462d17130..1af738f54 100644 --- a/interface/src/app/status/MqttStatus.tsx +++ b/interface/src/app/status/MqttStatus.tsx @@ -17,7 +17,8 @@ import type { Theme } from '@mui/material'; import * as MqttApi from 'api/mqtt'; -import { useRequest } from 'alova/client'; +// import { useRequest } from 'alova/client' // TODO replace when Alova 3 is released +import { useRequest } from 'alova'; import { ButtonRow, FormLoader, SectionContent, useLayoutTitle } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; import type { MqttStatusType } from 'types'; diff --git a/interface/src/app/status/NTPStatus.tsx b/interface/src/app/status/NTPStatus.tsx index 13b7841fe..3375dc073 100644 --- a/interface/src/app/status/NTPStatus.tsx +++ b/interface/src/app/status/NTPStatus.tsx @@ -29,7 +29,8 @@ import type { Theme } from '@mui/material'; import * as NTPApi from 'api/ntp'; import { dialogStyle } from 'CustomTheme'; -import { useRequest } from 'alova/client'; +// import { useRequest } from 'alova/client' // TODO replace when Alova 3 is released +import { useRequest } from 'alova'; import { ButtonRow, FormLoader, SectionContent, useLayoutTitle } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; import type { NTPStatusType, Time } from 'types'; diff --git a/interface/src/app/status/NetworkStatus.tsx b/interface/src/app/status/NetworkStatus.tsx index 201193cb2..48a29f378 100644 --- a/interface/src/app/status/NetworkStatus.tsx +++ b/interface/src/app/status/NetworkStatus.tsx @@ -20,7 +20,8 @@ import type { Theme } from '@mui/material'; import * as NetworkApi from 'api/network'; -import { useRequest } from 'alova/client'; +// import { useRequest } from 'alova/client' // TODO replace when Alova 3 is released +import { useRequest } from 'alova'; import { ButtonRow, FormLoader, SectionContent, useLayoutTitle } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; import type { NetworkStatusType } from 'types'; diff --git a/interface/src/app/status/RestartMonitor.tsx b/interface/src/app/status/RestartMonitor.tsx index a8cb12774..7c59dcf87 100644 --- a/interface/src/app/status/RestartMonitor.tsx +++ b/interface/src/app/status/RestartMonitor.tsx @@ -2,7 +2,8 @@ import { useEffect, useRef, useState } from 'react'; import * as SystemApi from 'api/system'; -import { useRequest } from 'alova/client'; +// import { useRequest } from 'alova/client' // TODO replace when Alova 3 is released +import { useRequest } from 'alova'; import { FormLoader } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; diff --git a/interface/src/app/status/Status.tsx b/interface/src/app/status/Status.tsx index 10ad173e8..2de7361e8 100644 --- a/interface/src/app/status/Status.tsx +++ b/interface/src/app/status/Status.tsx @@ -34,7 +34,8 @@ import { import * as SystemApi from 'api/system'; import { dialogStyle } from 'CustomTheme'; -import { useRequest } from 'alova/client'; +// import { useRequest } from 'alova/client' // TODO replace when Alova 3 is released +import { useRequest } from 'alova'; import { busConnectionStatus } from 'app/main/types'; import { FormLoader, SectionContent, useLayoutTitle } from 'components'; import ListMenuItem from 'components/layout/ListMenuItem'; @@ -67,8 +68,8 @@ const SystemStatus = () => { const { data: data, - loading, - send: loadData + send: loadData, + error } = useRequest(SystemApi.readSystemStatus, { initialData: [] }); @@ -272,11 +273,6 @@ const SystemStatus = () => { ); const content = () => { - // TODO remove test code - if (loading) { - return <>not loaded!; - } - if (!data) { return ; } diff --git a/interface/src/app/status/SystemLog.tsx b/interface/src/app/status/SystemLog.tsx index 32d649e6e..71e92e8a5 100644 --- a/interface/src/app/status/SystemLog.tsx +++ b/interface/src/app/status/SystemLog.tsx @@ -16,7 +16,9 @@ import { import * as SystemApi from 'api/system'; import { fetchLogES } from 'api/system'; -import { useRequest, useSSE } from 'alova/client'; +// import { useRequest, useSSE } from 'alova/client'; // TODO replace when Alova 3 is released +import { useSSE } from '@alova/scene-react'; +import { useRequest } from 'alova'; import { BlockFormControlLabel, BlockNavigation, diff --git a/interface/src/components/layout/LayoutAppBar.tsx b/interface/src/components/layout/LayoutAppBar.tsx index 46de4aa7d..c8f31ee0c 100644 --- a/interface/src/components/layout/LayoutAppBar.tsx +++ b/interface/src/components/layout/LayoutAppBar.tsx @@ -6,7 +6,12 @@ import { AppBar, IconButton, Toolbar, Typography } from '@mui/material'; export const DRAWER_WIDTH = 210; -export default function LayoutAppBar({ title, onToggleDrawer }) { +interface LayoutAppBarProps { + title: string; + onToggleDrawer: () => void; +} + +const LayoutAppBar = ({ title, onToggleDrawer }: LayoutAppBarProps) => { const pathnames = useLocation() .pathname.split('/') .filter((x) => x); @@ -50,4 +55,6 @@ export default function LayoutAppBar({ title, onToggleDrawer }) { ); -} +}; + +export default LayoutAppBar; diff --git a/interface/src/components/layout/LayoutDrawer.tsx b/interface/src/components/layout/LayoutDrawer.tsx index 2bdf4d735..320208129 100644 --- a/interface/src/components/layout/LayoutDrawer.tsx +++ b/interface/src/components/layout/LayoutDrawer.tsx @@ -16,7 +16,12 @@ const LayoutDrawerLogo = styled('img')(({ theme }) => ({ } })); -export default function LayoutDrawerProps({ mobileOpen, onClose }) { +interface LayoutDrawerProps { + mobileOpen: boolean; + onClose: () => void; +} + +const LayoutDrawerProps = ({ mobileOpen, onClose }: LayoutDrawerProps) => { const drawer = ( <> @@ -59,4 +64,6 @@ export default function LayoutDrawerProps({ mobileOpen, onClose }) { ); -} +}; + +export default LayoutDrawerProps; diff --git a/interface/src/components/routing/BlockNavigation.tsx b/interface/src/components/routing/BlockNavigation.tsx index d75683061..1c56c8448 100644 --- a/interface/src/components/routing/BlockNavigation.tsx +++ b/interface/src/components/routing/BlockNavigation.tsx @@ -1,3 +1,5 @@ +import type { Blocker } from 'react-router-dom'; + import { Button, Dialog, @@ -9,7 +11,7 @@ import { import { dialogStyle } from 'CustomTheme'; import { useI18nContext } from 'i18n/i18n-react'; -export default function BlockNavigation({ blocker }) { +const BlockNavigation = ({ blocker }: { blocker: Blocker }) => { const { LL } = useI18nContext(); return ( @@ -34,4 +36,6 @@ export default function BlockNavigation({ blocker }) { ); -} +}; + +export default BlockNavigation; diff --git a/interface/src/contexts/authentication/Authentication.tsx b/interface/src/contexts/authentication/Authentication.tsx index ce182c814..e49fb7562 100644 --- a/interface/src/contexts/authentication/Authentication.tsx +++ b/interface/src/contexts/authentication/Authentication.tsx @@ -6,7 +6,8 @@ import { toast } from 'react-toastify'; import { ACCESS_TOKEN } from 'api/endpoints'; import * as AuthenticationApi from 'components/routing/authentication'; -import { useRequest } from 'alova/client'; +// import { useRequest } from 'alova/client' // TODO replace when Alova 3 is released +import { useRequest } from 'alova'; import { LoadingSpinner } from 'components'; import { verifyAuthorization } from 'components/routing/authentication'; import { useI18nContext } from 'i18n/i18n-react'; diff --git a/interface/src/utils/useRest.ts b/interface/src/utils/useRest.ts index fac7acaed..183f5ee48 100644 --- a/interface/src/utils/useRest.ts +++ b/interface/src/utils/useRest.ts @@ -1,14 +1,90 @@ +// TODO Alova 3 code.... +// import { useState } from 'react'; +// import { useBlocker } from 'react-router-dom'; +// import { toast } from 'react-toastify'; +// import type { AlovaGenerics, Method } from 'alova'; +// import { useRequest } from 'alova/client'; +// import { useI18nContext } from 'i18n/i18n-react'; +// export interface RestRequestOptions { +// read: () => Method; +// update: (value: D) => Method; +// } +// export const useRest = ({ read, update }: RestRequestOptions) => { +// const { LL } = useI18nContext(); +// const [errorMessage, setErrorMessage] = useState(); +// const [restartNeeded, setRestartNeeded] = useState(false); +// const [origData, setOrigData] = useState(); +// const [dirtyFlags, setDirtyFlags] = useState([]); +// const blocker = useBlocker(dirtyFlags.length !== 0); +// const { +// data, +// send: readData, +// update: updateData +// } = useRequest(read()).onComplete((event) => { +// setOrigData(event.data as D); +// }); +// const { loading: saving, send: writeData } = useRequest( +// (newData: D) => update(newData), +// { immediate: false } +// ).onSuccess(() => { +// toast.success(LL.UPDATED_OF(LL.SETTINGS(1))); +// setDirtyFlags([]); +// }); +// const updateDataValue = (new_data: D) => { +// updateData({ data: new_data }); +// }; +// const loadData = async () => { +// setDirtyFlags([]); +// setErrorMessage(undefined); +// await readData().catch((error: Error) => { +// toast.error(error.message); +// setErrorMessage(error.message); +// }); +// }; +// const saveData = async () => { +// if (!data) { +// return; +// } +// setRestartNeeded(false); +// setErrorMessage(undefined); +// setDirtyFlags([]); +// setOrigData(data as D); +// await writeData(data as D).catch((error: Error) => { +// if (error.message === 'Reboot required') { +// setRestartNeeded(true); +// } else { +// toast.error(error.message); +// setErrorMessage(error.message); +// } +// }); +// }; +// return { +// loadData, +// saveData, +// saving: saving as boolean, +// updateDataValue, +// data: data as D, // Explicitly define the type of 'data' +// origData: origData as D, // Explicitly define the type of 'origData' to 'D' +// dirtyFlags, +// setDirtyFlags, +// setOrigData, +// blocker, +// errorMessage, +// restartNeeded +// } as const; +// }; import { useState } from 'react'; import { useBlocker } from 'react-router-dom'; import { toast } from 'react-toastify'; -import type { AlovaGenerics, Method } from 'alova'; -import { useRequest } from 'alova/client'; +import { type Method, useRequest } from 'alova'; import { useI18nContext } from 'i18n/i18n-react'; export interface RestRequestOptions { - read: () => Method; - update: (value: D) => Method; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + read: () => Method; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + update: (value: D) => Method; } export const useRest = ({ read, update }: RestRequestOptions) => { @@ -24,23 +100,29 @@ export const useRest = ({ read, update }: RestRequestOptions) => { const { data, send: readData, - update: updateData - } = useRequest(read()).onComplete((event) => { - setOrigData(event.data as D); - }); + update: updateData, + onComplete: onReadComplete + } = useRequest(read()); - const { loading: saving, send: writeData } = useRequest( - (newData: D) => update(newData), - { immediate: false } - ).onSuccess(() => { - toast.success(LL.UPDATED_OF(LL.SETTINGS(1))); - setDirtyFlags([]); - }); + const { + loading: saving, + send: writeData, + onSuccess: onWriteSuccess + } = useRequest((newData: D) => update(newData), { immediate: false }); const updateDataValue = (new_data: D) => { updateData({ data: new_data }); }; + onWriteSuccess(() => { + toast.success(LL.UPDATED_OF(LL.SETTINGS(1))); + setDirtyFlags([]); + }); + + onReadComplete((event) => { + setOrigData(event.data as D); + }); + const loadData = async () => { setDirtyFlags([]); setErrorMessage(undefined); diff --git a/interface/yarn.lock b/interface/yarn.lock index 8cad5c47a..c3cd78222 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -5,21 +5,17 @@ __metadata: version: 8 cacheKey: 10c0 -"@alova/adapter-xhr@npm:^2.0.4": - version: 2.0.4 - resolution: "@alova/adapter-xhr@npm:2.0.4" - dependencies: - "@alova/shared": "npm:^1.0.4" - peerDependencies: - alova: ^3.0.5 - checksum: 10c0/c68f51b83c75844cf2cddc47d6e08fa7a6f0af83cc6213b60d0d8ac32988f8e7b44f321b1f926fa282a2cda02757ce3cbfe94e86f140fd025ab22f0dfee9bed9 +"@alova/adapter-xhr@npm:1.0.6": + version: 1.0.6 + resolution: "@alova/adapter-xhr@npm:1.0.6" + checksum: 10c0/1cd4f2da4f1c58865e14999d9cf367635f72f8e6bd41497366c25681154ffc7a4dedd70f234610c5e028c01418992dab709c777d986a6432d7d9783beeeb150e languageName: node linkType: hard -"@alova/shared@npm:^1.0.4": - version: 1.0.4 - resolution: "@alova/shared@npm:1.0.4" - checksum: 10c0/308b3163ee81fe98bb8372bd8a7df2a053be508167c86c6cfa2b3610c79389621e9a3466c391210e3f058799733465cf7dd153fcae536b03ea58dabff9d6eab4 +"@alova/scene-react@npm:1.6.2": + version: 1.6.2 + resolution: "@alova/scene-react@npm:1.6.2" + checksum: 10c0/dac01605df824e66dba92c5d7073e33f98ad47367a7180bd0ddc78c01f1e672ac665c1ff0445df7299be1426ca92e325cf0b9fa459984125d6391e9e9eb9d439 languageName: node linkType: hard @@ -721,10 +717,10 @@ __metadata: languageName: node linkType: hard -"@eslint/js@npm:9.8.0, @eslint/js@npm:^9.8.0": - version: 9.8.0 - resolution: "@eslint/js@npm:9.8.0" - checksum: 10c0/42edaae6b020436410454579509dcb6a8cd5b260e9f18e037fd803ae28d35eb13663d4019f0ab8ba686a19d3c4a43b0e11394c148e23345377ab694da0e83262 +"@eslint/js@npm:9.9.0, @eslint/js@npm:^9.9.0": + version: 9.9.0 + resolution: "@eslint/js@npm:9.9.0" + checksum: 10c0/6ec9f1f0d576132444d6a5c66a8a08b0be9444e3ebb563fa6a6bebcf5299df3da7e454dc04c0fa601bb811197f00764b3a04430d8458cdb8e3a4677993d23f30 languageName: node linkType: hard @@ -1121,114 +1117,114 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-android-arm-eabi@npm:4.19.2": - version: 4.19.2 - resolution: "@rollup/rollup-android-arm-eabi@npm:4.19.2" +"@rollup/rollup-android-arm-eabi@npm:4.20.0": + version: 4.20.0 + resolution: "@rollup/rollup-android-arm-eabi@npm:4.20.0" conditions: os=android & cpu=arm languageName: node linkType: hard -"@rollup/rollup-android-arm64@npm:4.19.2": - version: 4.19.2 - resolution: "@rollup/rollup-android-arm64@npm:4.19.2" +"@rollup/rollup-android-arm64@npm:4.20.0": + version: 4.20.0 + resolution: "@rollup/rollup-android-arm64@npm:4.20.0" conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-darwin-arm64@npm:4.19.2": - version: 4.19.2 - resolution: "@rollup/rollup-darwin-arm64@npm:4.19.2" +"@rollup/rollup-darwin-arm64@npm:4.20.0": + version: 4.20.0 + resolution: "@rollup/rollup-darwin-arm64@npm:4.20.0" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-darwin-x64@npm:4.19.2": - version: 4.19.2 - resolution: "@rollup/rollup-darwin-x64@npm:4.19.2" +"@rollup/rollup-darwin-x64@npm:4.20.0": + version: 4.20.0 + resolution: "@rollup/rollup-darwin-x64@npm:4.20.0" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@rollup/rollup-linux-arm-gnueabihf@npm:4.19.2": - version: 4.19.2 - resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.19.2" +"@rollup/rollup-linux-arm-gnueabihf@npm:4.20.0": + version: 4.20.0 + resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.20.0" conditions: os=linux & cpu=arm & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-arm-musleabihf@npm:4.19.2": - version: 4.19.2 - resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.19.2" +"@rollup/rollup-linux-arm-musleabihf@npm:4.20.0": + version: 4.20.0 + resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.20.0" conditions: os=linux & cpu=arm & libc=musl languageName: node linkType: hard -"@rollup/rollup-linux-arm64-gnu@npm:4.19.2": - version: 4.19.2 - resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.19.2" +"@rollup/rollup-linux-arm64-gnu@npm:4.20.0": + version: 4.20.0 + resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.20.0" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-arm64-musl@npm:4.19.2": - version: 4.19.2 - resolution: "@rollup/rollup-linux-arm64-musl@npm:4.19.2" +"@rollup/rollup-linux-arm64-musl@npm:4.20.0": + version: 4.20.0 + resolution: "@rollup/rollup-linux-arm64-musl@npm:4.20.0" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@rollup/rollup-linux-powerpc64le-gnu@npm:4.19.2": - version: 4.19.2 - resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.19.2" +"@rollup/rollup-linux-powerpc64le-gnu@npm:4.20.0": + version: 4.20.0 + resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.20.0" conditions: os=linux & cpu=ppc64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-riscv64-gnu@npm:4.19.2": - version: 4.19.2 - resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.19.2" +"@rollup/rollup-linux-riscv64-gnu@npm:4.20.0": + version: 4.20.0 + resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.20.0" conditions: os=linux & cpu=riscv64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-s390x-gnu@npm:4.19.2": - version: 4.19.2 - resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.19.2" +"@rollup/rollup-linux-s390x-gnu@npm:4.20.0": + version: 4.20.0 + resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.20.0" conditions: os=linux & cpu=s390x & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-x64-gnu@npm:4.19.2": - version: 4.19.2 - resolution: "@rollup/rollup-linux-x64-gnu@npm:4.19.2" +"@rollup/rollup-linux-x64-gnu@npm:4.20.0": + version: 4.20.0 + resolution: "@rollup/rollup-linux-x64-gnu@npm:4.20.0" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-x64-musl@npm:4.19.2": - version: 4.19.2 - resolution: "@rollup/rollup-linux-x64-musl@npm:4.19.2" +"@rollup/rollup-linux-x64-musl@npm:4.20.0": + version: 4.20.0 + resolution: "@rollup/rollup-linux-x64-musl@npm:4.20.0" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@rollup/rollup-win32-arm64-msvc@npm:4.19.2": - version: 4.19.2 - resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.19.2" +"@rollup/rollup-win32-arm64-msvc@npm:4.20.0": + version: 4.20.0 + resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.20.0" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-win32-ia32-msvc@npm:4.19.2": - version: 4.19.2 - resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.19.2" +"@rollup/rollup-win32-ia32-msvc@npm:4.20.0": + version: 4.20.0 + resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.20.0" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@rollup/rollup-win32-x64-msvc@npm:4.19.2": - version: 4.19.2 - resolution: "@rollup/rollup-win32-x64-msvc@npm:4.19.2" +"@rollup/rollup-win32-x64-msvc@npm:4.20.0": + version: 4.20.0 + resolution: "@rollup/rollup-win32-x64-msvc@npm:4.20.0" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -1437,15 +1433,6 @@ __metadata: linkType: hard "@types/node@npm:*": - version: 22.0.3 - resolution: "@types/node@npm:22.0.3" - dependencies: - undici-types: "npm:~6.11.1" - checksum: 10c0/9d734bcaf6079dfaffd6315bb845f24f5d7348f8945c3b3b9c227c76a653dbac2140620821cd717f69012fafd37ec8938df9799d1feae07161671b54be23d920 - languageName: node - linkType: hard - -"@types/node@npm:^22.1.0": version: 22.1.0 resolution: "@types/node@npm:22.1.0" dependencies: @@ -1454,6 +1441,15 @@ __metadata: languageName: node linkType: hard +"@types/node@npm:^22.2.0": + version: 22.2.0 + resolution: "@types/node@npm:22.2.0" + dependencies: + undici-types: "npm:~6.13.0" + checksum: 10c0/c17900b34faecfec204f72970bd658d0c217aaf739c1bf7690c969465b6b26b77a8be1cd9ba735aadbd1dd20b5c3e4f406ec33528bf7c6eec90744886c5d5608 + languageName: node + linkType: hard + "@types/parse-json@npm:^4.0.0": version: 4.0.2 resolution: "@types/parse-json@npm:4.0.2" @@ -1655,11 +1651,12 @@ __metadata: version: 0.0.0-use.local resolution: "EMS-ESP@workspace:." dependencies: - "@alova/adapter-xhr": "npm:^2.0.4" + "@alova/adapter-xhr": "npm:1.0.6" + "@alova/scene-react": "npm:1.6.2" "@babel/core": "npm:^7.25.2" "@emotion/react": "npm:^11.13.0" "@emotion/styled": "npm:^11.13.0" - "@eslint/js": "npm:^9.8.0" + "@eslint/js": "npm:^9.9.0" "@mui/icons-material": "npm:^5.16.7" "@mui/material": "npm:^5.16.7" "@preact/compat": "npm:^17.1.2" @@ -1667,14 +1664,14 @@ __metadata: "@table-library/react-table-library": "npm:4.1.7" "@trivago/prettier-plugin-sort-imports": "npm:^4.3.0" "@types/babel__core": "npm:^7" - "@types/node": "npm:^22.1.0" + "@types/node": "npm:^22.2.0" "@types/react": "npm:^18.3.3" "@types/react-dom": "npm:^18.3.0" "@types/react-router-dom": "npm:^5.3.3" - alova: "npm:^3.0.5" + alova: "npm:2.21.4" async-validator: "npm:^4.2.5" concurrently: "npm:^8.2.2" - eslint: "npm:^9.8.0" + eslint: "npm:^9.9.0" eslint-config-prettier: "npm:^9.1.0" jwt-decode: "npm:^4.0.0" mime-types: "npm:^2.1.35" @@ -1753,13 +1750,10 @@ __metadata: languageName: node linkType: hard -"alova@npm:^3.0.5": - version: 3.0.5 - resolution: "alova@npm:3.0.5" - dependencies: - "@alova/shared": "npm:^1.0.4" - rate-limiter-flexible: "npm:^5.0.3" - checksum: 10c0/2e94066f75832c4c85def894389cb8a1861af176910d3c5b01a0977809fd952c8b747dd645873040fd2fd9af45f8df0de44b715aacec19751923d76801366e3a +"alova@npm:2.21.4": + version: 2.21.4 + resolution: "alova@npm:2.21.4" + checksum: 10c0/6600826747eecc85f750904cd5a9f75361bd5b542615b027fae072cafe72cb27b9f7b260a834063c0734a9b41a7aa8b15396a190f8ce9a46713d01b073296a50 languageName: node linkType: hard @@ -2126,9 +2120,9 @@ __metadata: linkType: hard "caniuse-lite@npm:^1.0.30001646": - version: 1.0.30001646 - resolution: "caniuse-lite@npm:1.0.30001646" - checksum: 10c0/ecdd87c08cd63fa32e11311dfa3543a52613b0b99498b6fe6f2c66af65cc27e2f7436fa5b2bc2bcf72174448a7670715b284d420de838bcf3e811864371a2465 + version: 1.0.30001651 + resolution: "caniuse-lite@npm:1.0.30001651" + checksum: 10c0/7821278952a6dbd17358e5d08083d258f092e2a530f5bc1840657cb140fbbc5ec44293bc888258c44a18a9570cde149ed05819ac8320b9710cf22f699891e6ad languageName: node linkType: hard @@ -2737,9 +2731,9 @@ __metadata: linkType: hard "electron-to-chromium@npm:^1.5.4": - version: 1.5.4 - resolution: "electron-to-chromium@npm:1.5.4" - checksum: 10c0/139abf1b7281c2f3288819fb9b114f09d541ac38c9f0373f194ce2d483d82d118b8751f1b2a59b04ed0d8f414071b58508a40050fc0f23b5aa7e38d11d0cf30c + version: 1.5.5 + resolution: "electron-to-chromium@npm:1.5.5" + checksum: 10c0/6e5e12f729a74a78d9a7386ea32039262cb8a2f4611ab346da1f162c270d0569194c72169042080a1017220835ed30ee2d77ca5ba13c1acaa5fa0d373fbc0ad5 languageName: node linkType: hard @@ -3162,15 +3156,15 @@ __metadata: languageName: node linkType: hard -"eslint@npm:^9.8.0": - version: 9.8.0 - resolution: "eslint@npm:9.8.0" +"eslint@npm:^9.9.0": + version: 9.9.0 + resolution: "eslint@npm:9.9.0" dependencies: "@eslint-community/eslint-utils": "npm:^4.2.0" "@eslint-community/regexpp": "npm:^4.11.0" "@eslint/config-array": "npm:^0.17.1" "@eslint/eslintrc": "npm:^3.1.0" - "@eslint/js": "npm:9.8.0" + "@eslint/js": "npm:9.9.0" "@humanwhocodes/module-importer": "npm:^1.0.1" "@humanwhocodes/retry": "npm:^0.3.0" "@nodelib/fs.walk": "npm:^1.2.8" @@ -3200,9 +3194,14 @@ __metadata: optionator: "npm:^0.9.3" strip-ansi: "npm:^6.0.1" text-table: "npm:^0.2.0" + peerDependencies: + jiti: "*" + peerDependenciesMeta: + jiti: + optional: true bin: eslint: bin/eslint.js - checksum: 10c0/a2ee0cce1147565d011fe185733af482f34d5466f5df5f390d0ea2ecf78097883cf568ed6c771d687138609c63cd55cd1e3ff12de7393c03f54fcffcdd0f225d + checksum: 10c0/3a22f68c99d75dcbafe6e2fef18d2b5bbcc960c2437f48a414ccf9ca214254733a18e6b79d07bbd374a2369a648413e421aabd07b11be3de5a44d5a4b9997877 languageName: node linkType: hard @@ -3589,12 +3588,12 @@ __metadata: linkType: hard "foreground-child@npm:^3.1.0": - version: 3.2.1 - resolution: "foreground-child@npm:3.2.1" + version: 3.3.0 + resolution: "foreground-child@npm:3.3.0" dependencies: cross-spawn: "npm:^7.0.0" signal-exit: "npm:^4.0.1" - checksum: 10c0/9a53a33dbd87090e9576bef65fb4a71de60f6863a8062a7b11bc1cbe3cc86d428677d7c0b9ef61cdac11007ac580006f78bd5638618d564cfd5e6fd713d6878f + checksum: 10c0/028f1d41000553fcfa6c4bb5c372963bf3d9bf0b1f25a87d1a6253014343fb69dfb1b42d9625d7cf44c8ba429940f3d0ff718b62105d4d4a4f6ef8ca0a53faa2 languageName: node linkType: hard @@ -5718,13 +5717,6 @@ __metadata: languageName: node linkType: hard -"rate-limiter-flexible@npm:^5.0.3": - version: 5.0.3 - resolution: "rate-limiter-flexible@npm:5.0.3" - checksum: 10c0/4ae8290cf57cbd9bc8dfd9829ed821ffad2bc6d4699170608b4b85b010059981e591803a4b1974f25755f1cbf25ff8208795cc325d5bed9d2315717865e25697 - languageName: node - linkType: hard - "react-dom@npm:^18.3.1": version: 18.3.1 resolution: "react-dom@npm:18.3.1" @@ -6019,25 +6011,25 @@ __metadata: linkType: hard "rollup@npm:^4.13.0": - version: 4.19.2 - resolution: "rollup@npm:4.19.2" + version: 4.20.0 + resolution: "rollup@npm:4.20.0" dependencies: - "@rollup/rollup-android-arm-eabi": "npm:4.19.2" - "@rollup/rollup-android-arm64": "npm:4.19.2" - "@rollup/rollup-darwin-arm64": "npm:4.19.2" - "@rollup/rollup-darwin-x64": "npm:4.19.2" - "@rollup/rollup-linux-arm-gnueabihf": "npm:4.19.2" - "@rollup/rollup-linux-arm-musleabihf": "npm:4.19.2" - "@rollup/rollup-linux-arm64-gnu": "npm:4.19.2" - "@rollup/rollup-linux-arm64-musl": "npm:4.19.2" - "@rollup/rollup-linux-powerpc64le-gnu": "npm:4.19.2" - "@rollup/rollup-linux-riscv64-gnu": "npm:4.19.2" - "@rollup/rollup-linux-s390x-gnu": "npm:4.19.2" - "@rollup/rollup-linux-x64-gnu": "npm:4.19.2" - "@rollup/rollup-linux-x64-musl": "npm:4.19.2" - "@rollup/rollup-win32-arm64-msvc": "npm:4.19.2" - "@rollup/rollup-win32-ia32-msvc": "npm:4.19.2" - "@rollup/rollup-win32-x64-msvc": "npm:4.19.2" + "@rollup/rollup-android-arm-eabi": "npm:4.20.0" + "@rollup/rollup-android-arm64": "npm:4.20.0" + "@rollup/rollup-darwin-arm64": "npm:4.20.0" + "@rollup/rollup-darwin-x64": "npm:4.20.0" + "@rollup/rollup-linux-arm-gnueabihf": "npm:4.20.0" + "@rollup/rollup-linux-arm-musleabihf": "npm:4.20.0" + "@rollup/rollup-linux-arm64-gnu": "npm:4.20.0" + "@rollup/rollup-linux-arm64-musl": "npm:4.20.0" + "@rollup/rollup-linux-powerpc64le-gnu": "npm:4.20.0" + "@rollup/rollup-linux-riscv64-gnu": "npm:4.20.0" + "@rollup/rollup-linux-s390x-gnu": "npm:4.20.0" + "@rollup/rollup-linux-x64-gnu": "npm:4.20.0" + "@rollup/rollup-linux-x64-musl": "npm:4.20.0" + "@rollup/rollup-win32-arm64-msvc": "npm:4.20.0" + "@rollup/rollup-win32-ia32-msvc": "npm:4.20.0" + "@rollup/rollup-win32-x64-msvc": "npm:4.20.0" "@types/estree": "npm:1.0.5" fsevents: "npm:~2.3.2" dependenciesMeta: @@ -6077,7 +6069,7 @@ __metadata: optional: true bin: rollup: dist/bin/rollup - checksum: 10c0/ff5c1d071c873f25016263568177f5406d76f242a04d25a191a37f4b859a1662a1acc9f76bf680968ffcebb467ac4952521462375698468c80506ff91a0b9f2d + checksum: 10c0/9b23bf0e3380e64573a5f68a55274d5c7969036e55c19aab9fb4deea2e938d76769db70f3c95ee3783c24af152bea1772ad73f9e3625b6ffd4e600a788fe97ea languageName: node linkType: hard @@ -6854,13 +6846,6 @@ __metadata: languageName: node linkType: hard -"undici-types@npm:~6.11.1": - version: 6.11.1 - resolution: "undici-types@npm:6.11.1" - checksum: 10c0/d8f5739a8e6c779d72336c82deb49c56d5ac9f9f6e0eb2e8dd4d3f6929ae9db7cde370d2e46516fe6cad04ea53e790c5e16c4c75eed7cd0f9bd31b0763bb2fa3 - languageName: node - linkType: hard - "undici-types@npm:~6.13.0": version: 6.13.0 resolution: "undici-types@npm:6.13.0"