From 8eb5f0caa0ea07eb8d1844e352a509e660daa0dc Mon Sep 17 00:00:00 2001 From: Tudor Stanciu Date: Tue, 18 Jan 2022 17:18:30 +0200 Subject: [PATCH] Shutdown and restart actions --- private/Notes.txt | 7 +- public/locales/en/translations.json | 6 +- public/locales/ro/translations.json | 6 +- src/api/useApi.js | 39 ++++++- src/features/machines/components/Machine.js | 82 ++++++++++---- .../machines/components/MachineContainer.js | 107 ++++++++++++++++-- 6 files changed, 211 insertions(+), 36 deletions(-) diff --git a/private/Notes.txt b/private/Notes.txt index 72db9b2..170bf0d 100644 --- a/private/Notes.txt +++ b/private/Notes.txt @@ -12,4 +12,9 @@ Log-ul va fi popup iar continutul lui poate fi ultima componenta de aici https:/ https://medium.com/@tacomanator/environments-with-create-react-app-7b645312c09d https://create-react-app.dev/docs/adding-custom-environment-variables/ -https://stackoverflow.com/questions/55690143/what-is-the-difference-between-env-local-and-env-development-local \ No newline at end of file +https://stackoverflow.com/questions/55690143/what-is-the-difference-between-env-local-and-env-development-local + + +REACT v4: +https://v4.mui.com/getting-started/installation/ +https://v4.mui.com/components/material-icons/ \ No newline at end of file diff --git a/public/locales/en/translations.json b/public/locales/en/translations.json index 096dc71..6e31cfb 100644 --- a/public/locales/en/translations.json +++ b/public/locales/en/translations.json @@ -36,7 +36,11 @@ "PoweredOn": "Powered on", "Actions": { "Wake": "Wake", - "Ping": "Ping" + "Ping": "Ping", + "More": "More", + "Shutdown": "Shutdown", + "Restart": "Restart", + "Advanced": "Advanced" } } } diff --git a/public/locales/ro/translations.json b/public/locales/ro/translations.json index 4cd80b4..8b25ec5 100644 --- a/public/locales/ro/translations.json +++ b/public/locales/ro/translations.json @@ -27,7 +27,11 @@ "PoweredOn": "Pornit", "Actions": { "Wake": "Pornește", - "Ping": "Ping" + "Ping": "Ping", + "More": "Mai mult", + "Shutdown": "Oprește", + "Restart": "Repornește", + "Advanced": "Avansat" } } } diff --git a/src/api/useApi.js b/src/api/useApi.js index 06ddacd..d430b46 100644 --- a/src/api/useApi.js +++ b/src/api/useApi.js @@ -25,7 +25,10 @@ const useApi = () => { error(message); }; - const defaultOptions = { onCompleted: () => {}, onError: handleError }; + const defaultOptions = { + onCompleted: () => {}, + onError: handleError + }; const call = async (request, options) => { const internalOptions = { ...defaultOptions, ...options }; @@ -63,7 +66,39 @@ const useApi = () => { return promise; }; - return { readMachines, wakeMachine, pingMachine }; + 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; + }; + + return { + readMachines, + wakeMachine, + pingMachine, + shutdownMachine, + restartMachine + }; }; export default useApi; diff --git a/src/features/machines/components/Machine.js b/src/features/machines/components/Machine.js index 6e163e7..946adac 100644 --- a/src/features/machines/components/Machine.js +++ b/src/features/machines/components/Machine.js @@ -1,11 +1,12 @@ -import React from "react"; +import React, { useMemo } from "react"; import PropTypes from "prop-types"; import { TableCell, TableRow, IconButton, Collapse, - Tooltip + Tooltip, + Menu } from "@material-ui/core"; import { KeyboardArrowDown, KeyboardArrowUp } from "@material-ui/icons"; import { makeStyles } from "@material-ui/core/styles"; @@ -20,10 +21,46 @@ const useRowStyles = makeStyles({ } }); -const Machine = ({ machine, actions, logs, addLog }) => { +const ActionButton = React.forwardRef((props, _ref) => { + const { action, machine } = props; + return ( + + + + + + + + ); +}); + +const Machine = ({ + machine, + actions, + logs, + addLog, + secondaryActionsMenuProps +}) => { const [open, setOpen] = React.useState(false); const classes = useRowStyles(); + const topActions = useMemo( + () => actions.filter(a => a.top === true), + [actions] + ); + + const secondaryActions = useMemo( + () => actions.filter(a => a.top === false), + [actions] + ); + return ( @@ -44,22 +81,28 @@ const Machine = ({ machine, actions, logs, addLog }) => { {machine.macAddress} - {actions.map(action => ( - - - - - - - + {topActions.map(action => ( + ))} + + {secondaryActions.map(action => ( + + ))} + @@ -84,7 +127,8 @@ Machine.propTypes = { }).isRequired, actions: PropTypes.array.isRequired, logs: PropTypes.array.isRequired, - addLog: PropTypes.func.isRequired + addLog: PropTypes.func.isRequired, + secondaryActionsMenuProps: PropTypes.object.isRequired }; export default Machine; diff --git a/src/features/machines/components/MachineContainer.js b/src/features/machines/components/MachineContainer.js index c9c0cce..9c74b27 100644 --- a/src/features/machines/components/MachineContainer.js +++ b/src/features/machines/components/MachineContainer.js @@ -2,12 +2,21 @@ import React, { useState, useCallback } from "react"; import PropTypes from "prop-types"; import Machine from "./Machine"; import { useToast } from "../../../hooks"; -import { LastPage } from "@material-ui/icons"; +import { + LastPage, + MoreHoriz, + RotateLeft, + Launch, + Stop +} from "@material-ui/icons"; import { useTranslation } from "react-i18next"; import useApi from "../../../api"; const MachineContainer = ({ machine }) => { const [logs, setLogs] = useState([]); + const [secondaryActionsAnchor, setSecondaryActionsAnchor] = + React.useState(null); + const { success, error } = useToast(); const { t } = useTranslation(); @@ -20,20 +29,58 @@ const MachineContainer = ({ machine }) => { [setLogs] ); + const manageActionResponse = useCallback( + response => { + addLog(`Success: ${response.success}. Status: ${response.status}`); + if (response.success) { + success(response.status); + } else { + error(response.status); + } + }, + [error, success, addLog] + ); + const pingMachine = useCallback( machine => async () => { await api.pingMachine(machine.machineId, { - onCompleted: result => { - addLog(`Success: ${result.success}. Status: ${result.status}`); - if (result.success) { - success(result.status); - } else { - error(result.status); - } - } + onCompleted: manageActionResponse }); }, - [error, success, addLog, api] + [manageActionResponse, api] + ); + + const handleOpenSecondaryActions = event => { + setSecondaryActionsAnchor(event.currentTarget); + }; + + const handleCloseSecondaryActions = () => { + setSecondaryActionsAnchor(null); + }; + + const secondaryActionsMenuProps = { + anchor: secondaryActionsAnchor, + onCloseSecondaryActions: handleCloseSecondaryActions + }; + + const shutdownMachine = useCallback( + machine => async () => { + await api.shutdownMachine(machine.machineId, 0, false, { + onCompleted: manageActionResponse + }); + handleCloseSecondaryActions(); + }, + [manageActionResponse, api] + ); + + const restartMachine = useCallback( + machine => async () => { + await api.restartMachine(machine.machineId, 0, false, { + onCompleted: manageActionResponse + }); + handleCloseSecondaryActions(); + }, + [manageActionResponse, api] ); const actions = [ @@ -41,12 +88,48 @@ const MachineContainer = ({ machine }) => { code: "ping", effect: pingMachine, icon: LastPage, - tooltip: t("Machine.Actions.Ping") + tooltip: t("Machine.Actions.Ping"), + top: true + }, + { + code: "more", + effect: handleOpenSecondaryActions, + icon: MoreHoriz, + tooltip: t("Machine.Actions.More"), + top: true, + system: true + }, + { + code: "shutdown", + effect: shutdownMachine, + icon: Stop, + tooltip: t("Machine.Actions.Shutdown"), + top: false + }, + { + code: "restart", + effect: restartMachine, + icon: RotateLeft, + tooltip: t("Machine.Actions.Restart"), + top: false + }, + { + code: "advanced", + effect: () => {}, + icon: Launch, + tooltip: t("Machine.Actions.Advanced"), + top: false } ]; return ( - + ); };