fix: compliance trigger UI

This commit is contained in:
Sérgio Salgado 2021-02-11 19:19:45 +00:00 committed by Josh Harvey
parent 175a98d50f
commit b594eb8b48
2 changed files with 143 additions and 47 deletions

View file

@ -36,17 +36,23 @@ const styles = {
},
infoCurrentText: {
color: comet
},
blankSpace: {
padding: [[0, 30]],
margin: [[0, 4, 0, 2]],
borderBottom: `1px solid ${comet}`,
display: 'inline-block'
}
}
const useStyles = makeStyles(styles)
const getStep = step => {
const getStep = (step, currency) => {
switch (step) {
// case 1:
// return txDirection
case 1:
return type
return type(currency)
case 2:
return requirements
default:
@ -91,9 +97,11 @@ const getTypeText = (config, currency) => {
config.threshold.threshold
)} ${currency}`
case 'txVolume':
return `makes transactions over ${orUnderline(
return `makes ${orUnderline(
config.threshold.threshold
)} ${currency} in ${orUnderline(config.threshold.thresholdDays)} days`
)} ${currency} worth of transactions within ${orUnderline(
config.threshold.thresholdDays
)} days`
case 'txVelocity':
return `makes ${orUnderline(
config.threshold.threshold
@ -143,13 +151,27 @@ const InfoPanel = ({ step, config = {}, liveValues = {}, currency }) => {
const newText = getText(step, liveValues, currency)
const isLastStep = step === LAST_STEP
const newTextParts = newText.split('⎼⎼⎼⎼⎼ ')
const mapIndexed = R.addIndex(R.map)
const newTextElements = mapIndexed((it, idx) => {
return idx === newTextParts.length - 1 ? (
<span className={classes.infoCurrentText}>{it}</span>
) : (
<>
<span className={classes.infoCurrentText}>{it}</span>
<span className={classes.blankSpace}></span>
</>
)
})(newTextParts)
return (
<>
<H5 className={classes.infoTitle}>Trigger overview so far</H5>
<Info3 noMargin>
<Info3 noMargin className={classes.infoText}>
{oldText}
{step !== 1 && ', '}
<span className={classes.infoCurrentText}>{newText}</span>
{newTextElements}
{/* <span className={classes.infoCurrentText}>{newText}</span> */}
{!isLastStep && '...'}
</Info3>
</>
@ -174,7 +196,7 @@ const Wizard = ({ onClose, save, error, currency }) => {
})
const isLastStep = step === LAST_STEP
const stepOptions = getStep(step)
const stepOptions = getStep(step, currency)
const onContinue = async it => {
const newConfig = R.merge(config, stepOptions.schema.cast(it))
@ -195,7 +217,7 @@ const Wizard = ({ onClose, save, error, currency }) => {
title="New compliance trigger"
handleClose={onClose}
width={520}
height={480}
height={520}
infoPanel={
<InfoPanel
currency={currency}
@ -218,7 +240,7 @@ const Wizard = ({ onClose, save, error, currency }) => {
validationSchema={stepOptions.schema}>
<Form className={classes.form}>
<GetValues setValues={setLiveValues} />
<stepOptions.Component />
<stepOptions.Component {...stepOptions.props} />
<div className={classes.submit}>
{error && <ErrorMessage>Failed to save</ErrorMessage>}
<Button className={classes.button} type="submit">

View file

@ -6,7 +6,7 @@ import React, { memo } from 'react'
import * as Yup from 'yup'
import { TextInput, RadioGroup } from 'src/components/inputs/formik'
import { H4, Label2, Label1, Info2 } from 'src/components/typography'
import { H4, Label2, Label1, Info1, Info2 } from 'src/components/typography'
import { errorColor } from 'src/styling/variables'
// import { ReactComponent as TxInIcon } from 'src/styling/icons/direction/cash-in.svg'
// import { ReactComponent as TxOutIcon } from 'src/styling/icons/direction/cash-out.svg'
@ -41,11 +41,22 @@ const useStyles = makeStyles({
marginLeft: 6
},
thresholdWrapper: {
display: 'flex'
display: 'flex',
flexDirection: 'column'
},
thresholdTitle: {
marginTop: 50
},
thresholdContentWrapper: {
display: 'flex',
flexDirection: 'row'
},
thresholdField: {
margin: 10,
width: 208
marginRight: 6,
width: 75
},
description: {
marginTop: 7
},
space: {
marginLeft: 6,
@ -203,7 +214,7 @@ const typeOptions = [
{ display: 'Consecutive days', code: 'consecutiveDays' }
]
const Type = () => {
const Type = ({ ...props }) => {
const classes = useStyles()
const { errors, touched, values } = useFormikContext()
@ -212,17 +223,19 @@ const Type = () => {
}
const containsType = R.contains(values?.triggerType)
const isThresholdEnabled = containsType([
'txAmount',
'txVolume',
'txVelocity'
])
const isThresholdCurrencyEnabled = containsType(['txAmount', 'txVolume'])
const isTransactionAmountEnabled = containsType(['txVelocity'])
const isThresholdDaysEnabled = containsType(['txVolume', 'txVelocity'])
const isConsecutiveDaysEnabled = containsType(['consecutiveDays'])
const isThresholdDaysEnabled = containsType([
'txVolume',
'txVelocity',
'consecutiveDays'
])
const isRadioGroupActive = () => {
return (
isThresholdCurrencyEnabled ||
isTransactionAmountEnabled ||
isThresholdDaysEnabled ||
isConsecutiveDaysEnabled
)
}
return (
<>
@ -239,38 +252,94 @@ const Type = () => {
/>
<div className={classes.thresholdWrapper}>
{isThresholdEnabled && (
<Field
className={classes.thresholdField}
component={TextInput}
label="Threshold"
size="lg"
name="threshold.threshold"
/>
)}
{isThresholdDaysEnabled && (
<Field
className={classes.thresholdField}
component={TextInput}
label="Threshold Days"
size="lg"
name="threshold.thresholdDays"
/>
{isRadioGroupActive() && (
<H4 className={classnames(typeClass, classes.thresholdTitle)}>
Threshold
</H4>
)}
<div className={classes.thresholdContentWrapper}>
{isThresholdCurrencyEnabled && (
<>
<Field
className={classes.thresholdField}
component={TextInput}
size="lg"
name="threshold.threshold"
/>
<Info1 className={classnames(typeClass, classes.description)}>
{props.currency}
</Info1>
</>
)}
{isTransactionAmountEnabled && (
<>
<Field
className={classes.thresholdField}
component={TextInput}
size="lg"
name="threshold.threshold"
/>
<Info1 className={classnames(typeClass, classes.description)}>
transactions
</Info1>
</>
)}
{isThresholdDaysEnabled && (
<>
<Info1
className={classnames(
typeClass,
classes.space,
classes.description
)}>
in
</Info1>
<Field
className={classes.thresholdField}
component={TextInput}
size="lg"
name="threshold.thresholdDays"
/>
<Info1 className={classnames(typeClass, classes.description)}>
days
</Info1>
</>
)}
{isConsecutiveDaysEnabled && (
<>
<Field
className={classes.thresholdField}
component={TextInput}
size="lg"
name="threshold.thresholdDays"
/>
<Info1 className={classnames(typeClass, classes.description)}>
consecutive days
</Info1>
</>
)}
</div>
</div>
</>
)
}
const type = {
const type = currency => ({
schema: typeSchema,
options: typeOptions,
Component: Type,
props: { currency },
initialValues: { triggerType: '', threshold: '' }
}
})
const requirementSchema = Yup.object().shape({
requirement
requirement: Yup.object({
requirement: Yup.string().required(),
suspensionDays: Yup.number().when('requirement', {
is: value => value === 'suspend',
then: Yup.number().required()
})
}).required()
})
const requirementOptions = [
@ -287,10 +356,15 @@ const requirementOptions = [
const Requirement = () => {
const classes = useStyles()
const { errors, values } = useFormikContext()
const { touched, errors, values } = useFormikContext()
const titleClass = {
[classes.error]: errors.requirement
[classes.error]:
!R.isEmpty(R.omit(['suspensionDays'], errors.requirement)) ||
(errors.requirement &&
touched.requirement &&
errors.requirement.suspensionDays &&
touched.requirement.suspensionDays)
}
const isSuspend = values?.requirement?.requirement === 'suspend'
@ -326,7 +400,7 @@ const requirements = {
schema: requirementSchema,
options: requirementOptions,
Component: Requirement,
initialValues: { requirement: '' }
initialValues: { requirement: { requirement: '', suspensionDays: '' } }
}
const getView = (data, code, compare) => it => {