fix: compliance trigger UI
This commit is contained in:
parent
175a98d50f
commit
b594eb8b48
2 changed files with 143 additions and 47 deletions
|
|
@ -36,17 +36,23 @@ const styles = {
|
||||||
},
|
},
|
||||||
infoCurrentText: {
|
infoCurrentText: {
|
||||||
color: comet
|
color: comet
|
||||||
|
},
|
||||||
|
blankSpace: {
|
||||||
|
padding: [[0, 30]],
|
||||||
|
margin: [[0, 4, 0, 2]],
|
||||||
|
borderBottom: `1px solid ${comet}`,
|
||||||
|
display: 'inline-block'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const useStyles = makeStyles(styles)
|
const useStyles = makeStyles(styles)
|
||||||
|
|
||||||
const getStep = step => {
|
const getStep = (step, currency) => {
|
||||||
switch (step) {
|
switch (step) {
|
||||||
// case 1:
|
// case 1:
|
||||||
// return txDirection
|
// return txDirection
|
||||||
case 1:
|
case 1:
|
||||||
return type
|
return type(currency)
|
||||||
case 2:
|
case 2:
|
||||||
return requirements
|
return requirements
|
||||||
default:
|
default:
|
||||||
|
|
@ -91,9 +97,11 @@ const getTypeText = (config, currency) => {
|
||||||
config.threshold.threshold
|
config.threshold.threshold
|
||||||
)} ${currency}`
|
)} ${currency}`
|
||||||
case 'txVolume':
|
case 'txVolume':
|
||||||
return `makes transactions over ${orUnderline(
|
return `makes ${orUnderline(
|
||||||
config.threshold.threshold
|
config.threshold.threshold
|
||||||
)} ${currency} in ${orUnderline(config.threshold.thresholdDays)} days`
|
)} ${currency} worth of transactions within ${orUnderline(
|
||||||
|
config.threshold.thresholdDays
|
||||||
|
)} days`
|
||||||
case 'txVelocity':
|
case 'txVelocity':
|
||||||
return `makes ${orUnderline(
|
return `makes ${orUnderline(
|
||||||
config.threshold.threshold
|
config.threshold.threshold
|
||||||
|
|
@ -143,13 +151,27 @@ const InfoPanel = ({ step, config = {}, liveValues = {}, currency }) => {
|
||||||
const newText = getText(step, liveValues, currency)
|
const newText = getText(step, liveValues, currency)
|
||||||
const isLastStep = step === LAST_STEP
|
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 (
|
return (
|
||||||
<>
|
<>
|
||||||
<H5 className={classes.infoTitle}>Trigger overview so far</H5>
|
<H5 className={classes.infoTitle}>Trigger overview so far</H5>
|
||||||
<Info3 noMargin>
|
<Info3 noMargin className={classes.infoText}>
|
||||||
{oldText}
|
{oldText}
|
||||||
{step !== 1 && ', '}
|
{step !== 1 && ', '}
|
||||||
<span className={classes.infoCurrentText}>{newText}</span>
|
{newTextElements}
|
||||||
|
{/* <span className={classes.infoCurrentText}>{newText}</span> */}
|
||||||
{!isLastStep && '...'}
|
{!isLastStep && '...'}
|
||||||
</Info3>
|
</Info3>
|
||||||
</>
|
</>
|
||||||
|
|
@ -174,7 +196,7 @@ const Wizard = ({ onClose, save, error, currency }) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
const isLastStep = step === LAST_STEP
|
const isLastStep = step === LAST_STEP
|
||||||
const stepOptions = getStep(step)
|
const stepOptions = getStep(step, currency)
|
||||||
|
|
||||||
const onContinue = async it => {
|
const onContinue = async it => {
|
||||||
const newConfig = R.merge(config, stepOptions.schema.cast(it))
|
const newConfig = R.merge(config, stepOptions.schema.cast(it))
|
||||||
|
|
@ -195,7 +217,7 @@ const Wizard = ({ onClose, save, error, currency }) => {
|
||||||
title="New compliance trigger"
|
title="New compliance trigger"
|
||||||
handleClose={onClose}
|
handleClose={onClose}
|
||||||
width={520}
|
width={520}
|
||||||
height={480}
|
height={520}
|
||||||
infoPanel={
|
infoPanel={
|
||||||
<InfoPanel
|
<InfoPanel
|
||||||
currency={currency}
|
currency={currency}
|
||||||
|
|
@ -218,7 +240,7 @@ const Wizard = ({ onClose, save, error, currency }) => {
|
||||||
validationSchema={stepOptions.schema}>
|
validationSchema={stepOptions.schema}>
|
||||||
<Form className={classes.form}>
|
<Form className={classes.form}>
|
||||||
<GetValues setValues={setLiveValues} />
|
<GetValues setValues={setLiveValues} />
|
||||||
<stepOptions.Component />
|
<stepOptions.Component {...stepOptions.props} />
|
||||||
<div className={classes.submit}>
|
<div className={classes.submit}>
|
||||||
{error && <ErrorMessage>Failed to save</ErrorMessage>}
|
{error && <ErrorMessage>Failed to save</ErrorMessage>}
|
||||||
<Button className={classes.button} type="submit">
|
<Button className={classes.button} type="submit">
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import React, { memo } from 'react'
|
||||||
import * as Yup from 'yup'
|
import * as Yup from 'yup'
|
||||||
|
|
||||||
import { TextInput, RadioGroup } from 'src/components/inputs/formik'
|
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 { errorColor } from 'src/styling/variables'
|
||||||
// import { ReactComponent as TxInIcon } from 'src/styling/icons/direction/cash-in.svg'
|
// import { ReactComponent as TxInIcon } from 'src/styling/icons/direction/cash-in.svg'
|
||||||
// import { ReactComponent as TxOutIcon } from 'src/styling/icons/direction/cash-out.svg'
|
// import { ReactComponent as TxOutIcon } from 'src/styling/icons/direction/cash-out.svg'
|
||||||
|
|
@ -41,11 +41,22 @@ const useStyles = makeStyles({
|
||||||
marginLeft: 6
|
marginLeft: 6
|
||||||
},
|
},
|
||||||
thresholdWrapper: {
|
thresholdWrapper: {
|
||||||
display: 'flex'
|
display: 'flex',
|
||||||
|
flexDirection: 'column'
|
||||||
|
},
|
||||||
|
thresholdTitle: {
|
||||||
|
marginTop: 50
|
||||||
|
},
|
||||||
|
thresholdContentWrapper: {
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'row'
|
||||||
},
|
},
|
||||||
thresholdField: {
|
thresholdField: {
|
||||||
margin: 10,
|
marginRight: 6,
|
||||||
width: 208
|
width: 75
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
marginTop: 7
|
||||||
},
|
},
|
||||||
space: {
|
space: {
|
||||||
marginLeft: 6,
|
marginLeft: 6,
|
||||||
|
|
@ -203,7 +214,7 @@ const typeOptions = [
|
||||||
{ display: 'Consecutive days', code: 'consecutiveDays' }
|
{ display: 'Consecutive days', code: 'consecutiveDays' }
|
||||||
]
|
]
|
||||||
|
|
||||||
const Type = () => {
|
const Type = ({ ...props }) => {
|
||||||
const classes = useStyles()
|
const classes = useStyles()
|
||||||
const { errors, touched, values } = useFormikContext()
|
const { errors, touched, values } = useFormikContext()
|
||||||
|
|
||||||
|
|
@ -212,17 +223,19 @@ const Type = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const containsType = R.contains(values?.triggerType)
|
const containsType = R.contains(values?.triggerType)
|
||||||
const isThresholdEnabled = containsType([
|
const isThresholdCurrencyEnabled = containsType(['txAmount', 'txVolume'])
|
||||||
'txAmount',
|
const isTransactionAmountEnabled = containsType(['txVelocity'])
|
||||||
'txVolume',
|
const isThresholdDaysEnabled = containsType(['txVolume', 'txVelocity'])
|
||||||
'txVelocity'
|
const isConsecutiveDaysEnabled = containsType(['consecutiveDays'])
|
||||||
])
|
|
||||||
|
|
||||||
const isThresholdDaysEnabled = containsType([
|
const isRadioGroupActive = () => {
|
||||||
'txVolume',
|
return (
|
||||||
'txVelocity',
|
isThresholdCurrencyEnabled ||
|
||||||
'consecutiveDays'
|
isTransactionAmountEnabled ||
|
||||||
])
|
isThresholdDaysEnabled ||
|
||||||
|
isConsecutiveDaysEnabled
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
@ -239,38 +252,94 @@ const Type = () => {
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div className={classes.thresholdWrapper}>
|
<div className={classes.thresholdWrapper}>
|
||||||
{isThresholdEnabled && (
|
{isRadioGroupActive() && (
|
||||||
|
<H4 className={classnames(typeClass, classes.thresholdTitle)}>
|
||||||
|
Threshold
|
||||||
|
</H4>
|
||||||
|
)}
|
||||||
|
<div className={classes.thresholdContentWrapper}>
|
||||||
|
{isThresholdCurrencyEnabled && (
|
||||||
|
<>
|
||||||
<Field
|
<Field
|
||||||
className={classes.thresholdField}
|
className={classes.thresholdField}
|
||||||
component={TextInput}
|
component={TextInput}
|
||||||
label="Threshold"
|
|
||||||
size="lg"
|
size="lg"
|
||||||
name="threshold.threshold"
|
name="threshold.threshold"
|
||||||
/>
|
/>
|
||||||
|
<Info1 className={classnames(typeClass, classes.description)}>
|
||||||
|
{props.currency}
|
||||||
|
</Info1>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
{isThresholdDaysEnabled && (
|
{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
|
<Field
|
||||||
className={classes.thresholdField}
|
className={classes.thresholdField}
|
||||||
component={TextInput}
|
component={TextInput}
|
||||||
label="Threshold Days"
|
|
||||||
size="lg"
|
size="lg"
|
||||||
name="threshold.thresholdDays"
|
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>
|
</div>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const type = {
|
const type = currency => ({
|
||||||
schema: typeSchema,
|
schema: typeSchema,
|
||||||
options: typeOptions,
|
options: typeOptions,
|
||||||
Component: Type,
|
Component: Type,
|
||||||
|
props: { currency },
|
||||||
initialValues: { triggerType: '', threshold: '' }
|
initialValues: { triggerType: '', threshold: '' }
|
||||||
}
|
})
|
||||||
|
|
||||||
const requirementSchema = Yup.object().shape({
|
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 = [
|
const requirementOptions = [
|
||||||
|
|
@ -287,10 +356,15 @@ const requirementOptions = [
|
||||||
|
|
||||||
const Requirement = () => {
|
const Requirement = () => {
|
||||||
const classes = useStyles()
|
const classes = useStyles()
|
||||||
const { errors, values } = useFormikContext()
|
const { touched, errors, values } = useFormikContext()
|
||||||
|
|
||||||
const titleClass = {
|
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'
|
const isSuspend = values?.requirement?.requirement === 'suspend'
|
||||||
|
|
@ -326,7 +400,7 @@ const requirements = {
|
||||||
schema: requirementSchema,
|
schema: requirementSchema,
|
||||||
options: requirementOptions,
|
options: requirementOptions,
|
||||||
Component: Requirement,
|
Component: Requirement,
|
||||||
initialValues: { requirement: '' }
|
initialValues: { requirement: { requirement: '', suspensionDays: '' } }
|
||||||
}
|
}
|
||||||
|
|
||||||
const getView = (data, code, compare) => it => {
|
const getView = (data, code, compare) => it => {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue