feat: added multicassette to notifications override

This commit is contained in:
Sérgio Salgado 2021-10-27 15:32:19 +01:00
parent f32d02a808
commit 20a3c40c48
5 changed files with 171 additions and 130 deletions

View file

@ -132,7 +132,7 @@ const ECol = ({ editing, focus, config, extraPaddingRight, extraPadding }) => {
SuffixComponent = TL2, SuffixComponent = TL2,
textStyle = it => {}, textStyle = it => {},
isHidden = it => false, isHidden = it => false,
view = it => it?.toString(), view = it => it?.toString() ?? '—',
inputProps = {} inputProps = {}
} = config } = config

View file

@ -22,6 +22,7 @@ const GET_INFO = gql`
machines { machines {
name name
deviceId deviceId
numberOfCassettes
} }
cryptoCurrencies { cryptoCurrencies {
code code
@ -52,7 +53,7 @@ const Notifications = ({
const [error, setError] = useState(null) const [error, setError] = useState(null)
const [editingKey, setEditingKey] = useState(null) const [editingKey, setEditingKey] = useState(null)
const { data } = useQuery(GET_INFO) const { data, loading } = useQuery(GET_INFO)
const [saveConfig] = useMutation(SAVE_CONFIG, { const [saveConfig] = useMutation(SAVE_CONFIG, {
refetchQueries: ['getData'], refetchQueries: ['getData'],
@ -100,6 +101,7 @@ const Notifications = ({
} }
return ( return (
!loading && (
<NotificationsCtx.Provider value={contextValue}> <NotificationsCtx.Provider value={contextValue}>
{displayTitle && <TitleSection title="Notifications" />} {displayTitle && <TitleSection title="Notifications" />}
{displaySetup && ( {displaySetup && (
@ -135,6 +137,7 @@ const Notifications = ({
)} )}
</NotificationsCtx.Provider> </NotificationsCtx.Provider>
) )
)
} }
export default Notifications export default Notifications

View file

@ -1,5 +1,6 @@
import { makeStyles } from '@material-ui/core' import { makeStyles } from '@material-ui/core'
import { Form, Formik } from 'formik' import { Form, Formik } from 'formik'
import * as R from 'ramda'
import React, { useContext } from 'react' import React, { useContext } from 'react'
import * as Yup from 'yup' import * as Yup from 'yup'
@ -17,6 +18,7 @@ import styles from './FiatBalanceAlerts.styles.js'
const useStyles = makeStyles(styles) const useStyles = makeStyles(styles)
const NAME = 'fiatBalanceAlerts' const NAME = 'fiatBalanceAlerts'
const DEFAULT_NUMBER_OF_CASSETTES = 2
const FiatBalance = ({ const FiatBalance = ({
section, section,
@ -24,11 +26,20 @@ const FiatBalance = ({
max = Number.MAX_SAFE_INTEGER, max = Number.MAX_SAFE_INTEGER,
fieldWidth = 80 fieldWidth = 80
}) => { }) => {
const { isEditing, isDisabled, setEditing, data, save } = useContext( const {
NotificationsCtx isEditing,
) isDisabled,
setEditing,
data,
save,
machines
} = useContext(NotificationsCtx)
const classes = useStyles() const classes = useStyles()
const maxNumberOfCassettes =
Math.max(...R.map(it => it.numberOfCassettes, machines)) ??
DEFAULT_NUMBER_OF_CASSETTES
const editing = isEditing(NAME) const editing = isEditing(NAME)
const schema = Yup.object().shape({ const schema = Yup.object().shape({
@ -39,6 +50,18 @@ const FiatBalance = ({
.max(max) .max(max)
.nullable(), .nullable(),
fiatBalanceCassette2: Yup.number() fiatBalanceCassette2: Yup.number()
.transform(transformNumber)
.integer()
.min(min)
.max(max)
.nullable(),
fiatBalanceCassette3: Yup.number()
.transform(transformNumber)
.integer()
.min(min)
.max(max)
.nullable(),
fiatBalanceCassette4: Yup.number()
.transform(transformNumber) .transform(transformNumber)
.integer() .integer()
.min(min) .min(min)
@ -46,10 +69,12 @@ const FiatBalance = ({
.nullable() .nullable()
}) })
const fiatBalanceCassette1Percent = const percentages = {
(100 * (data?.fiatBalanceCassette1 ?? 0)) / max cassette1: (100 * (data?.fiatBalanceCassette1 ?? 0)) / max,
const fiatBalanceCassette2Percent = cassette2: (100 * (data?.fiatBalanceCassette2 ?? 0)) / max,
(100 * (data?.fiatBalanceCassette2 ?? 0)) / max cassette3: (100 * (data?.fiatBalanceCassette3 ?? 0)) / max,
cassette4: (100 * (data?.fiatBalanceCassette4 ?? 0)) / max
}
return ( return (
<Formik <Formik
@ -58,7 +83,9 @@ const FiatBalance = ({
enableReinitialize enableReinitialize
initialValues={{ initialValues={{
fiatBalanceCassette1: data?.fiatBalanceCassette1 ?? '', fiatBalanceCassette1: data?.fiatBalanceCassette1 ?? '',
fiatBalanceCassette2: data?.fiatBalanceCassette2 ?? '' fiatBalanceCassette2: data?.fiatBalanceCassette2 ?? '',
fiatBalanceCassette3: data?.fiatBalanceCassette3 ?? '',
fiatBalanceCassette4: data?.fiatBalanceCassette4 ?? ''
}} }}
validationSchema={schema} validationSchema={schema}
onSubmit={it => save(section, schema.cast(it))} onSubmit={it => save(section, schema.cast(it))}
@ -74,39 +101,21 @@ const FiatBalance = ({
setEditing={it => setEditing(NAME, it)} setEditing={it => setEditing(NAME, it)}
/> />
<div className={classes.wrapper}> <div className={classes.wrapper}>
<div className={classes.first}> {R.map(
it => (
<>
<div className={classes.row}> <div className={classes.row}>
<Cashbox <Cashbox
labelClassName={classes.cashboxLabel} labelClassName={classes.cashboxLabel}
emptyPartClassName={classes.cashboxEmptyPart} emptyPartClassName={classes.cashboxEmptyPart}
percent={fiatBalanceCassette1Percent} percent={percentages[`cassette${it + 1}`]}
cashOut cashOut
/> />
<div className={classes.col2}> <div className={classes.col2}>
<TL2 className={classes.title}>Cassette 1 (Top)</TL2> <TL2 className={classes.title}>Cassette {it + 1}</TL2>
<EditableNumber <EditableNumber
label="Alert me under" label="Alert me under"
name="fiatBalanceCassette1" name={`fiatBalanceCassette${it + 1}`}
editing={editing}
displayValue={x => (x === '' ? '-' : x)}
decoration="notes"
width={fieldWidth}
/>
</div>
</div>
</div>
<div className={classes.row}>
<Cashbox
labelClassName={classes.cashboxLabel}
emptyPartClassName={classes.cashboxEmptyPart}
percent={fiatBalanceCassette2Percent}
cashOut
/>
<div className={classes.col2}>
<TL2 className={classes.title}>Cassette 2 (Bottom)</TL2>
<EditableNumber
label="Alert me under"
name="fiatBalanceCassette2"
editing={editing} editing={editing}
displayValue={x => (x === '' ? '-' : x)} displayValue={x => (x === '' ? '-' : x)}
decoration="notes" decoration="notes"
@ -114,6 +123,10 @@ const FiatBalance = ({
/> />
</div> </div>
</div> </div>
</>
),
R.times(R.identity, maxNumberOfCassettes)
)}
</div> </div>
</Form> </Form>
</Formik> </Formik>

View file

@ -7,14 +7,11 @@ export default {
form: { form: {
marginBottom: 36 marginBottom: 36
}, },
first: {
width: 236
},
title: { title: {
marginTop: 0 marginTop: 0
}, },
row: { row: {
width: 183, width: 236,
display: 'grid', display: 'grid',
gridTemplateColumns: 'repeat(2,1fr)', gridTemplateColumns: 'repeat(2,1fr)',
gridTemplateRows: '1fr', gridTemplateRows: '1fr',

View file

@ -11,9 +11,18 @@ import NotificationsCtx from '../NotificationsContext'
const CASSETTE_1_KEY = 'fiatBalanceCassette1' const CASSETTE_1_KEY = 'fiatBalanceCassette1'
const CASSETTE_2_KEY = 'fiatBalanceCassette2' const CASSETTE_2_KEY = 'fiatBalanceCassette2'
const CASSETTE_3_KEY = 'fiatBalanceCassette3'
const CASSETTE_4_KEY = 'fiatBalanceCassette4'
const MACHINE_KEY = 'machine' const MACHINE_KEY = 'machine'
const NAME = 'fiatBalanceOverrides' const NAME = 'fiatBalanceOverrides'
const CASSETTE_LIST = [
CASSETTE_1_KEY,
CASSETTE_2_KEY,
CASSETTE_3_KEY,
CASSETTE_4_KEY
]
const FiatBalanceOverrides = ({ section }) => { const FiatBalanceOverrides = ({ section }) => {
const { const {
machines = [], machines = [],
@ -41,42 +50,62 @@ const FiatBalanceOverrides = ({ section }) => {
const initialValues = { const initialValues = {
[MACHINE_KEY]: null, [MACHINE_KEY]: null,
[CASSETTE_1_KEY]: '', [CASSETTE_1_KEY]: '',
[CASSETTE_2_KEY]: '' [CASSETTE_2_KEY]: '',
[CASSETTE_3_KEY]: '',
[CASSETTE_4_KEY]: ''
} }
const maxNumberOfCassettes = Math.max(
...R.map(it => it.numberOfCassettes, machines)
)
const notesMin = 0 const notesMin = 0
const notesMax = 9999999 const notesMax = 9999999
const validationSchema = Yup.object().shape( const validationSchema = Yup.object()
{ .shape({
[MACHINE_KEY]: Yup.string() [MACHINE_KEY]: Yup.string()
.label('Machine') .label('Machine')
.nullable() .nullable()
.required(), .required(),
[CASSETTE_1_KEY]: Yup.number() [CASSETTE_1_KEY]: Yup.number()
.label('Cassette 1 (top)') .label('Cassette 1')
.when(CASSETTE_2_KEY, {
is: CASSETTE_2_KEY => !CASSETTE_2_KEY,
then: Yup.number().required()
})
.transform(transformNumber) .transform(transformNumber)
.integer() .integer()
.min(notesMin) .min(notesMin)
.max(notesMax) .max(notesMax)
.nullable(), .nullable(),
[CASSETTE_2_KEY]: Yup.number() [CASSETTE_2_KEY]: Yup.number()
.label('Cassette 2 (bottom)') .label('Cassette 2')
.when(CASSETTE_1_KEY, { .transform(transformNumber)
is: CASSETTE_1_KEY => !CASSETTE_1_KEY, .integer()
then: Yup.number().required() .min(notesMin)
}) .max(notesMax)
.nullable(),
[CASSETTE_3_KEY]: Yup.number()
.label('Cassette 3')
.transform(transformNumber)
.integer()
.min(notesMin)
.max(notesMax)
.nullable(),
[CASSETTE_4_KEY]: Yup.number()
.label('Cassette 4')
.transform(transformNumber) .transform(transformNumber)
.integer() .integer()
.min(notesMin) .min(notesMin)
.max(notesMax) .max(notesMax)
.nullable() .nullable()
}, })
[CASSETTE_1_KEY, CASSETTE_2_KEY] .test((values, context) => {
) const picked = R.pick(CASSETTE_LIST, values)
if (CASSETTE_LIST.some(it => !R.isNil(picked[it]))) return
return context.createError({
path: CASSETTE_1_KEY,
message: 'At least one of the cassettes must have a value'
})
})
const viewMachine = it => const viewMachine = it =>
R.compose(R.path(['name']), R.find(R.propEq('deviceId', it)))(machines) R.compose(R.path(['name']), R.find(R.propEq('deviceId', it)))(machines)
@ -93,35 +122,34 @@ const FiatBalanceOverrides = ({ section }) => {
valueProp: 'deviceId', valueProp: 'deviceId',
labelProp: 'name' labelProp: 'name'
} }
},
{
name: CASSETTE_1_KEY,
display: 'Cash-out 1',
width: 155,
textAlign: 'right',
doubleHeader: 'Cash-out (Cassette Empty)',
bold: true,
input: NumberInput,
suffix: 'notes',
inputProps: {
decimalPlaces: 0
}
},
{
name: CASSETTE_2_KEY,
display: 'Cash-out 2',
width: 155,
textAlign: 'right',
doubleHeader: 'Cash-out (Cassette Empty)',
bold: true,
input: NumberInput,
suffix: 'notes',
inputProps: {
decimalPlaces: 0
}
} }
] ]
R.until(
R.gt(R.__, maxNumberOfCassettes),
it => {
elements.push({
name: `fiatBalanceCassette${it}`,
display: `Cash-out ${it}`,
width: 155,
textAlign: 'right',
doubleHeader: 'Cash-out (Cassette Empty)',
bold: true,
input: NumberInput,
suffix: 'notes',
inputProps: {
decimalPlaces: 0
},
isHidden: value =>
it >
machines.find(({ deviceId }) => deviceId === value.machine)
?.numberOfCassettes
})
return R.add(1, it)
},
1
)
return ( return (
<EditableTable <EditableTable
name={NAME} name={NAME}