feat: add multicassette support on the dashboard

This commit is contained in:
Sérgio Salgado 2021-10-27 17:26:20 +01:00
parent f32d02a808
commit 18ab230951
7 changed files with 143 additions and 147 deletions

View file

@ -105,6 +105,7 @@ function getMachine (machineId, config) {
cassette2: r.cassette2, cassette2: r.cassette2,
cassette3: r.cassette3, cassette3: r.cassette3,
cassette4: r.cassette4, cassette4: r.cassette4,
numberOfCassettes: r.number_of_cassettes,
version: r.version, version: r.version,
model: r.model, model: r.model,
pairedAt: new Date(r.created), pairedAt: new Date(r.created),

View file

@ -10,7 +10,6 @@ const useStyles = makeStyles({
display: 'flex' display: 'flex'
}, },
cashCassette: { cashCassette: {
width: 80,
height: 36, height: 36,
marginRight: 14 marginRight: 14
} }

View file

@ -6,6 +6,7 @@ import TableContainer from '@material-ui/core/TableContainer'
import TableHead from '@material-ui/core/TableHead' import TableHead from '@material-ui/core/TableHead'
import TableRow from '@material-ui/core/TableRow' import TableRow from '@material-ui/core/TableRow'
import classnames from 'classnames' import classnames from 'classnames'
import * as R from 'ramda'
import React from 'react' import React from 'react'
import { useHistory } from 'react-router-dom' import { useHistory } from 'react-router-dom'
@ -60,6 +61,10 @@ const MachinesTable = ({ machines, numToRender }) => {
}) })
} }
const maxNumberOfCassettes = Math.max(
...R.map(it => it.numberOfCassettes, machines)
)
return ( return (
<TableContainer className={classes.table}> <TableContainer className={classes.table}>
<Table> <Table>
@ -80,18 +85,17 @@ const MachinesTable = ({ machines, numToRender }) => {
<TxInIcon /> <TxInIcon />
</div> </div>
</HeaderCell> */} </HeaderCell> */}
{R.map(
it => (
<HeaderCell> <HeaderCell>
<div className={classes.header}> <div className={classes.header}>
<TxOutIcon /> <TxOutIcon />
<Label2 className={classes.label}> 1</Label2> <Label2 className={classes.label}> {it + 1}</Label2>
</div>
</HeaderCell>
<HeaderCell>
<div className={classes.header}>
<TxOutIcon />
<Label2 className={classes.label}> 2</Label2>
</div> </div>
</HeaderCell> </HeaderCell>
),
R.times(R.identity, maxNumberOfCassettes)
)}
</TableRow> </TableRow>
</TableHead> </TableHead>
<TableBody> <TableBody>
@ -120,12 +124,19 @@ const MachinesTable = ({ machines, numToRender }) => {
{/* <StyledCell align="left"> {/* <StyledCell align="left">
{makePercentageText(machine.cashbox)} {makePercentageText(machine.cashbox)}
</StyledCell> */} </StyledCell> */}
{R.map(
it =>
machine.numberOfCassettes > it ? (
<StyledCell align="left"> <StyledCell align="left">
{makePercentageText(machine.cassette1)} {makePercentageText(machine[`cassette${it + 1}`])}
</StyledCell> </StyledCell>
) : (
<StyledCell align="left"> <StyledCell align="left">
{makePercentageText(machine.cassette2)} <TL2>{`— %`}</TL2>
</StyledCell> </StyledCell>
),
R.times(R.identity, maxNumberOfCassettes)
)}
</TableRow> </TableRow>
) )
} }

View file

@ -27,6 +27,9 @@ const GET_DATA = gql`
cashbox cashbox
cassette1 cassette1
cassette2 cassette2
cassette3
cassette4
numberOfCassettes
statuses { statuses {
label label
type type

View file

@ -1,18 +1,26 @@
/* eslint-disable no-unused-vars */
import { useMutation } from '@apollo/react-hooks' import { useMutation } from '@apollo/react-hooks'
import { makeStyles } from '@material-ui/core' import { makeStyles } from '@material-ui/core'
import gql from 'graphql-tag' import gql from 'graphql-tag'
import * as R from 'ramda'
import React from 'react' import React from 'react'
import * as Yup from 'yup' import * as Yup from 'yup'
import { Table as EditableTable } from 'src/components/editableTable' import { Table as EditableTable } from 'src/components/editableTable'
import { CashOut, CashIn } from 'src/components/inputs/cashbox/Cashbox' import { CashOut, CashIn } from 'src/components/inputs/cashbox/Cashbox'
import { NumberInput } from 'src/components/inputs/formik' import { NumberInput, CashCassetteInput } from 'src/components/inputs/formik'
import { fromNamespace } from 'src/utils/config' import { fromNamespace } from 'src/utils/config'
import styles from './Cassettes.styles' import styles from './Cassettes.styles'
const useStyles = makeStyles(styles) const useStyles = makeStyles(styles)
const widthsByNumberOfCassettes = {
2: { cashbox: 116, cassette: 280, cassetteGraph: 80, editWidth: 174 },
3: { cashbox: 106, cassette: 200, cassetteGraph: 60, editWidth: 145 },
4: { cashbox: 106, cassette: 164, cassetteGraph: 40, editWidth: 90 }
}
const ValidationSchema = Yup.object().shape({ const ValidationSchema = Yup.object().shape({
name: Yup.string().required('Required'), name: Yup.string().required('Required'),
cashbox: Yup.number() cashbox: Yup.number()
@ -27,6 +35,16 @@ const ValidationSchema = Yup.object().shape({
.min(0) .min(0)
.max(500), .max(500),
cassette2: Yup.number() cassette2: Yup.number()
.required('Required')
.integer()
.min(0)
.max(500),
cassette3: Yup.number()
.required('Required')
.integer()
.min(0)
.max(500),
cassette4: Yup.number()
.required('Required') .required('Required')
.integer() .integer()
.min(0) .min(0)
@ -69,6 +87,7 @@ const CashCassettes = ({ machine, config, refetchData }) => {
const cashout = data?.config && fromNamespace('cashOut')(data.config) const cashout = data?.config && fromNamespace('cashOut')(data.config)
const locale = data?.config && fromNamespace('locale')(data.config) const locale = data?.config && fromNamespace('locale')(data.config)
const fiatCurrency = locale?.fiatCurrency const fiatCurrency = locale?.fiatCurrency
const numberOfCassettes = machine.numberOfCassettes
const getCashoutSettings = deviceId => fromNamespace(deviceId)(cashout) const getCashoutSettings = deviceId => fromNamespace(deviceId)(cashout)
const isCashOutDisabled = ({ deviceId }) => const isCashOutDisabled = ({ deviceId }) =>
@ -78,7 +97,7 @@ const CashCassettes = ({ machine, config, refetchData }) => {
{ {
name: 'cashbox', name: 'cashbox',
header: 'Cashbox', header: 'Cashbox',
width: 240, width: widthsByNumberOfCassettes[numberOfCassettes].cashbox,
stripe: false, stripe: false,
view: value => ( view: value => (
<CashIn currency={{ code: fiatCurrency }} notes={value} total={0} /> <CashIn currency={{ code: fiatCurrency }} notes={value} total={0} />
@ -87,87 +106,44 @@ const CashCassettes = ({ machine, config, refetchData }) => {
inputProps: { inputProps: {
decimalPlaces: 0 decimalPlaces: 0
} }
},
{
name: 'cassette1',
header: 'Cash-out 1',
width: 265,
stripe: true,
view: (value, { deviceId }) => (
<CashOut
className={classes.cashbox}
denomination={getCashoutSettings(deviceId)?.cassette1}
currency={{ code: fiatCurrency }}
notes={value}
/>
),
input: NumberInput,
inputProps: {
decimalPlaces: 0
}
},
{
name: 'cassette2',
header: 'Cash-out 2',
width: 265,
stripe: true,
view: (value, { deviceId }) => {
return (
<CashOut
className={classes.cashbox}
denomination={getCashoutSettings(deviceId)?.cassette2}
currency={{ code: fiatCurrency }}
notes={value}
/>
)
},
input: NumberInput,
inputProps: {
decimalPlaces: 0
}
},
{
name: 'cassette3',
header: 'Cash-out 3',
width: 265,
stripe: true,
view: (value, { deviceId }) => {
return (
<CashOut
className={classes.cashbox}
denomination={getCashoutSettings(deviceId)?.cassette2}
currency={{ code: fiatCurrency }}
notes={value}
/>
)
},
input: NumberInput,
inputProps: {
decimalPlaces: 0
}
},
{
name: 'cassette4',
header: 'Cash-out 4',
width: 265,
stripe: true,
view: (value, { deviceId }) => {
return (
<CashOut
className={classes.cashbox}
denomination={getCashoutSettings(deviceId)?.cassette2}
currency={{ code: fiatCurrency }}
notes={value}
/>
)
},
input: NumberInput,
inputProps: {
decimalPlaces: 0
}
} }
] ]
R.until(
R.gt(R.__, numberOfCassettes),
it => {
elements.push({
name: `cassette${it}`,
header: `Cash-out ${it}`,
width: widthsByNumberOfCassettes[numberOfCassettes].cassette,
stripe: true,
doubleHeader: 'Cash-out',
view: value => {
return (
<CashOut
className={classes.cashbox}
denomination={
getCashoutSettings(machine.deviceId)?.[`cassette${it}`]
}
currency={{ code: fiatCurrency }}
notes={value}
width={widthsByNumberOfCassettes[numberOfCassettes].cassetteGraph}
/>
)
},
isHidden: ({ numberOfCassettes }) => it > numberOfCassettes,
input: CashCassetteInput,
inputProps: {
decimalPlaces: 0,
width: widthsByNumberOfCassettes[numberOfCassettes].cassetteGraph,
inputClassName: classes.cashbox
}
})
return R.add(1, it)
},
1
)
const [setCassetteBills, { error }] = useMutation(SET_CASSETTE_BILLS, { const [setCassetteBills, { error }] = useMutation(SET_CASSETTE_BILLS, {
refetchQueries: () => refetchData() refetchQueries: () => refetchData()
}) })
@ -191,11 +167,13 @@ const CashCassettes = ({ machine, config, refetchData }) => {
return machine.name ? ( return machine.name ? (
<EditableTable <EditableTable
error={error?.message} error={error?.message}
enableEdit
editWidth={widthsByNumberOfCassettes[numberOfCassettes].editWidth}
stripeWhen={isCashOutDisabled} stripeWhen={isCashOutDisabled}
disableRowEdit={isCashOutDisabled} disableRowEdit={isCashOutDisabled}
name="cashboxes" name="cashboxes"
elements={elements} elements={elements}
data={[machine] || []} data={[machine]}
save={onSave} save={onSave}
validationSchema={ValidationSchema} validationSchema={ValidationSchema}
/> />

View file

@ -1,6 +1,5 @@
const styles = { const styles = {
cashbox: { cashbox: {
width: 80,
height: 36 height: 36
} }
} }

View file

@ -32,6 +32,9 @@ const GET_INFO = gql`
cashbox cashbox
cassette1 cassette1
cassette2 cassette2
cassette3
cassette4
numberOfCassettes
statuses { statuses {
label label
type type
@ -48,7 +51,7 @@ const getMachineID = path => path.slice(path.lastIndexOf('/') + 1)
const Machines = () => { const Machines = () => {
const location = useLocation() const location = useLocation()
const { data, refetch } = useQuery(GET_INFO, { const { data, loading, refetch } = useQuery(GET_INFO, {
variables: { variables: {
deviceId: getMachineID(location.pathname) deviceId: getMachineID(location.pathname)
} }
@ -62,6 +65,7 @@ const Machines = () => {
const machineID = R.path(['deviceId'])(machine) ?? null const machineID = R.path(['deviceId'])(machine) ?? null
return ( return (
!loading && (
<Grid container className={classes.grid}> <Grid container className={classes.grid}>
<Grid item xs={3}> <Grid item xs={3}>
<Grid item xs={12}> <Grid item xs={12}>
@ -116,6 +120,7 @@ const Machines = () => {
</Grid> </Grid>
</Grid> </Grid>
) )
)
} }
export default Machines export default Machines