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
This commit is contained in:
Liordino Neto 2020-10-30 12:08:29 -03:00 committed by Josh Harvey
parent f10b49f31c
commit 3a5bbbca1f
4 changed files with 59 additions and 43 deletions

View file

@ -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)
}

View file

@ -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

View file

@ -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(
</DialogTitle>
)}
<DialogContent className={classes.dialogContent}>
{message && <P>{message}</P>}
<TextInput
label={confirmationMessage}
name="confirm-input"

View file

@ -69,18 +69,10 @@ const Item = ({ children, ...props }) => (
)
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 (
<>
<Container className={classes.wrapper}>
@ -134,43 +127,25 @@ const MachineDetailsRow = ({ it: machine, onActionSuccess }) => {
className={classes.separator}
/>
<ConfirmDialog
open={renameActionDialogOpen}
title={`Rename this machine?`}
initialValue={machine.name}
open={confirmDialogOpen}
title={`${action?.command} this machine?`}
errorMessage={errorMessage}
confirmationMessage={`Write the new name for this machine`}
saveButtonAlwaysEnabled={true}
toBeConfirmed={machine.name}
message={action?.message}
confirmationMessage={action?.confirmationMessage}
saveButtonAlwaysEnabled={action?.command === 'Rename'}
onConfirmed={value => {
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)
}}
/>
<ConfirmDialog
open={confirmActionDialogOpen}
title={`${action} this machine?`}
errorMessage={errorMessage}
toBeConfirmed={machine.name}
onConfirmed={() => {
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
</ActionButton>
<ActionButton
@ -206,7 +186,11 @@ const MachineDetailsRow = ({ it: machine, onActionSuccess }) => {
Icon={UnpairIcon}
InverseIcon={UnpairReversedIcon}
disabled={loading}
onClick={() => confirmActionDialog('Unpair')}>
onClick={() =>
setAction({
command: 'Unpair'
})
}>
Unpair
</ActionButton>
<ActionButton
@ -215,7 +199,11 @@ const MachineDetailsRow = ({ it: machine, onActionSuccess }) => {
Icon={RebootIcon}
InverseIcon={RebootReversedIcon}
disabled={loading}
onClick={() => confirmActionDialog('Reboot')}>
onClick={() =>
setAction({
command: 'Reboot'
})
}>
Reboot
</ActionButton>
<ActionButton
@ -224,7 +212,13 @@ const MachineDetailsRow = ({ it: machine, onActionSuccess }) => {
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
</ActionButton>
</div>