refactoring api integration
parent
0e025e6c68
commit
3a211bcb17
|
@ -1,3 +0,0 @@
|
||||||
import useApi from "./useApi";
|
|
||||||
|
|
||||||
export default useApi;
|
|
|
@ -1,115 +0,0 @@
|
||||||
import { get, post } from "../utils/axios";
|
|
||||||
import { toast } from "react-toastify";
|
|
||||||
|
|
||||||
const networkRoute = `${process.env.REACT_APP_NETWORK_RESURRECTOR_API_URL}/network`;
|
|
||||||
const systemRoute = `${process.env.REACT_APP_NETWORK_RESURRECTOR_API_URL}/system`;
|
|
||||||
const powerActionsRoute = `${process.env.REACT_APP_NETWORK_RESURRECTOR_API_URL}/resurrector`;
|
|
||||||
const securityRoute = `${process.env.REACT_APP_NETWORK_RESURRECTOR_API_URL}/security`;
|
|
||||||
|
|
||||||
const handleError = err => {
|
|
||||||
let message;
|
|
||||||
switch (err?.status) {
|
|
||||||
case 500:
|
|
||||||
message = err.title;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 404:
|
|
||||||
message = err.message;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
message = err.title;
|
|
||||||
}
|
|
||||||
|
|
||||||
toast.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 getPermissions = (options = defaultOptions) => {
|
|
||||||
const promise = call(() => get(`${securityRoute}/permissions`), options);
|
|
||||||
return promise;
|
|
||||||
};
|
|
||||||
|
|
||||||
const getSystemVersion = (options = defaultOptions) => {
|
|
||||||
const releaseNotesPromise = call(
|
|
||||||
() => get(`${systemRoute}/version`),
|
|
||||||
options
|
|
||||||
);
|
|
||||||
return releaseNotesPromise;
|
|
||||||
};
|
|
||||||
|
|
||||||
const readReleaseNotes = (options = defaultOptions) => {
|
|
||||||
const releaseNotesPromise = call(
|
|
||||||
() => get(`${systemRoute}/release-notes`),
|
|
||||||
options
|
|
||||||
);
|
|
||||||
return releaseNotesPromise;
|
|
||||||
};
|
|
||||||
|
|
||||||
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;
|
|
||||||
};
|
|
||||||
|
|
||||||
const shutdownMachine = (machineId, delay, force, options = defaultOptions) => {
|
|
||||||
const promise = call(
|
|
||||||
() => post(`${powerActionsRoute}/shutdown`, { machineId, delay, force }),
|
|
||||||
options
|
|
||||||
);
|
|
||||||
return promise;
|
|
||||||
};
|
|
||||||
|
|
||||||
const restartMachine = (machineId, delay, force, options = defaultOptions) => {
|
|
||||||
const promise = call(
|
|
||||||
() => post(`${powerActionsRoute}/restart`, { machineId, delay, force }),
|
|
||||||
options
|
|
||||||
);
|
|
||||||
return promise;
|
|
||||||
};
|
|
||||||
|
|
||||||
const useApi = () => {
|
|
||||||
return {
|
|
||||||
getPermissions,
|
|
||||||
getSystemVersion,
|
|
||||||
readReleaseNotes,
|
|
||||||
readMachines,
|
|
||||||
wakeMachine,
|
|
||||||
pingMachine,
|
|
||||||
shutdownMachine,
|
|
||||||
restartMachine
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export default useApi;
|
|
|
@ -1,8 +1,8 @@
|
||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import PropTypes from "prop-types";
|
import PropTypes from "prop-types";
|
||||||
import useApi from "../../../api";
|
|
||||||
import ReleaseNotesList from "./ReleaseNotesList";
|
import ReleaseNotesList from "./ReleaseNotesList";
|
||||||
import TimelineComponent from "../timeline/TimelineComponent";
|
import TimelineComponent from "../timeline/TimelineComponent";
|
||||||
|
import { routes, get } from "../../../utils/api";
|
||||||
|
|
||||||
const sort = releases =>
|
const sort = releases =>
|
||||||
releases.sort((a, b) => new Date(b.date) - new Date(a.date));
|
releases.sort((a, b) => new Date(b.date) - new Date(a.date));
|
||||||
|
@ -10,16 +10,12 @@ const sort = releases =>
|
||||||
const ReleaseNotesContainer = ({ view }) => {
|
const ReleaseNotesContainer = ({ view }) => {
|
||||||
const [state, setState] = useState({ data: [], loaded: false });
|
const [state, setState] = useState({ data: [], loaded: false });
|
||||||
|
|
||||||
const api = useApi();
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (state.loaded) return;
|
if (state.loaded) return;
|
||||||
api.readReleaseNotes({
|
get(routes.releaseNotes, {
|
||||||
onCompleted: data => {
|
onCompleted: data => setState({ data, loaded: true })
|
||||||
setState({ data, loaded: true });
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}, [api, state.loaded]);
|
}, [state.loaded]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
|
@ -1,20 +1,16 @@
|
||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import SystemVersionComponent from "./SystemVersionComponent";
|
import SystemVersionComponent from "./SystemVersionComponent";
|
||||||
import useApi from "../../../api";
|
import { routes, get } from "../../../utils/api";
|
||||||
|
|
||||||
const SystemVersionContainer = () => {
|
const SystemVersionContainer = () => {
|
||||||
const [state, setState] = useState({ data: {}, loaded: false });
|
const [state, setState] = useState({ data: {}, loaded: false });
|
||||||
|
|
||||||
const api = useApi();
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (state.loaded) return;
|
if (state.loaded) return;
|
||||||
api.getSystemVersion({
|
get(routes.systemVersion, {
|
||||||
onCompleted: data => {
|
onCompleted: data => setState({ data, loaded: true })
|
||||||
setState({ data, loaded: true });
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}, [api, state.loaded]);
|
}, [state.loaded]);
|
||||||
|
|
||||||
return <>{state.loaded && <SystemVersionComponent data={state.data} />}</>;
|
return <>{state.loaded && <SystemVersionComponent data={state.data} />}</>;
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { ViewModes } from "./ViewModeSelection";
|
||||||
import { useToast } from "../../../hooks";
|
import { useToast } from "../../../hooks";
|
||||||
import { LastPage, RotateLeft, Launch, Stop } from "@material-ui/icons";
|
import { LastPage, RotateLeft, Launch, Stop } from "@material-ui/icons";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import useApi from "../../../api";
|
import { routes, post } from "../../../utils/api";
|
||||||
|
|
||||||
const MachineContainer = ({ machine, viewMode }) => {
|
const MachineContainer = ({ machine, viewMode }) => {
|
||||||
const [logs, setLogs] = useState([]);
|
const [logs, setLogs] = useState([]);
|
||||||
|
@ -14,8 +14,6 @@ const MachineContainer = ({ machine, viewMode }) => {
|
||||||
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]);
|
||||||
|
@ -37,29 +35,41 @@ const MachineContainer = ({ machine, viewMode }) => {
|
||||||
|
|
||||||
const pingMachine = useCallback(
|
const pingMachine = useCallback(
|
||||||
async machine => {
|
async machine => {
|
||||||
await api.pingMachine(machine.machineId, {
|
await post(
|
||||||
onCompleted: manageActionResponse
|
routes.pingMachine,
|
||||||
});
|
{ machineId: machine.machineId },
|
||||||
|
{
|
||||||
|
onCompleted: manageActionResponse
|
||||||
|
}
|
||||||
|
);
|
||||||
},
|
},
|
||||||
[manageActionResponse, api]
|
[manageActionResponse]
|
||||||
);
|
);
|
||||||
|
|
||||||
const shutdownMachine = useCallback(
|
const shutdownMachine = useCallback(
|
||||||
async machine => {
|
async machine => {
|
||||||
await api.shutdownMachine(machine.machineId, 0, false, {
|
await post(
|
||||||
onCompleted: manageActionResponse
|
routes.shutdownMachine,
|
||||||
});
|
{ machineId: machine.machineId, delay: 0, force: false },
|
||||||
|
{
|
||||||
|
onCompleted: manageActionResponse
|
||||||
|
}
|
||||||
|
);
|
||||||
},
|
},
|
||||||
[manageActionResponse, api]
|
[manageActionResponse]
|
||||||
);
|
);
|
||||||
|
|
||||||
const restartMachine = useCallback(
|
const restartMachine = useCallback(
|
||||||
async machine => {
|
async machine => {
|
||||||
await api.restartMachine(machine.machineId, 0, false, {
|
await post(
|
||||||
onCompleted: manageActionResponse
|
routes.restartMachine,
|
||||||
});
|
{ machineId: machine.machineId, delay: 0, force: false },
|
||||||
|
{
|
||||||
|
onCompleted: manageActionResponse
|
||||||
|
}
|
||||||
|
);
|
||||||
},
|
},
|
||||||
[manageActionResponse, api]
|
[manageActionResponse]
|
||||||
);
|
);
|
||||||
|
|
||||||
const actions = [
|
const actions = [
|
||||||
|
|
|
@ -3,11 +3,11 @@ import {
|
||||||
NetworkStateContext,
|
NetworkStateContext,
|
||||||
NetworkDispatchContext
|
NetworkDispatchContext
|
||||||
} from "../../network/state/contexts";
|
} from "../../network/state/contexts";
|
||||||
import useApi from "../../../api";
|
|
||||||
import MachinesListComponent from "./MachinesListComponent";
|
import MachinesListComponent from "./MachinesListComponent";
|
||||||
import PageTitle from "../../../components/common/PageTitle";
|
import PageTitle from "../../../components/common/PageTitle";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import ViewModeSelection, { ViewModes } from "./ViewModeSelection";
|
import ViewModeSelection, { ViewModes } from "./ViewModeSelection";
|
||||||
|
import { routes, get } from "../../../utils/api";
|
||||||
|
|
||||||
const MachinesContainer = () => {
|
const MachinesContainer = () => {
|
||||||
const [viewMode, setViewMode] = useState(null);
|
const [viewMode, setViewMode] = useState(null);
|
||||||
|
@ -16,16 +16,14 @@ const MachinesContainer = () => {
|
||||||
const dispatchActions = useContext(NetworkDispatchContext);
|
const dispatchActions = useContext(NetworkDispatchContext);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const api = useApi();
|
|
||||||
|
|
||||||
const handleReadMachines = useCallback(async () => {
|
const handleReadMachines = useCallback(async () => {
|
||||||
await api.readMachines({
|
await get(routes.machines, {
|
||||||
onCompleted: machines => {
|
onCompleted: machines => {
|
||||||
const data = Object.assign(machines, { loaded: true });
|
const data = Object.assign(machines, { loaded: true });
|
||||||
dispatchActions.onNetworkChange("machines", data);
|
dispatchActions.onNetworkChange("machines", data);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, [dispatchActions, api]);
|
}, [dispatchActions]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!state.network.machines.loaded) {
|
if (!state.network.machines.loaded) {
|
||||||
|
|
|
@ -5,7 +5,7 @@ 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 { msToMinAndSec } from "../../../../utils/time";
|
import { msToMinAndSec } from "../../../../utils/time";
|
||||||
import useApi from "../../../../api";
|
import { routes, post } from "../../../../utils/api";
|
||||||
|
|
||||||
const initialState = { on: false };
|
const initialState = { on: false };
|
||||||
const defaultPingInterval = 1200000; //20 minutes
|
const defaultPingInterval = 1200000; //20 minutes
|
||||||
|
@ -17,7 +17,6 @@ const WakeComponent = ({ machine, addLog, disabled }) => {
|
||||||
|
|
||||||
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;
|
||||||
|
@ -38,43 +37,51 @@ const WakeComponent = ({ machine, addLog, disabled }) => {
|
||||||
);
|
);
|
||||||
|
|
||||||
const wakeMachine = useCallback(async () => {
|
const wakeMachine = useCallback(async () => {
|
||||||
await api.wakeMachine(machine.machineId, {
|
await post(
|
||||||
onCompleted: result => {
|
routes.wakeMachine,
|
||||||
setState(prev => ({ ...prev, on: result.success }));
|
{ machineId: machine.machineId },
|
||||||
log(`[Wake]: Success: ${result.success}. Status: ${result.status}`);
|
{
|
||||||
if (result.success) {
|
onCompleted: result => {
|
||||||
success(result.status);
|
setState(prev => ({ ...prev, on: result.success }));
|
||||||
|
log(`[Wake]: Success: ${result.success}. Status: ${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, api]);
|
}, [log, success, error, startingTime, machine.machineId]);
|
||||||
|
|
||||||
const pingInLoop = useCallback(async () => {
|
const pingInLoop = useCallback(async () => {
|
||||||
await api.pingMachine(machine.machineId, {
|
await post(
|
||||||
onCompleted: result => {
|
routes.pingMachine,
|
||||||
setState(prev => ({ ...prev, on: result.success }));
|
{ machineId: machine.machineId },
|
||||||
log(`[Ping]: Success: ${result.success}. Status: ${result.status}`);
|
{
|
||||||
|
onCompleted: result => {
|
||||||
|
setState(prev => ({ ...prev, on: result.success }));
|
||||||
|
log(`[Ping]: Success: ${result.success}. Status: ${result.status}`);
|
||||||
|
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
setTrigger(prev => !prev);
|
setTrigger(prev => !prev);
|
||||||
}, pingInterval);
|
}, pingInterval);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onError: () => {}
|
onError: () => {}
|
||||||
});
|
}
|
||||||
|
);
|
||||||
}, [machine, log, pingInterval]); // eslint-disable-line react-hooks/exhaustive-deps
|
}, [machine, log, pingInterval]); // eslint-disable-line react-hooks/exhaustive-deps
|
||||||
// if "api" is added in pingInLoop dependencies, the useEffect is triggered in loop
|
// if "api" is added in pingInLoop dependencies, the useEffect is triggered in loop
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import React, { useState, useEffect, useContext, useMemo } from "react";
|
import React, { useState, useEffect, useContext, useMemo } from "react";
|
||||||
import PropTypes from "prop-types";
|
import PropTypes from "prop-types";
|
||||||
import useApi from "../api";
|
import { routes, get } from "../utils/api";
|
||||||
|
|
||||||
const permissionCodes = {
|
const permissionCodes = {
|
||||||
VIEW_DASHBOARD: "VIEW_DASHBOARD",
|
VIEW_DASHBOARD: "VIEW_DASHBOARD",
|
||||||
|
@ -64,13 +64,11 @@ const usePermissions = () => {
|
||||||
const UserPermissionsProvider = ({ children }) => {
|
const UserPermissionsProvider = ({ children }) => {
|
||||||
const [permissions, setPermissions] = useState(initialState);
|
const [permissions, setPermissions] = useState(initialState);
|
||||||
|
|
||||||
const { getPermissions } = useApi();
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getPermissions({
|
get(routes.permissions, {
|
||||||
onCompleted: data => setPermissions({ ...data, loading: false })
|
onCompleted: data => setPermissions({ ...data, loading: false })
|
||||||
});
|
});
|
||||||
}, [getPermissions]);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<UserPermissionsContext.Provider value={permissions}>
|
<UserPermissionsContext.Provider value={permissions}>
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
import * as axios from "../utils/axios";
|
||||||
|
import { toast } from "react-toastify";
|
||||||
|
|
||||||
|
const networkRoute = `${process.env.REACT_APP_NETWORK_RESURRECTOR_API_URL}/network`;
|
||||||
|
const systemRoute = `${process.env.REACT_APP_NETWORK_RESURRECTOR_API_URL}/system`;
|
||||||
|
const powerActionsRoute = `${process.env.REACT_APP_NETWORK_RESURRECTOR_API_URL}/resurrector`;
|
||||||
|
const securityRoute = `${process.env.REACT_APP_NETWORK_RESURRECTOR_API_URL}/security`;
|
||||||
|
|
||||||
|
const routes = {
|
||||||
|
permissions: `${securityRoute}/permissions`,
|
||||||
|
systemVersion: `${systemRoute}/version`,
|
||||||
|
releaseNotes: `${systemRoute}/release-notes`,
|
||||||
|
machines: `${networkRoute}/machines`,
|
||||||
|
wakeMachine: `${powerActionsRoute}/wake`,
|
||||||
|
pingMachine: `${powerActionsRoute}/ping`,
|
||||||
|
shutdownMachine: `${powerActionsRoute}/shutdown`,
|
||||||
|
restartMachine: `${powerActionsRoute}/restart`
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleError = err => {
|
||||||
|
let message;
|
||||||
|
switch (err?.status) {
|
||||||
|
case 500:
|
||||||
|
message = err.title;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 404:
|
||||||
|
message = err.message;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
message = err.title;
|
||||||
|
}
|
||||||
|
|
||||||
|
toast.error(message);
|
||||||
|
};
|
||||||
|
|
||||||
|
const defaultOptions = {
|
||||||
|
onCompleted: () => {},
|
||||||
|
onError: handleError
|
||||||
|
};
|
||||||
|
|
||||||
|
const call = async (request, options = defaultOptions) => {
|
||||||
|
const internalOptions = { ...defaultOptions, ...options };
|
||||||
|
const { onCompleted, onError } = internalOptions;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const result = await request();
|
||||||
|
onCompleted(result);
|
||||||
|
} catch (error) {
|
||||||
|
onError(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const get = (route, options) => {
|
||||||
|
const promise = call(() => axios.get(route), options);
|
||||||
|
return promise;
|
||||||
|
};
|
||||||
|
|
||||||
|
const post = (route, data, options) => {
|
||||||
|
const promise = call(() => axios.post(route, data), options);
|
||||||
|
return promise;
|
||||||
|
};
|
||||||
|
|
||||||
|
export { routes, get, post };
|
Loading…
Reference in New Issue