From 3a5bbbca1f2755ba2be13d0e5903d080554608b2 Mon Sep 17 00:00:00 2001 From: Liordino Neto Date: Fri, 30 Oct 2020 12:08:29 -0300 Subject: [PATCH] feat: added shutdown function to the machine loader feat: created shutdown route and call it from gql server (called from admin UI button) feat: added an extra message property to the ConfirmDialog refactor: simplified the MachineDetailsCard component feat: added an extra information message to the Shutdown machine action --- lib/machine-loader.js | 5 ++ lib/routes.js | 15 ++++ .../src/components/ConfirmDialog.js | 4 +- .../pages/Maintenance/MachineDetailsCard.js | 78 +++++++++---------- 4 files changed, 59 insertions(+), 43 deletions(-) diff --git a/lib/machine-loader.js b/lib/machine-loader.js index cc7d350f..68c06734 100644 --- a/lib/machine-loader.js +++ b/lib/machine-loader.js @@ -111,6 +111,10 @@ function reboot (rec) { return axios.post(`http://localhost:3030/reboot?device_id=${rec.deviceId}`) } +function shutdown (rec) { + return axios.post(`http://localhost:3030/shutdown?device_id=${rec.deviceId}`) +} + function restartServices (rec) { return axios.post(`http://localhost:3030/restartServices?device_id=${rec.deviceId}`) } @@ -122,6 +126,7 @@ function setMachine (rec) { case 'resetCashOutBills': return resetCashOutBills(rec) case 'unpair': return unpair(rec) case 'reboot': return reboot(rec) + case 'shutdown': return shutdown(rec) case 'restartServices': return restartServices(rec) default: throw new Error('No such action: ' + rec.action) } diff --git a/lib/routes.js b/lib/routes.js index 76612e2b..5b3fbc25 100644 --- a/lib/routes.js +++ b/lib/routes.js @@ -38,6 +38,7 @@ const SETTINGS_CACHE_REFRESH = 60 * 60 * 1000 const pids = {} const reboots = {} +const shutdowns = {} const restartServicesMap = {} const canGetLastSeenMap = {} const canLogClockSkewMap = {} @@ -74,6 +75,7 @@ function poll (req, res, next) { const cassettes = results.cassettes const reboot = pid && reboots[deviceId] && reboots[deviceId] === pid + const shutdown = pid && shutdowns[deviceId] && shutdowns[deviceId] === pid const restartServices = pid && restartServicesMap[deviceId] && restartServicesMap[deviceId] === pid const langs = localeConfig.languages @@ -95,6 +97,7 @@ function poll (req, res, next) { twoWayMode: cashOutConfig.active, zeroConfLimit: cashOutConfig.zeroConfLimit, reboot, + shutdown, restartServices, hasLightning, receipt, @@ -510,6 +513,18 @@ localApp.post('/reboot', (req, res) => { res.sendStatus(200) }) +localApp.post('/shutdown', (req, res) => { + const deviceId = req.query.device_id + const pid = pids[deviceId] && pids[deviceId].pid + + if (!deviceId || !pid) { + return res.sendStatus(400) + } + + shutdowns[deviceId] = pid + res.sendStatus(200) +}) + localApp.post('/restartServices', (req, res) => { const deviceId = req.query.device_id const pid = pids[deviceId] && pids[deviceId].pid diff --git a/new-lamassu-admin/src/components/ConfirmDialog.js b/new-lamassu-admin/src/components/ConfirmDialog.js index 1a2fa4a3..294b2bd7 100644 --- a/new-lamassu-admin/src/components/ConfirmDialog.js +++ b/new-lamassu-admin/src/components/ConfirmDialog.js @@ -8,7 +8,7 @@ import React, { memo, useState } from 'react' import { Button, IconButton } from 'src/components/buttons' import { TextInput } from 'src/components/inputs' -import { H4 } from 'src/components/typography' +import { H4, P } from 'src/components/typography' import { ReactComponent as CloseIcon } from 'src/styling/icons/action/close/zodiac.svg' import { spacer } from 'src/styling/variables' @@ -60,6 +60,7 @@ export const ConfirmDialog = memo( open, toBeConfirmed, saveButtonAlwaysEnabled = false, + message, confirmationMessage = `Write '${toBeConfirmed}' to confirm this action`, onConfirmed, onDissmised, @@ -98,6 +99,7 @@ export const ConfirmDialog = memo( )} + {message &&

{message}

} ( ) const MachineDetailsRow = ({ it: machine, onActionSuccess }) => { - const [action, setAction] = useState('') - const [renameActionDialogOpen, setRenameActionDialogOpen] = useState(false) - const [confirmActionDialogOpen, setConfirmActionDialogOpen] = useState(false) + const [action, setAction] = useState(null) const [errorMessage, setErrorMessage] = useState(null) const classes = useMDStyles() - const confirmActionDialog = action => - setAction(action) || setConfirmActionDialogOpen(true) - - const renameActionDialog = () => - setAction('Rename') || setRenameActionDialogOpen(true) - const [machineAction, { loading }] = useMutation(MACHINE_ACTION, { onError: ({ message }) => { const errorMessage = message ?? 'An error ocurred' @@ -88,11 +80,12 @@ const MachineDetailsRow = ({ it: machine, onActionSuccess }) => { }, onCompleted: () => { onActionSuccess && onActionSuccess() - setConfirmActionDialogOpen(false) - setRenameActionDialogOpen(false) + setAction(null) } }) + const confirmDialogOpen = Boolean(action) + return ( <> @@ -134,43 +127,25 @@ const MachineDetailsRow = ({ it: machine, onActionSuccess }) => { className={classes.separator} /> { setErrorMessage(null) machineAction({ variables: { deviceId: machine.deviceId, - action: `${action}`.toLowerCase(), - newName: value + action: `${action?.command}`.toLowerCase(), + ...(action?.command === 'Rename' && { newName: value }) } }) }} onDissmised={() => { - setRenameActionDialogOpen(false) - setErrorMessage(null) - }} - /> - { - setErrorMessage(null) - machineAction({ - variables: { - deviceId: machine.deviceId, - action: `${action}`.toLowerCase() - } - }) - }} - onDissmised={() => { - setConfirmActionDialogOpen(false) + setAction(null) setErrorMessage(null) }} /> @@ -197,7 +172,12 @@ const MachineDetailsRow = ({ it: machine, onActionSuccess }) => { color="primary" Icon={EditIcon} InverseIcon={EditReversedIcon} - onClick={() => renameActionDialog()}> + onClick={() => + setAction({ + command: 'Rename', + confirmationMessage: 'Write the new name for this machine' + }) + }> Rename { Icon={UnpairIcon} InverseIcon={UnpairReversedIcon} disabled={loading} - onClick={() => confirmActionDialog('Unpair')}> + onClick={() => + setAction({ + command: 'Unpair' + }) + }> Unpair { Icon={RebootIcon} InverseIcon={RebootReversedIcon} disabled={loading} - onClick={() => confirmActionDialog('Reboot')}> + onClick={() => + setAction({ + command: 'Reboot' + }) + }> Reboot { color="primary" Icon={ShutdownIcon} InverseIcon={ShutdownReversedIcon} - onClick={() => confirmActionDialog('Shutdown')}> + onClick={() => + setAction({ + command: 'Shutdown', + message: + 'In order to bring it back online, the machine will need to be visited and its power reset.' + }) + }> Shutdown