feat: added multicassette to notifications override
This commit is contained in:
parent
f32d02a808
commit
20a3c40c48
5 changed files with 171 additions and 130 deletions
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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',
|
||||||
|
|
|
||||||
|
|
@ -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}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue