From 3a211bcb172f90ef3212982d516c9478c65c5407 Mon Sep 17 00:00:00 2001 From: Tudor Stanciu Date: Sat, 15 Apr 2023 00:53:11 +0300 Subject: [PATCH] refactoring api integration --- src/api/index.js | 3 - src/api/useApi.js | 115 ------------------ .../releaseNotes/ReleaseNotesContainer.js | 12 +- .../about/system/SystemVersionContainer.js | 12 +- .../machines/components/MachineContainer.js | 40 +++--- .../machines/components/MachinesContainer.js | 8 +- .../components/common/WakeComponent.js | 73 ++++++----- src/providers/UserPermissionsProvider.js | 8 +- src/utils/api.js | 65 ++++++++++ 9 files changed, 144 insertions(+), 192 deletions(-) delete mode 100644 src/api/index.js delete mode 100644 src/api/useApi.js create mode 100644 src/utils/api.js diff --git a/src/api/index.js b/src/api/index.js deleted file mode 100644 index 3ee57a3..0000000 --- a/src/api/index.js +++ /dev/null @@ -1,3 +0,0 @@ -import useApi from "./useApi"; - -export default useApi; diff --git a/src/api/useApi.js b/src/api/useApi.js deleted file mode 100644 index 388cfd8..0000000 --- a/src/api/useApi.js +++ /dev/null @@ -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; diff --git a/src/features/about/releaseNotes/ReleaseNotesContainer.js b/src/features/about/releaseNotes/ReleaseNotesContainer.js index 25aff8a..29efc6b 100644 --- a/src/features/about/releaseNotes/ReleaseNotesContainer.js +++ b/src/features/about/releaseNotes/ReleaseNotesContainer.js @@ -1,8 +1,8 @@ import React, { useState, useEffect } from "react"; import PropTypes from "prop-types"; -import useApi from "../../../api"; import ReleaseNotesList from "./ReleaseNotesList"; import TimelineComponent from "../timeline/TimelineComponent"; +import { routes, get } from "../../../utils/api"; const sort = releases => releases.sort((a, b) => new Date(b.date) - new Date(a.date)); @@ -10,16 +10,12 @@ const sort = releases => const ReleaseNotesContainer = ({ view }) => { const [state, setState] = useState({ data: [], loaded: false }); - const api = useApi(); - useEffect(() => { if (state.loaded) return; - api.readReleaseNotes({ - onCompleted: data => { - setState({ data, loaded: true }); - } + get(routes.releaseNotes, { + onCompleted: data => setState({ data, loaded: true }) }); - }, [api, state.loaded]); + }, [state.loaded]); return ( <> diff --git a/src/features/about/system/SystemVersionContainer.js b/src/features/about/system/SystemVersionContainer.js index a990954..c4731fa 100644 --- a/src/features/about/system/SystemVersionContainer.js +++ b/src/features/about/system/SystemVersionContainer.js @@ -1,20 +1,16 @@ import React, { useState, useEffect } from "react"; import SystemVersionComponent from "./SystemVersionComponent"; -import useApi from "../../../api"; +import { routes, get } from "../../../utils/api"; const SystemVersionContainer = () => { const [state, setState] = useState({ data: {}, loaded: false }); - const api = useApi(); - useEffect(() => { if (state.loaded) return; - api.getSystemVersion({ - onCompleted: data => { - setState({ data, loaded: true }); - } + get(routes.systemVersion, { + onCompleted: data => setState({ data, loaded: true }) }); - }, [api, state.loaded]); + }, [state.loaded]); return <>{state.loaded && }; }; diff --git a/src/features/machines/components/MachineContainer.js b/src/features/machines/components/MachineContainer.js index 4674cf4..c7b128f 100644 --- a/src/features/machines/components/MachineContainer.js +++ b/src/features/machines/components/MachineContainer.js @@ -6,7 +6,7 @@ import { ViewModes } from "./ViewModeSelection"; import { useToast } from "../../../hooks"; import { LastPage, RotateLeft, Launch, Stop } from "@material-ui/icons"; import { useTranslation } from "react-i18next"; -import useApi from "../../../api"; +import { routes, post } from "../../../utils/api"; const MachineContainer = ({ machine, viewMode }) => { const [logs, setLogs] = useState([]); @@ -14,8 +14,6 @@ const MachineContainer = ({ machine, viewMode }) => { const { success, error } = useToast(); const { t } = useTranslation(); - const api = useApi(); - const addLog = useCallback( text => { setLogs(prev => [...prev, text]); @@ -37,29 +35,41 @@ const MachineContainer = ({ machine, viewMode }) => { const pingMachine = useCallback( async machine => { - await api.pingMachine(machine.machineId, { - onCompleted: manageActionResponse - }); + await post( + routes.pingMachine, + { machineId: machine.machineId }, + { + onCompleted: manageActionResponse + } + ); }, - [manageActionResponse, api] + [manageActionResponse] ); const shutdownMachine = useCallback( async machine => { - await api.shutdownMachine(machine.machineId, 0, false, { - onCompleted: manageActionResponse - }); + await post( + routes.shutdownMachine, + { machineId: machine.machineId, delay: 0, force: false }, + { + onCompleted: manageActionResponse + } + ); }, - [manageActionResponse, api] + [manageActionResponse] ); const restartMachine = useCallback( async machine => { - await api.restartMachine(machine.machineId, 0, false, { - onCompleted: manageActionResponse - }); + await post( + routes.restartMachine, + { machineId: machine.machineId, delay: 0, force: false }, + { + onCompleted: manageActionResponse + } + ); }, - [manageActionResponse, api] + [manageActionResponse] ); const actions = [ diff --git a/src/features/machines/components/MachinesContainer.js b/src/features/machines/components/MachinesContainer.js index a0a4103..33263b8 100644 --- a/src/features/machines/components/MachinesContainer.js +++ b/src/features/machines/components/MachinesContainer.js @@ -3,11 +3,11 @@ import { NetworkStateContext, NetworkDispatchContext } from "../../network/state/contexts"; -import useApi from "../../../api"; import MachinesListComponent from "./MachinesListComponent"; import PageTitle from "../../../components/common/PageTitle"; import { useTranslation } from "react-i18next"; import ViewModeSelection, { ViewModes } from "./ViewModeSelection"; +import { routes, get } from "../../../utils/api"; const MachinesContainer = () => { const [viewMode, setViewMode] = useState(null); @@ -16,16 +16,14 @@ const MachinesContainer = () => { const dispatchActions = useContext(NetworkDispatchContext); const { t } = useTranslation(); - const api = useApi(); - const handleReadMachines = useCallback(async () => { - await api.readMachines({ + await get(routes.machines, { onCompleted: machines => { const data = Object.assign(machines, { loaded: true }); dispatchActions.onNetworkChange("machines", data); } }); - }, [dispatchActions, api]); + }, [dispatchActions]); useEffect(() => { if (!state.network.machines.loaded) { diff --git a/src/features/machines/components/common/WakeComponent.js b/src/features/machines/components/common/WakeComponent.js index f118c9a..98bbd5a 100644 --- a/src/features/machines/components/common/WakeComponent.js +++ b/src/features/machines/components/common/WakeComponent.js @@ -5,7 +5,7 @@ import { PowerSettingsNew } from "@material-ui/icons"; import { useTranslation } from "react-i18next"; import { useToast } from "../../../../hooks"; import { msToMinAndSec } from "../../../../utils/time"; -import useApi from "../../../../api"; +import { routes, post } from "../../../../utils/api"; const initialState = { on: false }; const defaultPingInterval = 1200000; //20 minutes @@ -17,7 +17,6 @@ const WakeComponent = ({ machine, addLog, disabled }) => { const { t } = useTranslation(); const { success, error } = useToast(); - const api = useApi(); const pingInterval = process.env.REACT_APP_MACHINE_PING_INTERVAL || defaultPingInterval; @@ -38,43 +37,51 @@ const WakeComponent = ({ machine, addLog, disabled }) => { ); const wakeMachine = useCallback(async () => { - await api.wakeMachine(machine.machineId, { - onCompleted: result => { - setState(prev => ({ ...prev, on: result.success })); - log(`[Wake]: Success: ${result.success}. Status: ${result.status}`); - if (result.success) { - success(result.status); + await post( + routes.wakeMachine, + { machineId: machine.machineId }, + { + onCompleted: result => { + setState(prev => ({ ...prev, on: result.success })); + log(`[Wake]: Success: ${result.success}. Status: ${result.status}`); + if (result.success) { + success(result.status); - //retrigger - log( - `Periodic ping will be re-triggered in ${startingTime} ms [${msToMinAndSec( - startingTime - )}]` - ); - setTimeout(() => { - setTrigger(prev => !prev); - }, startingTime); - } else { - error(result.status); + //retrigger + log( + `Periodic ping will be re-triggered in ${startingTime} ms [${msToMinAndSec( + startingTime + )}]` + ); + setTimeout(() => { + setTrigger(prev => !prev); + }, startingTime); + } else { + error(result.status); + } } } - }); - }, [log, success, error, startingTime, machine.machineId, api]); + ); + }, [log, success, error, startingTime, machine.machineId]); 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}`); + await post( + routes.pingMachine, + { machineId: 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: () => {} - }); + 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 diff --git a/src/providers/UserPermissionsProvider.js b/src/providers/UserPermissionsProvider.js index 297d674..92dfe45 100644 --- a/src/providers/UserPermissionsProvider.js +++ b/src/providers/UserPermissionsProvider.js @@ -1,6 +1,6 @@ import React, { useState, useEffect, useContext, useMemo } from "react"; import PropTypes from "prop-types"; -import useApi from "../api"; +import { routes, get } from "../utils/api"; const permissionCodes = { VIEW_DASHBOARD: "VIEW_DASHBOARD", @@ -64,13 +64,11 @@ const usePermissions = () => { const UserPermissionsProvider = ({ children }) => { const [permissions, setPermissions] = useState(initialState); - const { getPermissions } = useApi(); - useEffect(() => { - getPermissions({ + get(routes.permissions, { onCompleted: data => setPermissions({ ...data, loading: false }) }); - }, [getPermissions]); + }, []); return ( diff --git a/src/utils/api.js b/src/utils/api.js new file mode 100644 index 0000000..a116652 --- /dev/null +++ b/src/utils/api.js @@ -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 };