useApi changes

master
Tudor Stanciu 2022-01-18 14:08:04 +02:00
parent 0d611d2eb8
commit c7576a08c2
6 changed files with 132 additions and 70 deletions

3
src/api/index.js Normal file
View File

@ -0,0 +1,3 @@
import useApi from "./useApi";
export default useApi;

65
src/api/useApi.js Normal file
View File

@ -0,0 +1,65 @@
import { useToast } from "../hooks";
import { get, post } from "../utils/axios";
const networkRoute = `${process.env.REACT_APP_NETWORK_RESURRECTOR_API_URL}/network`;
const powerActionsRoute = `${process.env.REACT_APP_NETWORK_RESURRECTOR_API_URL}/resurrector`;
const useApi = () => {
const { error } = useToast();
const handleError = err => {
let message;
switch (err.response.status) {
case 500:
message = err.response.statusText;
break;
default:
message = err.message;
}
error(message);
};
const defaultOptions = { onCompleted: () => {}, onError: handleError };
const call = async (request, options) => {
const internalOptions = { ...defaultOptions, ...options };
const { onCompleted, onError } = internalOptions;
try {
const result = await request();
onCompleted(result);
} catch (error) {
onError(error);
}
};
const readMachines = (options = defaultOptions) => {
const machinesPromise = call(
() => get(`${networkRoute}/machines`),
options
);
return machinesPromise;
};
const wakeMachine = (machineId, options = defaultOptions) => {
const promise = call(
() => post(`${powerActionsRoute}/wake`, { machineId }),
options
);
return promise;
};
const pingMachine = (machineId, options = defaultOptions) => {
const promise = call(
() => post(`${powerActionsRoute}/ping`, { machineId }),
options
);
return promise;
};
return { readMachines, wakeMachine, pingMachine };
};
export default useApi;

View File

@ -1,26 +0,0 @@
import { get, post } from "../../utils/axios";
const networkRoute = `${process.env.REACT_APP_NETWORK_RESURRECTOR_API_URL}/network`;
const powerActionsRoute = `${process.env.REACT_APP_NETWORK_RESURRECTOR_API_URL}/resurrector`;
const readMachines = () => {
const machinesPromise = get(`${networkRoute}/machines`);
return machinesPromise;
};
const wakeMachine = async machineId => {
try {
const promise = await post(`${powerActionsRoute}/wake`, { machineId });
return promise;
} catch (ex) {
debugger;
console.log(ex);
}
};
const pingMachine = machineId => {
const promise = post(`${powerActionsRoute}/ping`, { machineId });
return promise;
};
export { readMachines, wakeMachine, pingMachine };

View File

@ -1,16 +1,18 @@
import React, { useState, useCallback } from "react"; import React, { useState, useCallback } from "react";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import Machine from "./Machine"; import Machine from "./Machine";
import * as api from "../api";
import { useToast } from "../../../hooks"; import { useToast } from "../../../hooks";
import { LastPage } from "@material-ui/icons"; import { LastPage } from "@material-ui/icons";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import useApi from "../../../api";
const MachineContainer = ({ machine }) => { const MachineContainer = ({ machine }) => {
const [logs, setLogs] = useState([]); const [logs, setLogs] = useState([]);
const { success, error } = useToast(); const { success, error } = useToast();
const { t } = useTranslation(); const { t } = useTranslation();
const api = useApi();
const addLog = useCallback( const addLog = useCallback(
text => { text => {
setLogs(prev => [...prev, text]); setLogs(prev => [...prev, text]);
@ -20,15 +22,18 @@ const MachineContainer = ({ machine }) => {
const pingMachine = useCallback( const pingMachine = useCallback(
machine => async () => { machine => async () => {
const result = await api.pingMachine(machine.machineId); await api.pingMachine(machine.machineId, {
addLog(`Success: ${result.success}. Status: ${result.status}`); onCompleted: result => {
if (result.success) { addLog(`Success: ${result.success}. Status: ${result.status}`);
success(result.status); if (result.success) {
} else { success(result.status);
error(result.status); } else {
} error(result.status);
}
}
});
}, },
[error, success, addLog] [error, success, addLog, api]
); );
const actions = [ const actions = [

View File

@ -3,18 +3,23 @@ import {
ApplicationStateContext, ApplicationStateContext,
ApplicationDispatchContext ApplicationDispatchContext
} from "../../../state/ApplicationContexts"; } from "../../../state/ApplicationContexts";
import * as api from "../api"; import useApi from "../../../api";
import MachinesList from "./MachinesList"; import MachinesList from "./MachinesList";
const MachinesContainer = () => { const MachinesContainer = () => {
const state = useContext(ApplicationStateContext); const state = useContext(ApplicationStateContext);
const dispatchActions = useContext(ApplicationDispatchContext); const dispatchActions = useContext(ApplicationDispatchContext);
const api = useApi();
const handleReadMachines = useCallback(async () => { const handleReadMachines = useCallback(async () => {
const machines = await api.readMachines(); await api.readMachines({
const data = Object.assign(machines, { loaded: true }); onCompleted: machines => {
dispatchActions.onNetworkChange("machines", data); const data = Object.assign(machines, { loaded: true });
}, [dispatchActions]); dispatchActions.onNetworkChange("machines", data);
}
});
}, [dispatchActions, api]);
useEffect(() => { useEffect(() => {
if (!state.network.machines.loaded) { if (!state.network.machines.loaded) {

View File

@ -4,8 +4,8 @@ import { IconButton, Tooltip } from "@material-ui/core";
import { PowerSettingsNew } from "@material-ui/icons"; import { PowerSettingsNew } from "@material-ui/icons";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { useToast } from "../../../hooks"; import { useToast } from "../../../hooks";
import * as api from "../api";
import { msToMinAndSec } from "../../../utils/time"; import { msToMinAndSec } from "../../../utils/time";
import useApi from "../../../api";
const initialState = { on: false }; const initialState = { on: false };
const defaultPingInterval = 1200000; //20 minutes const defaultPingInterval = 1200000; //20 minutes
@ -17,6 +17,7 @@ const WakeComponent = ({ machine, addLog }) => {
const { t } = useTranslation(); const { t } = useTranslation();
const { success, error } = useToast(); const { success, error } = useToast();
const api = useApi();
const pingInterval = const pingInterval =
process.env.REACT_APP_MACHINE_PING_INTERVAL || defaultPingInterval; process.env.REACT_APP_MACHINE_PING_INTERVAL || defaultPingInterval;
@ -37,38 +38,47 @@ const WakeComponent = ({ machine, addLog }) => {
); );
const wakeMachine = useCallback(async () => { const wakeMachine = useCallback(async () => {
const result = await api.wakeMachine(machine.machineId); await api.wakeMachine(machine.machineId, {
setState(prev => ({ ...prev, on: result.success })); onCompleted: result => {
log(`[Wake]: Success: ${result.success}. Status: ${result.status}`); setState(prev => ({ ...prev, on: result.success }));
if (result.success) { log(`[Wake]: Success: ${result.success}. Status: ${result.status}`);
success(result.status); if (result.success) {
success(result.status);
//retrigger //retrigger
log( log(
`Periodic ping will be re-triggered in ${startingTime} ms [${msToMinAndSec( `Periodic ping will be re-triggered in ${startingTime} ms [${msToMinAndSec(
startingTime startingTime
)}]` )}]`
); );
setTimeout(() => { setTimeout(() => {
setTrigger(prev => !prev); setTrigger(prev => !prev);
}, startingTime); }, startingTime);
} else { } else {
error(result.status); error(result.status);
} }
}, [log, success, error, startingTime, machine.machineId]);
useEffect(() => {
api.pingMachine(machine.machineId).then(result => {
setState(prev => ({ ...prev, on: result.success }));
log(`[Ping]: Success: ${result.success}. Status: ${result.status}`);
if (result.success) {
setTimeout(() => {
setTrigger(prev => !prev);
}, pingInterval);
} }
}); });
}, [machine, log, pingInterval, trigger]); }, [log, success, error, startingTime, machine.machineId, api]);
const pingInLoop = useCallback(async () => {
await api.pingMachine(machine.machineId, {
onCompleted: result => {
setState(prev => ({ ...prev, on: result.success }));
log(`[Ping]: Success: ${result.success}. Status: ${result.status}`);
if (result.success) {
setTimeout(() => {
setTrigger(prev => !prev);
}, pingInterval);
}
},
onError: () => {}
});
}, [machine, log, pingInterval]); // eslint-disable-line react-hooks/exhaustive-deps
// if "api" is added in pingInLoop dependencies, the useEffect is triggered in loop
useEffect(pingInLoop, [trigger, pingInLoop]);
return ( return (
<Tooltip title={t(state.on ? "Machine.PoweredOn" : "Machine.Actions.Wake")}> <Tooltip title={t(state.on ? "Machine.PoweredOn" : "Machine.Actions.Wake")}>