mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-06 07:49:52 +03:00
api refactoring
This commit is contained in:
@@ -25,13 +25,12 @@
|
||||
"@alova/adapter-xhr": "^2.0.4",
|
||||
"@emotion/react": "^11.13.0",
|
||||
"@emotion/styled": "^11.13.0",
|
||||
"@mui/icons-material": "^5.16.6",
|
||||
"@mui/material": "^5.16.6",
|
||||
"@mui/icons-material": "^5.16.7",
|
||||
"@mui/material": "^5.16.7",
|
||||
"@table-library/react-table-library": "4.1.7",
|
||||
"alova": "^3.0.5",
|
||||
"async-validator": "^4.2.5",
|
||||
"jwt-decode": "^4.0.0",
|
||||
"lodash-es": "^4.17.21",
|
||||
"mime-types": "^2.1.35",
|
||||
"preact": "^10.23.1",
|
||||
"react": "^18.3.1",
|
||||
@@ -50,7 +49,6 @@
|
||||
"@preact/preset-vite": "^2.9.0",
|
||||
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
|
||||
"@types/babel__core": "^7",
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"@types/node": "^22.1.0",
|
||||
"@types/react": "^18.3.3",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useContext, useEffect } from 'react';
|
||||
import { Navigate, Route, Routes, useLocation } from 'react-router-dom';
|
||||
import { Navigate, Route, Routes } from 'react-router-dom';
|
||||
import { toast } from 'react-toastify';
|
||||
|
||||
import AuthenticatedRouting from 'AuthenticatedRouting';
|
||||
|
||||
@@ -4,9 +4,7 @@ import { toast } from 'react-toastify';
|
||||
import ForwardIcon from '@mui/icons-material/Forward';
|
||||
import { Box, Button, Paper, Typography } from '@mui/material';
|
||||
|
||||
import * as AuthenticationApi from 'api/authentication';
|
||||
import { PROJECT_NAME } from 'api/env';
|
||||
|
||||
import * as AuthenticationApi from 'components/routing/authentication';
|
||||
import { useRequest } from 'alova/client';
|
||||
import type { ValidateFieldsError } from 'async-validator';
|
||||
import {
|
||||
@@ -15,6 +13,7 @@ import {
|
||||
ValidatedTextField
|
||||
} from 'components';
|
||||
import { AuthenticationContext } from 'contexts/authentication';
|
||||
import { PROJECT_NAME } from 'env';
|
||||
import { useI18nContext } from 'i18n/i18n-react';
|
||||
import type { SignInRequest } from 'types';
|
||||
import { onEnterCallback, updateValue } from 'utils';
|
||||
|
||||
@@ -17,7 +17,7 @@ import type {
|
||||
Settings,
|
||||
WriteAnalogSensor,
|
||||
WriteTemperatureSensor
|
||||
} from './types';
|
||||
} from '../app/main/types';
|
||||
|
||||
// DashboardDevices
|
||||
export const readCoreData = () => alovaInstance.Get<CoreData>(`/rest/coreData`);
|
||||
@@ -2,7 +2,7 @@ import { xhrRequestAdapter } from '@alova/adapter-xhr';
|
||||
import { createAlova } from 'alova';
|
||||
import ReactHook from 'alova/react';
|
||||
|
||||
import { unpack } from '../api/unpack';
|
||||
import { unpack } from './unpack';
|
||||
|
||||
export const ACCESS_TOKEN = 'access_token';
|
||||
|
||||
|
||||
@@ -29,8 +29,8 @@ import {
|
||||
} from 'components';
|
||||
import { useI18nContext } from 'i18n/i18n-react';
|
||||
|
||||
import { readCustomEntities, writeCustomEntities } from '../../api/app';
|
||||
import SettingsCustomEntitiesDialog from './CustomEntitiesDialog';
|
||||
import { readCustomEntities, writeCustomEntities } from './api';
|
||||
import { DeviceValueTypeNames, DeviceValueUOM_s } from './types';
|
||||
import type { Entities, EntityItem } from './types';
|
||||
import { entityItemValidation } from './validators';
|
||||
|
||||
@@ -26,7 +26,7 @@ import {
|
||||
Typography
|
||||
} from '@mui/material';
|
||||
|
||||
import * as SystemApi from 'api/system';
|
||||
import { restart } from 'api/system';
|
||||
|
||||
import {
|
||||
Body,
|
||||
@@ -50,7 +50,13 @@ import {
|
||||
} from 'components';
|
||||
import { useI18nContext } from 'i18n/i18n-react';
|
||||
|
||||
import * as EMSESP from './api';
|
||||
import {
|
||||
readDeviceEntities,
|
||||
readDevices,
|
||||
resetCustomizations,
|
||||
writeCustomizationEntities,
|
||||
writeDeviceName
|
||||
} from '../../api/app';
|
||||
import SettingsCustomizationsDialog from './CustomizationsDialog';
|
||||
import EntityMaskToggle from './EntityMaskToggle';
|
||||
import OptionIcon from './OptionIcon';
|
||||
@@ -77,7 +83,7 @@ const Customizations = () => {
|
||||
useLayoutTitle(LL.CUSTOMIZATIONS());
|
||||
|
||||
// fetch devices first
|
||||
const { data: devices, send: fetchDevices } = useRequest(EMSESP.readDevices);
|
||||
const { data: devices, send: fetchDevices } = useRequest(readDevices);
|
||||
|
||||
const [selectedDevice, setSelectedDevice] = useState<number>(
|
||||
Number(useLocation().state) || -1
|
||||
@@ -86,27 +92,26 @@ const Customizations = () => {
|
||||
useState<string>(''); // needed for API URL
|
||||
const [selectedDeviceName, setSelectedDeviceName] = useState<string>('');
|
||||
|
||||
const { send: resetCustomizations } = useRequest(EMSESP.resetCustomizations(), {
|
||||
const { send: sendResetCustomizations } = useRequest(resetCustomizations(), {
|
||||
immediate: false
|
||||
});
|
||||
|
||||
const { send: writeDeviceName } = useRequest(
|
||||
(data: { id: number; name: string }) => EMSESP.writeDeviceName(data),
|
||||
const { send: sendDeviceName } = useRequest(
|
||||
(data: { id: number; name: string }) => writeDeviceName(data),
|
||||
{
|
||||
immediate: false
|
||||
}
|
||||
);
|
||||
|
||||
const { send: writeCustomizationEntities } = useRequest(
|
||||
(data: { id: number; entity_ids: string[] }) =>
|
||||
EMSESP.writeCustomizationEntities(data),
|
||||
const { send: sendCustomizationEntities } = useRequest(
|
||||
(data: { id: number; entity_ids: string[] }) => writeCustomizationEntities(data),
|
||||
{
|
||||
immediate: false
|
||||
}
|
||||
);
|
||||
|
||||
const { send: readDeviceEntities } = useRequest(
|
||||
(data: number) => EMSESP.readDeviceEntities(data),
|
||||
const { send: sendDeviceEntities } = useRequest(
|
||||
(data: number) => readDeviceEntities(data),
|
||||
{
|
||||
initialData: [],
|
||||
immediate: false
|
||||
@@ -127,7 +132,7 @@ const Customizations = () => {
|
||||
);
|
||||
};
|
||||
|
||||
const { send: restartCommand } = useRequest(SystemApi.restart(), {
|
||||
const { send: sendRestart } = useRequest(restart(), {
|
||||
immediate: false
|
||||
});
|
||||
|
||||
@@ -228,7 +233,7 @@ const Customizations = () => {
|
||||
|
||||
useEffect(() => {
|
||||
if (devices && selectedDevice !== -1) {
|
||||
void readDeviceEntities(selectedDevice);
|
||||
void sendDeviceEntities(selectedDevice);
|
||||
const id = devices.devices.findIndex((d) => d.i === selectedDevice);
|
||||
if (id === -1) {
|
||||
setSelectedDevice(-1);
|
||||
@@ -242,8 +247,8 @@ const Customizations = () => {
|
||||
}
|
||||
}, [devices, selectedDevice]);
|
||||
|
||||
const restart = async () => {
|
||||
await restartCommand().catch((error: Error) => {
|
||||
const doRestart = async () => {
|
||||
await sendRestart().catch((error: Error) => {
|
||||
toast.error(error.message);
|
||||
});
|
||||
setRestarting(true);
|
||||
@@ -324,7 +329,7 @@ const Customizations = () => {
|
||||
|
||||
const resetCustomization = async () => {
|
||||
try {
|
||||
await resetCustomizations();
|
||||
await sendResetCustomizations();
|
||||
toast.info(LL.CUSTOMIZATIONS_RESTART());
|
||||
} catch (error) {
|
||||
toast.error((error as Error).message);
|
||||
@@ -384,7 +389,7 @@ const Customizations = () => {
|
||||
return;
|
||||
}
|
||||
|
||||
await writeCustomizationEntities({
|
||||
await sendCustomizationEntities({
|
||||
id: selectedDevice,
|
||||
entity_ids: masked_entities
|
||||
}).catch((error: Error) => {
|
||||
@@ -399,7 +404,7 @@ const Customizations = () => {
|
||||
};
|
||||
|
||||
const renameDevice = async () => {
|
||||
await writeDeviceName({ id: selectedDevice, name: selectedDeviceName })
|
||||
await sendDeviceName({ id: selectedDevice, name: selectedDeviceName })
|
||||
.then(() => {
|
||||
toast.success(LL.UPDATED_OF(LL.NAME(1)));
|
||||
})
|
||||
@@ -673,7 +678,7 @@ const Customizations = () => {
|
||||
startIcon={<PowerSettingsNewIcon />}
|
||||
variant="contained"
|
||||
color="error"
|
||||
onClick={restart}
|
||||
onClick={doRestart}
|
||||
>
|
||||
{LL.RESTART()}
|
||||
</Button>
|
||||
@@ -688,7 +693,7 @@ const Customizations = () => {
|
||||
startIcon={<CancelIcon />}
|
||||
variant="outlined"
|
||||
color="secondary"
|
||||
onClick={() => devices && readDeviceEntities(selectedDevice)}
|
||||
onClick={() => devices && sendDeviceEntities(selectedDevice)}
|
||||
>
|
||||
{LL.CANCEL()}
|
||||
</Button>
|
||||
|
||||
@@ -61,7 +61,7 @@ import { ButtonRow, MessageBox, SectionContent, useLayoutTitle } from 'component
|
||||
import { AuthenticatedContext } from 'contexts/authentication';
|
||||
import { useI18nContext } from 'i18n/i18n-react';
|
||||
|
||||
import * as EMSESP from './api';
|
||||
import { readCoreData, readDeviceData, writeDeviceValue } from '../../api/app';
|
||||
import DeviceIcon from './DeviceIcon';
|
||||
import DashboardDevicesDialog from './DevicesDialog';
|
||||
import { formatValue } from './deviceValue';
|
||||
@@ -84,18 +84,15 @@ const Devices = () => {
|
||||
|
||||
useLayoutTitle(LL.DEVICES());
|
||||
|
||||
const { data: coreData, send: readCoreData } = useRequest(
|
||||
() => EMSESP.readCoreData(),
|
||||
{
|
||||
const { data: coreData, send: sendCoreData } = useRequest(() => readCoreData(), {
|
||||
initialData: {
|
||||
connected: true,
|
||||
devices: []
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
const { data: deviceData, send: readDeviceData } = useRequest(
|
||||
(id: number) => EMSESP.readDeviceData(id),
|
||||
const { data: deviceData, send: sendDeviceData } = useRequest(
|
||||
(id: number) => readDeviceData(id),
|
||||
{
|
||||
initialData: {
|
||||
data: []
|
||||
@@ -104,8 +101,8 @@ const Devices = () => {
|
||||
}
|
||||
);
|
||||
|
||||
const { loading: submitting, send: writeDeviceValue } = useRequest(
|
||||
(data: { id: number; c: string; v: unknown }) => EMSESP.writeDeviceValue(data),
|
||||
const { loading: submitting, send: sendDeviceValue } = useRequest(
|
||||
(data: { id: number; c: string; v: unknown }) => writeDeviceValue(data),
|
||||
{
|
||||
immediate: false
|
||||
}
|
||||
@@ -287,7 +284,7 @@ const Devices = () => {
|
||||
async function onSelectChange(action: Action, state: State) {
|
||||
setSelectedDevice(state.id as number);
|
||||
if (action.type === 'ADD_BY_ID_EXCLUSIVELY') {
|
||||
await readDeviceData(state.id as number);
|
||||
await sendDeviceData(state.id as number);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -322,7 +319,7 @@ const Devices = () => {
|
||||
|
||||
const refreshData = () => {
|
||||
if (!deviceValueDialogOpen) {
|
||||
selectedDevice ? void readDeviceData(selectedDevice) : void readCoreData();
|
||||
selectedDevice ? void sendDeviceData(selectedDevice) : void sendCoreData();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -444,7 +441,7 @@ const Devices = () => {
|
||||
|
||||
const deviceValueDialogSave = async (devicevalue: DeviceValue) => {
|
||||
const id = Number(device_select.state.id);
|
||||
await writeDeviceValue({ id, c: devicevalue.c ?? '', v: devicevalue.v })
|
||||
await sendDeviceValue({ id, c: devicevalue.c ?? '', v: devicevalue.v })
|
||||
.then(() => {
|
||||
toast.success(LL.WRITE_CMD_SENT());
|
||||
})
|
||||
@@ -453,7 +450,7 @@ const Devices = () => {
|
||||
})
|
||||
.finally(async () => {
|
||||
setDeviceValueDialogOpen(false);
|
||||
await readDeviceData(id);
|
||||
await sendDeviceData(id);
|
||||
setSelectedDeviceValue(undefined);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -17,20 +17,20 @@ import {
|
||||
Typography
|
||||
} from '@mui/material';
|
||||
|
||||
import * as SystemApi from 'api/system';
|
||||
import { readSystemStatus } from 'api/system';
|
||||
|
||||
import * as EMSESP from 'app/main/api';
|
||||
import { useRequest } from 'alova/client';
|
||||
import { SectionContent, useLayoutTitle } from 'components';
|
||||
import { useI18nContext } from 'i18n/i18n-react';
|
||||
|
||||
import { API } from '../../api/app';
|
||||
import type { APIcall } from './types';
|
||||
|
||||
const Help = () => {
|
||||
const { LL } = useI18nContext();
|
||||
useLayoutTitle(LL.HELP_OF(''));
|
||||
|
||||
const { send: getAPI } = useRequest((data: APIcall) => EMSESP.API(data), {
|
||||
const { send: getAPI } = useRequest((data: APIcall) => API(data), {
|
||||
immediate: false
|
||||
}).onSuccess((event) => {
|
||||
const anchor = document.createElement('a');
|
||||
@@ -47,7 +47,7 @@ const Help = () => {
|
||||
toast.info(LL.DOWNLOAD_SUCCESSFUL());
|
||||
});
|
||||
|
||||
const { data, loading } = useRequest(SystemApi.readSystemStatus);
|
||||
const { data, loading } = useRequest(readSystemStatus);
|
||||
|
||||
const callAPI = async (device: string, entity: string) => {
|
||||
await getAPI({ device, entity, id: 0 }).catch((error: Error) => {
|
||||
|
||||
@@ -27,8 +27,8 @@ import {
|
||||
} from 'components';
|
||||
import { useI18nContext } from 'i18n/i18n-react';
|
||||
|
||||
import { readModules, writeModules } from '../../api/app';
|
||||
import ModulesDialog from './ModulesDialog';
|
||||
import { readModules, writeModules } from './api';
|
||||
import type { ModuleItem, Modules } from './types';
|
||||
|
||||
const Modules = () => {
|
||||
|
||||
@@ -28,8 +28,8 @@ import {
|
||||
} from 'components';
|
||||
import { useI18nContext } from 'i18n/i18n-react';
|
||||
|
||||
import { readSchedule, writeSchedule } from '../../api/app';
|
||||
import SettingsSchedulerDialog from './SchedulerDialog';
|
||||
import { readSchedule, writeSchedule } from './api';
|
||||
import { ScheduleFlag } from './types';
|
||||
import type { Schedule, ScheduleItem } from './types';
|
||||
import { schedulerItemValidation } from './validators';
|
||||
|
||||
@@ -25,7 +25,11 @@ import { ButtonRow, SectionContent, useLayoutTitle } from 'components';
|
||||
import { AuthenticatedContext } from 'contexts/authentication';
|
||||
import { useI18nContext } from 'i18n/i18n-react';
|
||||
|
||||
import * as EMSESP from './api';
|
||||
import {
|
||||
readSensorData,
|
||||
writeAnalogSensor,
|
||||
writeTemperatureSensor
|
||||
} from '../../api/app';
|
||||
import DashboardSensorsAnalogDialog from './SensorsAnalogDialog';
|
||||
import DashboardSensorsTemperatureDialog from './SensorsTemperatureDialog';
|
||||
import {
|
||||
@@ -56,8 +60,8 @@ const Sensors = () => {
|
||||
const [analogDialogOpen, setAnalogDialogOpen] = useState<boolean>(false);
|
||||
const [creating, setCreating] = useState<boolean>(false);
|
||||
|
||||
const { data: sensorData, send: fetchSensorData } = useRequest(
|
||||
() => EMSESP.readSensorData(),
|
||||
const { data: sensorData, send: sendSensorData } = useRequest(
|
||||
() => readSensorData(),
|
||||
{
|
||||
initialData: {
|
||||
ts: [],
|
||||
@@ -68,15 +72,15 @@ const Sensors = () => {
|
||||
}
|
||||
);
|
||||
|
||||
const { send: writeTemperatureSensor } = useRequest(
|
||||
(data: WriteTemperatureSensor) => EMSESP.writeTemperatureSensor(data),
|
||||
const { send: sendTemperatureSensor } = useRequest(
|
||||
(data: WriteTemperatureSensor) => writeTemperatureSensor(data),
|
||||
{
|
||||
immediate: false
|
||||
}
|
||||
);
|
||||
|
||||
const { send: writeAnalogSensor } = useRequest(
|
||||
(data: WriteAnalogSensor) => EMSESP.writeAnalogSensor(data),
|
||||
const { send: sendAnalogSensor } = useRequest(
|
||||
(data: WriteAnalogSensor) => writeAnalogSensor(data),
|
||||
{
|
||||
immediate: false
|
||||
}
|
||||
@@ -195,7 +199,7 @@ const Sensors = () => {
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const timer = setInterval(() => fetchSensorData(), 30000);
|
||||
const timer = setInterval(() => sendSensorData(), 30000);
|
||||
return () => {
|
||||
clearInterval(timer);
|
||||
};
|
||||
@@ -265,7 +269,7 @@ const Sensors = () => {
|
||||
};
|
||||
|
||||
const onTemperatureDialogSave = async (ts: TemperatureSensor) => {
|
||||
await writeTemperatureSensor({ id: ts.id, name: ts.n, offset: ts.o })
|
||||
await sendTemperatureSensor({ id: ts.id, name: ts.n, offset: ts.o })
|
||||
.then(() => {
|
||||
toast.success(LL.UPDATED_OF(LL.SENSOR(1)));
|
||||
})
|
||||
@@ -275,7 +279,7 @@ const Sensors = () => {
|
||||
.finally(async () => {
|
||||
setTemperatureDialogOpen(false);
|
||||
setSelectedTemperatureSensor(undefined);
|
||||
await fetchSensorData();
|
||||
await sendSensorData();
|
||||
});
|
||||
};
|
||||
|
||||
@@ -310,7 +314,7 @@ const Sensors = () => {
|
||||
};
|
||||
|
||||
const onAnalogDialogSave = async (as: AnalogSensor) => {
|
||||
await writeAnalogSensor({
|
||||
await sendAnalogSensor({
|
||||
id: as.id,
|
||||
gpio: as.g,
|
||||
name: as.n,
|
||||
@@ -329,7 +333,7 @@ const Sensors = () => {
|
||||
.finally(async () => {
|
||||
setAnalogDialogOpen(false);
|
||||
setSelectedAnalogSensor(undefined);
|
||||
await fetchSensorData();
|
||||
await sendSensorData();
|
||||
});
|
||||
};
|
||||
|
||||
@@ -503,7 +507,7 @@ const Sensors = () => {
|
||||
startIcon={<RefreshIcon />}
|
||||
variant="outlined"
|
||||
color="secondary"
|
||||
onClick={fetchSensorData}
|
||||
onClick={sendSensorData}
|
||||
>
|
||||
{LL.REFRESH()}
|
||||
</Button>
|
||||
|
||||
@@ -18,7 +18,6 @@ import {
|
||||
useLayoutTitle
|
||||
} from 'components';
|
||||
import { useI18nContext } from 'i18n/i18n-react';
|
||||
import { range } from 'lodash-es';
|
||||
import type { APSettingsType } from 'types';
|
||||
import { APProvisionMode } from 'types';
|
||||
import { numberValue, updateValueDirty, useRest } from 'utils';
|
||||
@@ -73,6 +72,11 @@ const APSettings = () => {
|
||||
}
|
||||
};
|
||||
|
||||
// no lodash - https://asleepace.com/blog/typescript-range-without-a-loop/
|
||||
function range(a: number, b: number): number[] {
|
||||
return a < b ? [a, ...range(a + 1, b)] : [b];
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<ValidatedTextField
|
||||
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
Typography
|
||||
} from '@mui/material';
|
||||
|
||||
import * as SystemApi from 'api/system';
|
||||
import { readHardwareStatus, restart } from 'api/system';
|
||||
|
||||
import { useRequest } from 'alova/client';
|
||||
import RestartMonitor from 'app/status/RestartMonitor';
|
||||
@@ -35,7 +35,7 @@ import { useI18nContext } from 'i18n/i18n-react';
|
||||
import { numberValue, updateValueDirty, useRest } from 'utils';
|
||||
import { validate } from 'validators';
|
||||
|
||||
import * as EMSESP from '../main/api';
|
||||
import { getBoardProfile, readSettings, writeSettings } from '../../api/app';
|
||||
import { BOARD_PROFILES } from '../main/types';
|
||||
import type { Settings } from '../main/types';
|
||||
import { createSettingsValidator } from '../main/validators';
|
||||
@@ -49,7 +49,7 @@ export function boardProfileSelectItems() {
|
||||
}
|
||||
|
||||
const ApplicationSettings = () => {
|
||||
const { data: hardwareData } = useRequest(SystemApi.readHardwareStatus, {
|
||||
const { data: hardwareData } = useRequest(readHardwareStatus, {
|
||||
initialData: { psram: false }
|
||||
});
|
||||
|
||||
@@ -66,8 +66,8 @@ const ApplicationSettings = () => {
|
||||
errorMessage,
|
||||
restartNeeded
|
||||
} = useRest<Settings>({
|
||||
read: EMSESP.readSettings,
|
||||
update: EMSESP.writeSettings
|
||||
read: readSettings,
|
||||
update: writeSettings
|
||||
});
|
||||
|
||||
const [restarting, setRestarting] = useState<boolean>();
|
||||
@@ -84,7 +84,7 @@ const ApplicationSettings = () => {
|
||||
const [fieldErrors, setFieldErrors] = useState<ValidateFieldsError>();
|
||||
|
||||
const { loading: processingBoard, send: readBoardProfile } = useRequest(
|
||||
(boardProfile: string) => EMSESP.getBoardProfile(boardProfile),
|
||||
(boardProfile: string) => getBoardProfile(boardProfile),
|
||||
{
|
||||
immediate: false
|
||||
}
|
||||
@@ -105,7 +105,7 @@ const ApplicationSettings = () => {
|
||||
});
|
||||
});
|
||||
|
||||
const { send: restartCommand } = useRequest(SystemApi.restart(), {
|
||||
const { send: restartCommand } = useRequest(restart(), {
|
||||
immediate: false
|
||||
});
|
||||
|
||||
|
||||
@@ -5,8 +5,15 @@ import DownloadIcon from '@mui/icons-material/GetApp';
|
||||
import { Box, Button, Divider, Link, Typography } from '@mui/material';
|
||||
|
||||
import * as SystemApi from 'api/system';
|
||||
import {
|
||||
API,
|
||||
getCustomizations,
|
||||
getEntities,
|
||||
getSchedule,
|
||||
getSettings
|
||||
} from 'api/app';
|
||||
import { getDevVersion, getStableVersion } from 'api/system';
|
||||
|
||||
import * as EMSESP from 'app/main/api';
|
||||
import { useRequest } from 'alova/client';
|
||||
import type { APIcall } from 'app/main/types';
|
||||
import {
|
||||
@@ -24,31 +31,31 @@ const UploadDownload = () => {
|
||||
const [restarting, setRestarting] = useState<boolean>();
|
||||
const [md5, setMd5] = useState<string>();
|
||||
|
||||
const { send: getSettings } = useRequest(EMSESP.getSettings(), {
|
||||
const { send: sendSettings } = useRequest(getSettings(), {
|
||||
immediate: false
|
||||
}).onSuccess((event) => {
|
||||
saveFile(event.data, 'settings.json');
|
||||
});
|
||||
|
||||
const { send: getCustomizations } = useRequest(EMSESP.getCustomizations(), {
|
||||
const { send: sendCustomizations } = useRequest(getCustomizations(), {
|
||||
immediate: false
|
||||
}).onSuccess((event) => {
|
||||
saveFile(event.data, 'customizations.json');
|
||||
});
|
||||
|
||||
const { send: getEntities } = useRequest(EMSESP.getEntities(), {
|
||||
const { send: sendEntities } = useRequest(getEntities(), {
|
||||
immediate: false
|
||||
}).onSuccess((event) => {
|
||||
saveFile(event.data, 'entities.json');
|
||||
});
|
||||
|
||||
const { send: getSchedule } = useRequest(EMSESP.getSchedule(), {
|
||||
const { send: sendSchedule } = useRequest(getSchedule(), {
|
||||
immediate: false
|
||||
}).onSuccess((event) => {
|
||||
saveFile(event.data, 'schedule.json');
|
||||
});
|
||||
|
||||
const { send: getAPI } = useRequest((data: APIcall) => EMSESP.API(data), {
|
||||
const { send: getAPI } = useRequest((data: APIcall) => API(data), {
|
||||
immediate: false
|
||||
}).onSuccess((event) => {
|
||||
saveFile(
|
||||
@@ -64,8 +71,8 @@ const UploadDownload = () => {
|
||||
} = useRequest(SystemApi.readHardwareStatus);
|
||||
|
||||
// called immediately to get the latest version, on page load
|
||||
const { data: latestVersion } = useRequest(SystemApi.getStableVersion);
|
||||
const { data: latestDevVersion } = useRequest(SystemApi.getDevVersion);
|
||||
const { data: latestVersion } = useRequest(getStableVersion);
|
||||
const { data: latestDevVersion } = useRequest(getDevVersion);
|
||||
|
||||
const STABLE_URL = 'https://github.com/emsesp/EMS-ESP32/releases/download/';
|
||||
const STABLE_RELNOTES_URL =
|
||||
@@ -131,25 +138,25 @@ const UploadDownload = () => {
|
||||
};
|
||||
|
||||
const downloadSettings = async () => {
|
||||
await getSettings().catch((error: Error) => {
|
||||
await sendSettings().catch((error: Error) => {
|
||||
toast.error(error.message);
|
||||
});
|
||||
};
|
||||
|
||||
const downloadCustomizations = async () => {
|
||||
await getCustomizations().catch((error: Error) => {
|
||||
await sendCustomizations().catch((error: Error) => {
|
||||
toast.error(error.message);
|
||||
});
|
||||
};
|
||||
|
||||
const downloadEntities = async () => {
|
||||
await getEntities().catch((error: Error) => {
|
||||
await sendEntities().catch((error: Error) => {
|
||||
toast.error(error.message);
|
||||
});
|
||||
};
|
||||
|
||||
const downloadSchedule = async () => {
|
||||
await getSchedule().catch((error: Error) => {
|
||||
await sendSchedule().catch((error: Error) => {
|
||||
toast.error(error.message);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -18,7 +18,7 @@ import { ButtonRow, FormLoader, SectionContent, useLayoutTitle } from 'component
|
||||
import { useI18nContext } from 'i18n/i18n-react';
|
||||
import type { Translation } from 'i18n/i18n-types';
|
||||
|
||||
import * as EMSESP from '../main/api';
|
||||
import * as EMSESP from '../../api/app';
|
||||
import type { Stat } from '../main/types';
|
||||
|
||||
const SystemActivity = () => {
|
||||
|
||||
@@ -4,8 +4,7 @@ import { useLocation } from 'react-router-dom';
|
||||
|
||||
import { Box, Toolbar } from '@mui/material';
|
||||
|
||||
import { PROJECT_NAME } from 'api/env';
|
||||
|
||||
import { PROJECT_NAME } from 'env';
|
||||
import type { RequiredChildrenProps } from 'utils';
|
||||
|
||||
import LayoutAppBar from './LayoutAppBar';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Box, Divider, Drawer, Toolbar, Typography, styled } from '@mui/material';
|
||||
|
||||
import { PROJECT_NAME } from 'api/env';
|
||||
import { PROJECT_NAME } from 'env';
|
||||
|
||||
import { DRAWER_WIDTH } from './Layout';
|
||||
import LayoutMenu from './LayoutMenu';
|
||||
|
||||
@@ -2,8 +2,7 @@ import { useContext, useEffect } from 'react';
|
||||
import type { FC } from 'react';
|
||||
import { Navigate, useLocation } from 'react-router-dom';
|
||||
|
||||
import { storeLoginRedirect } from 'api/authentication';
|
||||
|
||||
import { storeLoginRedirect } from 'components/routing/authentication';
|
||||
import type { AuthenticatedContextValue } from 'contexts/authentication/context';
|
||||
import {
|
||||
AuthenticatedContext,
|
||||
|
||||
@@ -2,8 +2,7 @@ import { useContext } from 'react';
|
||||
import type { FC } from 'react';
|
||||
import { Navigate } from 'react-router-dom';
|
||||
|
||||
import * as AuthenticationApi from 'api/authentication';
|
||||
|
||||
import { fetchLoginRedirect } from 'components/routing/authentication';
|
||||
import { AuthenticationContext } from 'contexts/authentication';
|
||||
import type { RequiredChildrenProps } from 'utils';
|
||||
|
||||
@@ -11,7 +10,7 @@ const RequireUnauthenticated: FC<RequiredChildrenProps> = ({ children }) => {
|
||||
const authenticationContext = useContext(AuthenticationContext);
|
||||
|
||||
return authenticationContext.me ? (
|
||||
<Navigate to={AuthenticationApi.fetchLoginRedirect()} />
|
||||
<Navigate to={fetchLoginRedirect()} />
|
||||
) : (
|
||||
<>{children}</>
|
||||
);
|
||||
|
||||
@@ -4,7 +4,7 @@ import type * as H from 'history';
|
||||
import { jwtDecode } from 'jwt-decode';
|
||||
import type { Me, SignInRequest, SignInResponse } from 'types';
|
||||
|
||||
import { ACCESS_TOKEN, alovaInstance } from './endpoints';
|
||||
import { ACCESS_TOKEN, alovaInstance } from '../../api/endpoints';
|
||||
|
||||
export const SIGN_IN_PATHNAME = 'loginPathname';
|
||||
export const SIGN_IN_SEARCH = 'loginSearch';
|
||||
@@ -3,11 +3,12 @@ import type { FC } from 'react';
|
||||
import { redirect } from 'react-router-dom';
|
||||
import { toast } from 'react-toastify';
|
||||
|
||||
import * as AuthenticationApi from 'api/authentication';
|
||||
import { ACCESS_TOKEN } from 'api/endpoints';
|
||||
|
||||
import * as AuthenticationApi from 'components/routing/authentication';
|
||||
import { useRequest } from 'alova/client';
|
||||
import { LoadingSpinner } from 'components';
|
||||
import { verifyAuthorization } from 'components/routing/authentication';
|
||||
import { useI18nContext } from 'i18n/i18n-react';
|
||||
import type { Me } from 'types';
|
||||
import type { RequiredChildrenProps } from 'utils';
|
||||
@@ -20,12 +21,9 @@ const Authentication: FC<RequiredChildrenProps> = ({ children }) => {
|
||||
const [initialized, setInitialized] = useState<boolean>(false);
|
||||
const [me, setMe] = useState<Me>();
|
||||
|
||||
const { send: verifyAuthorization } = useRequest(
|
||||
AuthenticationApi.verifyAuthorization(),
|
||||
{
|
||||
const { send: sendVerifyAuthorization } = useRequest(verifyAuthorization(), {
|
||||
immediate: false
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
const signIn = (accessToken: string) => {
|
||||
try {
|
||||
@@ -51,7 +49,7 @@ const Authentication: FC<RequiredChildrenProps> = ({ children }) => {
|
||||
const refresh = useCallback(async () => {
|
||||
const accessToken = AuthenticationApi.getStorage().getItem(ACCESS_TOKEN);
|
||||
if (accessToken) {
|
||||
await verifyAuthorization()
|
||||
await sendVerifyAuthorization()
|
||||
.then(() => {
|
||||
setMe(AuthenticationApi.decodeMeJWT(accessToken));
|
||||
setInitialized(true);
|
||||
|
||||
@@ -815,16 +815,16 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@mui/core-downloads-tracker@npm:^5.16.6":
|
||||
version: 5.16.6
|
||||
resolution: "@mui/core-downloads-tracker@npm:5.16.6"
|
||||
checksum: 10c0/ee7655eda56e8eeb18ae600b24182c10caab4468d33179de3e76a783a827be9577afe114750835f7c9c7f555c0de0845c0500e91ed2e669b16399a1ffe41c33d
|
||||
"@mui/core-downloads-tracker@npm:^5.16.7":
|
||||
version: 5.16.7
|
||||
resolution: "@mui/core-downloads-tracker@npm:5.16.7"
|
||||
checksum: 10c0/4644c850160d01232c1abdbed141e4fa70e155891a9c68f0c2cc3054b4a3cdc1d28cf2d6665366fd8c725b2b091db677e11831552889a4e4e14f1e44450cf654
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@mui/icons-material@npm:^5.16.6":
|
||||
version: 5.16.6
|
||||
resolution: "@mui/icons-material@npm:5.16.6"
|
||||
"@mui/icons-material@npm:^5.16.7":
|
||||
version: 5.16.7
|
||||
resolution: "@mui/icons-material@npm:5.16.7"
|
||||
dependencies:
|
||||
"@babel/runtime": "npm:^7.23.9"
|
||||
peerDependencies:
|
||||
@@ -834,17 +834,17 @@ __metadata:
|
||||
peerDependenciesMeta:
|
||||
"@types/react":
|
||||
optional: true
|
||||
checksum: 10c0/9d24d95e8b4606b5fa2a2e40319255e2e6da52845db50d2d3ca6fd526102be3c498ec1aa9be8d33aad52cf531749b15d490abca5f23af92afc86cf45dc62ce24
|
||||
checksum: 10c0/49bab1754334798acaf93187d27200cf90d7c50b6a019531594aeac9e5ced9168281fec70bb040792dc86c8bc0d3bf9a876f22cfbf86ad07941ca6bc6c564921
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@mui/material@npm:^5.16.6":
|
||||
version: 5.16.6
|
||||
resolution: "@mui/material@npm:5.16.6"
|
||||
"@mui/material@npm:^5.16.7":
|
||||
version: 5.16.7
|
||||
resolution: "@mui/material@npm:5.16.7"
|
||||
dependencies:
|
||||
"@babel/runtime": "npm:^7.23.9"
|
||||
"@mui/core-downloads-tracker": "npm:^5.16.6"
|
||||
"@mui/system": "npm:^5.16.6"
|
||||
"@mui/core-downloads-tracker": "npm:^5.16.7"
|
||||
"@mui/system": "npm:^5.16.7"
|
||||
"@mui/types": "npm:^7.2.15"
|
||||
"@mui/utils": "npm:^5.16.6"
|
||||
"@popperjs/core": "npm:^2.11.8"
|
||||
@@ -867,7 +867,7 @@ __metadata:
|
||||
optional: true
|
||||
"@types/react":
|
||||
optional: true
|
||||
checksum: 10c0/52cbffd87a36b9f8e16ba59030e89501e680ddea4d3dcf3db5d8fb7b86205444b00162e656c79571824a74769f879f39df2e7671d1e7ca8bc23602a7bf588dc5
|
||||
checksum: 10c0/b11419c1a77835413471f9352586fed65fb5de19c6737e121669da0484c441c7dd9939aa73fdad779482c30efaa694fb9fdcf18dcf418af07881e60eaff92b4f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -909,9 +909,9 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@mui/system@npm:^5.16.6":
|
||||
version: 5.16.6
|
||||
resolution: "@mui/system@npm:5.16.6"
|
||||
"@mui/system@npm:^5.16.7":
|
||||
version: 5.16.7
|
||||
resolution: "@mui/system@npm:5.16.7"
|
||||
dependencies:
|
||||
"@babel/runtime": "npm:^7.23.9"
|
||||
"@mui/private-theming": "npm:^5.16.6"
|
||||
@@ -933,7 +933,7 @@ __metadata:
|
||||
optional: true
|
||||
"@types/react":
|
||||
optional: true
|
||||
checksum: 10c0/493900594f51d1fc84994042e5cfa000b2d7664f86c8c0d62b87dbbb51cf7e789a700512f98e18c82e605beab38c20d0714ec25c46e2f6a5024f79f16db743f7
|
||||
checksum: 10c0/c07479c0728433847c1e3d7f57b96d9e0770cc814dfd1c9e070304955984a0b706832703b22388eb83906d1a01691f37047e2bac6a5e5c083e8c29a54302d476
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -1429,22 +1429,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/lodash-es@npm:^4.17.12":
|
||||
version: 4.17.12
|
||||
resolution: "@types/lodash-es@npm:4.17.12"
|
||||
dependencies:
|
||||
"@types/lodash": "npm:*"
|
||||
checksum: 10c0/5d12d2cede07f07ab067541371ed1b838a33edb3c35cb81b73284e93c6fd0c4bbeaefee984e69294bffb53f62d7272c5d679fdba8e595ff71e11d00f2601dde0
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/lodash@npm:*":
|
||||
version: 4.17.7
|
||||
resolution: "@types/lodash@npm:4.17.7"
|
||||
checksum: 10c0/40c965b5ffdcf7ff5c9105307ee08b782da228c01b5c0529122c554c64f6b7168fc8f11dc79aa7bae4e67e17efafaba685dc3a47e294dbf52a65ed2b67100561
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/minimatch@npm:*":
|
||||
version: 5.1.2
|
||||
resolution: "@types/minimatch@npm:5.1.2"
|
||||
@@ -1676,14 +1660,13 @@ __metadata:
|
||||
"@emotion/react": "npm:^11.13.0"
|
||||
"@emotion/styled": "npm:^11.13.0"
|
||||
"@eslint/js": "npm:^9.8.0"
|
||||
"@mui/icons-material": "npm:^5.16.6"
|
||||
"@mui/material": "npm:^5.16.6"
|
||||
"@mui/icons-material": "npm:^5.16.7"
|
||||
"@mui/material": "npm:^5.16.7"
|
||||
"@preact/compat": "npm:^17.1.2"
|
||||
"@preact/preset-vite": "npm:^2.9.0"
|
||||
"@table-library/react-table-library": "npm:4.1.7"
|
||||
"@trivago/prettier-plugin-sort-imports": "npm:^4.3.0"
|
||||
"@types/babel__core": "npm:^7"
|
||||
"@types/lodash-es": "npm:^4.17.12"
|
||||
"@types/node": "npm:^22.1.0"
|
||||
"@types/react": "npm:^18.3.3"
|
||||
"@types/react-dom": "npm:^18.3.0"
|
||||
@@ -1694,7 +1677,6 @@ __metadata:
|
||||
eslint: "npm:^9.8.0"
|
||||
eslint-config-prettier: "npm:^9.1.0"
|
||||
jwt-decode: "npm:^4.0.0"
|
||||
lodash-es: "npm:^4.17.21"
|
||||
mime-types: "npm:^2.1.35"
|
||||
preact: "npm:^10.23.1"
|
||||
prettier: "npm:^3.3.3"
|
||||
@@ -4695,13 +4677,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"lodash-es@npm:^4.17.21":
|
||||
version: 4.17.21
|
||||
resolution: "lodash-es@npm:4.17.21"
|
||||
checksum: 10c0/fb407355f7e6cd523a9383e76e6b455321f0f153a6c9625e21a8827d10c54c2a2341bd2ae8d034358b60e07325e1330c14c224ff582d04612a46a4f0479ff2f2
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"lodash.merge@npm:^4.6.2":
|
||||
version: 4.6.2
|
||||
resolution: "lodash.merge@npm:4.6.2"
|
||||
|
||||
Reference in New Issue
Block a user