feat: compliance triggers and customers up to spec
This commit is contained in:
parent
b153a23f25
commit
6f5cb385b0
8 changed files with 400 additions and 104 deletions
|
|
@ -93,6 +93,7 @@ const ECol = ({
|
|||
}) => {
|
||||
const {
|
||||
name,
|
||||
bypassField,
|
||||
input,
|
||||
editable = true,
|
||||
size,
|
||||
|
|
@ -122,6 +123,9 @@ const ECol = ({
|
|||
innerProps.getLabel = view
|
||||
}
|
||||
|
||||
const isEditing = editing && editable
|
||||
const isField = !bypassField
|
||||
|
||||
return (
|
||||
<Td
|
||||
className={{
|
||||
|
|
@ -133,11 +137,11 @@ const ECol = ({
|
|||
size={size}
|
||||
bold={bold}
|
||||
textAlign={textAlign}>
|
||||
{editing && editable ? (
|
||||
{isEditing && isField && (
|
||||
<Field name={name} component={input} {...innerProps} />
|
||||
) : (
|
||||
values && <>{view(values[name])}</>
|
||||
)}
|
||||
{isEditing && !isField && <config.input name={name} />}
|
||||
{!isEditing && values && <>{view(values[name], values)}</>}
|
||||
{suffix && (
|
||||
<SuffixComponent className={classes.suffix}>{suffix}</SuffixComponent>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -3,12 +3,12 @@ import { makeStyles } from '@material-ui/core/styles'
|
|||
import classnames from 'classnames'
|
||||
import React, { memo } from 'react'
|
||||
|
||||
// import { ActionButton } from 'src/components/buttons'
|
||||
import { ActionButton } from 'src/components/buttons'
|
||||
import { H3 } from 'src/components/typography'
|
||||
// import { ReactComponent as AuthorizeReversedIcon } from 'src/styling/icons/button/authorize/white.svg'
|
||||
// import { ReactComponent as AuthorizeIcon } from 'src/styling/icons/button/authorize/zodiac.svg'
|
||||
// import { ReactComponent as RejectReversedIcon } from 'src/styling/icons/button/cancel/white.svg'
|
||||
// import { ReactComponent as RejectIcon } from 'src/styling/icons/button/cancel/zodiac.svg'
|
||||
import { ReactComponent as AuthorizeReversedIcon } from 'src/styling/icons/button/authorize/white.svg'
|
||||
import { ReactComponent as AuthorizeIcon } from 'src/styling/icons/button/authorize/zodiac.svg'
|
||||
import { ReactComponent as RejectReversedIcon } from 'src/styling/icons/button/cancel/white.svg'
|
||||
import { ReactComponent as RejectIcon } from 'src/styling/icons/button/cancel/zodiac.svg'
|
||||
|
||||
import { propertyCardStyles } from './PropertyCard.styles'
|
||||
|
||||
|
|
@ -24,48 +24,46 @@ const PropertyCard = memo(
|
|||
|
||||
const propertyCardClassNames = {
|
||||
[classes.propertyCard]: true,
|
||||
[classes.propertyCardPending]: true
|
||||
// [classes.propertyCardPending]: state === OVERRIDE_PENDING
|
||||
// [classes.propertyCardRejected]: state === OVERRIDE_REJECTED,
|
||||
// [classes.propertyCardAccepted]: state === OVERRIDE_AUTHORIZED
|
||||
[classes.propertyCardPending]: state === OVERRIDE_PENDING,
|
||||
[classes.propertyCardRejected]: state === OVERRIDE_REJECTED,
|
||||
[classes.propertyCardAccepted]: state === OVERRIDE_AUTHORIZED
|
||||
}
|
||||
|
||||
// const label1ClassNames = {
|
||||
// [classes.label1]: true,
|
||||
// [classes.label1Pending]: true
|
||||
// [classes.label1Pending]: state === OVERRIDE_PENDING
|
||||
// [classes.label1Rejected]: state === OVERRIDE_REJECTED,
|
||||
// [classes.label1Accepted]: state === OVERRIDE_AUTHORIZED
|
||||
// }
|
||||
const label1ClassNames = {
|
||||
[classes.label1]: true,
|
||||
[classes.label1Pending]: state === OVERRIDE_PENDING,
|
||||
[classes.label1Rejected]: state === OVERRIDE_REJECTED,
|
||||
[classes.label1Accepted]: state === OVERRIDE_AUTHORIZED
|
||||
}
|
||||
|
||||
// const AuthorizeButton = () => (
|
||||
// <ActionButton
|
||||
// className={classes.cardActionButton}
|
||||
// color="secondary"
|
||||
// Icon={AuthorizeIcon}
|
||||
// InverseIcon={AuthorizeReversedIcon}
|
||||
// onClick={() => authorize()}>
|
||||
// Authorize
|
||||
// </ActionButton>
|
||||
// )
|
||||
const AuthorizeButton = () => (
|
||||
<ActionButton
|
||||
className={classes.cardActionButton}
|
||||
color="secondary"
|
||||
Icon={AuthorizeIcon}
|
||||
InverseIcon={AuthorizeReversedIcon}
|
||||
onClick={() => authorize()}>
|
||||
Authorize
|
||||
</ActionButton>
|
||||
)
|
||||
|
||||
// const RejectButton = () => (
|
||||
// <ActionButton
|
||||
// className={classes.cardActionButton}
|
||||
// color="secondary"
|
||||
// Icon={RejectIcon}
|
||||
// InverseIcon={RejectReversedIcon}
|
||||
// onClick={() => reject()}>
|
||||
// Reject
|
||||
// </ActionButton>
|
||||
// )
|
||||
const RejectButton = () => (
|
||||
<ActionButton
|
||||
className={classes.cardActionButton}
|
||||
color="secondary"
|
||||
Icon={RejectIcon}
|
||||
InverseIcon={RejectReversedIcon}
|
||||
onClick={() => reject()}>
|
||||
Reject
|
||||
</ActionButton>
|
||||
)
|
||||
|
||||
// const authorizedAsString =
|
||||
// state === OVERRIDE_PENDING
|
||||
// ? 'Pending'
|
||||
// : state === OVERRIDE_REJECTED
|
||||
// ? 'Rejected'
|
||||
// : 'Accepted'
|
||||
const authorizedAsString =
|
||||
state === OVERRIDE_PENDING
|
||||
? 'Pending'
|
||||
: state === OVERRIDE_REJECTED
|
||||
? 'Rejected'
|
||||
: 'Accepted'
|
||||
|
||||
return (
|
||||
<Paper
|
||||
|
|
@ -73,18 +71,17 @@ const PropertyCard = memo(
|
|||
elevation={0}>
|
||||
<div className={classes.rowSpaceBetween}>
|
||||
<H3>{title}</H3>
|
||||
{/* <div className={classnames(label1ClassNames)}>
|
||||
<div className={classnames(label1ClassNames)}>
|
||||
{authorizedAsString}
|
||||
</div> */}
|
||||
</div>
|
||||
</div>
|
||||
<Paper className={classes.cardProperties} elevation={0}>
|
||||
{children}
|
||||
</Paper>
|
||||
{/* V2 */}
|
||||
{/* <div className={classes.buttonsWrapper}>
|
||||
<div className={classes.buttonsWrapper}>
|
||||
{state !== OVERRIDE_AUTHORIZED && AuthorizeButton()}
|
||||
{state !== OVERRIDE_REJECTED && RejectButton()}
|
||||
</div> */}
|
||||
</div>
|
||||
</Paper>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ const propertyCardStyles = {
|
|||
display: 'flex',
|
||||
borderRadius: 8,
|
||||
width: '100%',
|
||||
height: 'calc(100% - 75px)',
|
||||
height: 'calc(100% - 104px)',
|
||||
padding: [[20]],
|
||||
boxSizing: 'border-box',
|
||||
boxShadow: '0 0 8px 0 rgba(0, 0, 0, 0.04)',
|
||||
|
|
|
|||
|
|
@ -12,7 +12,12 @@ import { cpcStyles } from './Transactions.styles'
|
|||
|
||||
const useStyles = makeStyles(cpcStyles)
|
||||
|
||||
const CopyToClipboard = ({ className, children, ...props }) => {
|
||||
const CopyToClipboard = ({
|
||||
className,
|
||||
buttonClassname,
|
||||
children,
|
||||
...props
|
||||
}) => {
|
||||
const [anchorEl, setAnchorEl] = useState(null)
|
||||
|
||||
useEffect(() => {
|
||||
|
|
@ -39,7 +44,7 @@ const CopyToClipboard = ({ className, children, ...props }) => {
|
|||
<div className={classnames(classes.address, className)}>
|
||||
{children}
|
||||
</div>
|
||||
<div className={classes.buttonWrapper}>
|
||||
<div className={classnames(classes.buttonWrapper, buttonClassname)}>
|
||||
<ReactCopyToClipboard text={R.replace(/\s/g, '')(children)}>
|
||||
<button
|
||||
aria-describedby={id}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import { fromNamespace, namespaces } from 'src/utils/config'
|
|||
|
||||
import { mainStyles } from './Triggers.styles'
|
||||
import Wizard from './Wizard'
|
||||
import { Schema, elements, sortBy } from './helper'
|
||||
import { Schema, getElements, sortBy, fromServer, toServer } from './helper'
|
||||
|
||||
const useStyles = makeStyles(mainStyles)
|
||||
|
||||
|
|
@ -34,7 +34,7 @@ const Triggers = () => {
|
|||
const [error, setError] = useState(false)
|
||||
|
||||
const { data } = useQuery(GET_INFO)
|
||||
const triggers = data?.config?.triggers ?? []
|
||||
const triggers = fromServer(data?.config?.triggers ?? [])
|
||||
|
||||
const [saveConfig] = useMutation(SAVE_CONFIG, {
|
||||
onCompleted: () => setWizard(false),
|
||||
|
|
@ -45,12 +45,14 @@ const Triggers = () => {
|
|||
const add = rawConfig => {
|
||||
const toSave = R.concat([{ id: v4(), ...rawConfig }])(triggers)
|
||||
setError(false)
|
||||
return saveConfig({ variables: { config: { triggers: toSave } } })
|
||||
return saveConfig({ variables: { config: { triggers: toServer(toSave) } } })
|
||||
}
|
||||
|
||||
const save = config => {
|
||||
setError(false)
|
||||
return saveConfig({ variables: { config } })
|
||||
return saveConfig({
|
||||
variables: { config: { triggers: toServer(config.triggers) } }
|
||||
})
|
||||
}
|
||||
|
||||
const currency = R.path(['fiatCurrency'])(
|
||||
|
|
@ -78,7 +80,7 @@ const Triggers = () => {
|
|||
enableDelete
|
||||
save={save}
|
||||
validationSchema={Schema}
|
||||
elements={elements}
|
||||
elements={getElements(currency, classes)}
|
||||
/>
|
||||
{wizard && (
|
||||
<Wizard
|
||||
|
|
|
|||
|
|
@ -21,6 +21,13 @@ const mainStyles = {
|
|||
padding: 4,
|
||||
margin: 4
|
||||
},
|
||||
tableRadioGroup: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between'
|
||||
},
|
||||
tableRadioLabel: {
|
||||
marginRight: 0
|
||||
},
|
||||
closeButton: {
|
||||
position: 'absolute',
|
||||
width: 16,
|
||||
|
|
|
|||
|
|
@ -88,19 +88,19 @@ const getTypeText = (config, currency) => {
|
|||
switch (config.triggerType) {
|
||||
case 'txAmount':
|
||||
return `makes a single transaction over ${orUnderline(
|
||||
config.threshold
|
||||
config.threshold.threshold
|
||||
)} ${currency}`
|
||||
case 'txVolume':
|
||||
return `makes transactions over ${orUnderline(
|
||||
config.threshold
|
||||
)} ${currency} in ${orUnderline(config.days)} days`
|
||||
config.threshold.threshold
|
||||
)} ${currency} in ${orUnderline(config.threshold.thresholdDays)} days`
|
||||
case 'txVelocity':
|
||||
return `makes ${orUnderline(
|
||||
config.threshold
|
||||
)} transactions in ${orUnderline(config.days)} days`
|
||||
config.threshold.threshold
|
||||
)} transactions in ${orUnderline(config.threshold.thresholdDays)} days`
|
||||
case 'consecutiveDays':
|
||||
return `at least one transaction every day for ${orUnderline(
|
||||
config.days
|
||||
config.threshold.thresholdDays
|
||||
)} days`
|
||||
default:
|
||||
return ''
|
||||
|
|
@ -108,7 +108,7 @@ const getTypeText = (config, currency) => {
|
|||
}
|
||||
|
||||
const getRequirementText = config => {
|
||||
switch (config.requirement) {
|
||||
switch (config.requirement?.requirement) {
|
||||
case 'sms':
|
||||
return 'asked to enter code provided through SMS verification'
|
||||
case 'idPhoto':
|
||||
|
|
@ -122,7 +122,9 @@ const getRequirementText = config => {
|
|||
case 'superuser':
|
||||
return ''
|
||||
case 'suspend':
|
||||
return 'suspended'
|
||||
return `suspended for ${orUnderline(
|
||||
config.requirement.suspensionDays
|
||||
)} days`
|
||||
case 'block':
|
||||
return 'blocked'
|
||||
default:
|
||||
|
|
@ -155,7 +157,6 @@ const InfoPanel = ({ step, config = {}, liveValues = {}, currency }) => {
|
|||
const GetValues = ({ setValues }) => {
|
||||
const { values } = useFormikContext()
|
||||
useEffect(() => {
|
||||
console.log('triggered')
|
||||
setValues && values && setValues(values)
|
||||
}, [setValues, values])
|
||||
|
||||
|
|
|
|||
|
|
@ -2,12 +2,11 @@ import { makeStyles, Box } from '@material-ui/core'
|
|||
import classnames from 'classnames'
|
||||
import { Field, useFormikContext } from 'formik'
|
||||
import * as R from 'ramda'
|
||||
import React from 'react'
|
||||
import React, { memo } from 'react'
|
||||
import * as Yup from 'yup'
|
||||
|
||||
import { TextInput, RadioGroup } from 'src/components/inputs/formik'
|
||||
import Autocomplete from 'src/components/inputs/formik/Autocomplete'
|
||||
import { H4 } from 'src/components/typography'
|
||||
import { H4, Label2, Label1, Info2 } from 'src/components/typography'
|
||||
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 { errorColor } from 'src/styling/variables'
|
||||
|
|
@ -40,13 +39,45 @@ const useStyles = makeStyles({
|
|||
},
|
||||
directionName: {
|
||||
marginLeft: 6
|
||||
},
|
||||
thresholdWrapper: {
|
||||
display: 'flex'
|
||||
},
|
||||
thresholdField: {
|
||||
margin: 10,
|
||||
width: 208
|
||||
},
|
||||
space: {
|
||||
marginLeft: 6,
|
||||
marginRight: 6
|
||||
},
|
||||
lastSpace: {
|
||||
marginLeft: 6
|
||||
},
|
||||
suspensionDays: {
|
||||
width: 34
|
||||
},
|
||||
input: {
|
||||
marginTop: -2
|
||||
},
|
||||
limitedInput: {
|
||||
width: 50
|
||||
},
|
||||
daysInput: {
|
||||
width: 60
|
||||
}
|
||||
})
|
||||
|
||||
const cashDirection = Yup.string().required('Required')
|
||||
const triggerType = Yup.string().required('Required')
|
||||
const threshold = Yup.number().required('Required')
|
||||
const requirement = Yup.string().required('Required')
|
||||
const threshold = Yup.object().shape({
|
||||
threshold: Yup.number(),
|
||||
thresholdDays: Yup.number()
|
||||
})
|
||||
const requirement = Yup.object().shape({
|
||||
requirement: Yup.string().required('Required'),
|
||||
suspensionDays: Yup.number()
|
||||
})
|
||||
|
||||
const Schema = Yup.object().shape({
|
||||
triggerType,
|
||||
|
|
@ -59,9 +90,52 @@ const Schema = Yup.object().shape({
|
|||
const directionSchema = Yup.object().shape({ cashDirection })
|
||||
|
||||
const directionOptions = [
|
||||
{ display: 'Both', code: 'both' },
|
||||
{ display: 'Only cash-in', code: 'cashIn' },
|
||||
{ display: 'Only cash-out', code: 'cashOut' }
|
||||
{
|
||||
display: 'Both',
|
||||
code: 'both'
|
||||
},
|
||||
{
|
||||
display: 'Only cash-in',
|
||||
code: 'cashIn'
|
||||
},
|
||||
{
|
||||
display: 'Only cash-out',
|
||||
code: 'cashOut'
|
||||
}
|
||||
]
|
||||
|
||||
const directionOptions2 = [
|
||||
{
|
||||
display: (
|
||||
<>
|
||||
<TxInIcon /> in
|
||||
</>
|
||||
),
|
||||
code: 'cashIn'
|
||||
},
|
||||
{
|
||||
display: (
|
||||
<>
|
||||
<TxOutIcon /> out
|
||||
</>
|
||||
),
|
||||
code: 'cashOut'
|
||||
},
|
||||
{
|
||||
display: (
|
||||
<>
|
||||
<Box display="flex">
|
||||
<Box mr={0.25}>
|
||||
<TxOutIcon />
|
||||
</Box>
|
||||
<Box>
|
||||
<TxInIcon />
|
||||
</Box>
|
||||
</Box>
|
||||
</>
|
||||
),
|
||||
code: 'both'
|
||||
}
|
||||
]
|
||||
|
||||
const Direction = () => {
|
||||
|
|
@ -113,12 +187,25 @@ const typeOptions = [
|
|||
|
||||
const Type = () => {
|
||||
const classes = useStyles()
|
||||
const { errors, touched } = useFormikContext()
|
||||
const { errors, touched, values } = useFormikContext()
|
||||
|
||||
const typeClass = {
|
||||
[classes.error]: errors.triggerType && touched.triggerType
|
||||
}
|
||||
|
||||
const containsType = R.contains(values?.triggerType)
|
||||
const isThresholdEnabled = containsType([
|
||||
'txAmount',
|
||||
'txVolume',
|
||||
'txVelocity'
|
||||
])
|
||||
|
||||
const isThresholdDaysEnabled = containsType([
|
||||
'txVolume',
|
||||
'txVelocity',
|
||||
'consecutiveDays'
|
||||
])
|
||||
|
||||
return (
|
||||
<>
|
||||
<Box display="flex" alignItems="center">
|
||||
|
|
@ -133,13 +220,26 @@ const Type = () => {
|
|||
className={classes.radioGroup}
|
||||
/>
|
||||
|
||||
<div className={classes.thresholdWrapper}>
|
||||
{isThresholdEnabled && (
|
||||
<Field
|
||||
className={classes.thresholdField}
|
||||
component={TextInput}
|
||||
label="Threshold"
|
||||
size="lg"
|
||||
name="threshold"
|
||||
options={typeOptions}
|
||||
name="threshold.threshold"
|
||||
/>
|
||||
)}
|
||||
{isThresholdDaysEnabled && (
|
||||
<Field
|
||||
className={classes.thresholdField}
|
||||
component={TextInput}
|
||||
label="Threshold Days"
|
||||
size="lg"
|
||||
name="threshold.thresholdDays"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
@ -168,12 +268,14 @@ const requirementOptions = [
|
|||
|
||||
const Requirement = () => {
|
||||
const classes = useStyles()
|
||||
const { errors } = useFormikContext()
|
||||
const { errors, values } = useFormikContext()
|
||||
|
||||
const titleClass = {
|
||||
[classes.error]: errors.requirement
|
||||
}
|
||||
|
||||
const isSuspend = values?.requirement?.requirement === 'suspend'
|
||||
|
||||
return (
|
||||
<>
|
||||
<Box display="flex" alignItems="center">
|
||||
|
|
@ -181,12 +283,22 @@ const Requirement = () => {
|
|||
</Box>
|
||||
<Field
|
||||
component={RadioGroup}
|
||||
name="requirement"
|
||||
name="requirement.requirement"
|
||||
options={requirementOptions}
|
||||
labelClassName={classes.specialLabel}
|
||||
radioClassName={classes.radio}
|
||||
className={classnames(classes.radioGroup, classes.specialGrid)}
|
||||
/>
|
||||
|
||||
{isSuspend && (
|
||||
<Field
|
||||
className={classes.thresholdField}
|
||||
component={TextInput}
|
||||
label="Days"
|
||||
size="lg"
|
||||
name="requirement.suspensionDays"
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
@ -219,7 +331,149 @@ const DirectionDisplay = ({ code }) => {
|
|||
)
|
||||
}
|
||||
|
||||
const elements = [
|
||||
const RequirementInput = () => {
|
||||
const { values } = useFormikContext()
|
||||
const classes = useStyles()
|
||||
|
||||
const requirement = values?.requirement?.requirement
|
||||
const isSuspend = requirement === 'suspend'
|
||||
|
||||
const display = getView(requirementOptions, 'display')(requirement)
|
||||
|
||||
return (
|
||||
<Box display="flex" alignItems="baseline">
|
||||
{`${display} ${isSuspend ? 'for' : ''}`}
|
||||
{isSuspend && (
|
||||
<Field
|
||||
bold
|
||||
className={classes.suspensionDays}
|
||||
name="requirement.suspensionDays"
|
||||
component={TextInput}
|
||||
textAlign="center"
|
||||
/>
|
||||
)}
|
||||
{isSuspend && 'days'}
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
const RequirementView = ({ requirement, suspensionDays }) => {
|
||||
const classes = useStyles()
|
||||
const display = getView(requirementOptions, 'display')(requirement)
|
||||
const isSuspend = requirement === 'suspend'
|
||||
|
||||
return (
|
||||
<Box display="flex" alignItems="baseline">
|
||||
{`${display} ${isSuspend ? 'for' : ''}`}
|
||||
{isSuspend && (
|
||||
<Info2 className={classes.space} noMargin>
|
||||
{suspensionDays}
|
||||
</Info2>
|
||||
)}
|
||||
{isSuspend && 'days'}
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
const DisplayThreshold = ({ config, currency, isEdit }) => {
|
||||
const classes = useStyles()
|
||||
|
||||
const inputClasses = {
|
||||
[classes.input]: true,
|
||||
[classes.limitedInput]: config?.triggerType === 'txVelocity',
|
||||
[classes.daysInput]: config?.triggerType === 'consecutiveDays'
|
||||
}
|
||||
|
||||
const threshold = config?.threshold?.threshold
|
||||
const thresholdDays = config?.threshold?.thresholdDays
|
||||
|
||||
const Threshold = isEdit ? (
|
||||
<Field
|
||||
bold
|
||||
className={classnames(inputClasses)}
|
||||
name="threshold.threshold"
|
||||
component={TextInput}
|
||||
textAlign="right"
|
||||
/>
|
||||
) : (
|
||||
<Info2 noMargin>{threshold}</Info2>
|
||||
)
|
||||
const ThresholdDays = isEdit ? (
|
||||
<Field
|
||||
bold
|
||||
className={classnames(inputClasses)}
|
||||
name="threshold.thresholdDays"
|
||||
component={TextInput}
|
||||
textAlign="right"
|
||||
/>
|
||||
) : (
|
||||
<Info2 noMargin>{thresholdDays}</Info2>
|
||||
)
|
||||
|
||||
switch (config?.triggerType) {
|
||||
case 'txAmount':
|
||||
return (
|
||||
<Box display="flex" alignItems="baseline" justifyContent="right">
|
||||
{Threshold}
|
||||
<Label2 noMargin className={classes.lastSpace}>
|
||||
{currency}
|
||||
</Label2>
|
||||
</Box>
|
||||
)
|
||||
case 'txVolume':
|
||||
return (
|
||||
<Box display="flex" alignItems="baseline" justifyContent="right">
|
||||
{Threshold}
|
||||
<Label2 noMargin className={classes.lastSpace}>
|
||||
{currency}
|
||||
</Label2>
|
||||
<Label1 noMargin className={classes.space}>
|
||||
in
|
||||
</Label1>
|
||||
{ThresholdDays}
|
||||
<Label1 noMargin className={classes.lastSpace}>
|
||||
days
|
||||
</Label1>
|
||||
</Box>
|
||||
)
|
||||
case 'txVelocity':
|
||||
return (
|
||||
<Box display="flex" alignItems="baseline" justifyContent="right">
|
||||
{Threshold}
|
||||
<Label1 className={classes.space} noMargin>
|
||||
transactions in
|
||||
</Label1>
|
||||
{ThresholdDays}
|
||||
<Label1 className={classes.lastSpace} noMargin>
|
||||
days
|
||||
</Label1>
|
||||
</Box>
|
||||
)
|
||||
case 'consecutiveDays':
|
||||
return (
|
||||
<Box display="flex" alignItems="baseline" justifyContent="right">
|
||||
{ThresholdDays}
|
||||
<Label1 className={classes.lastSpace} noMargin>
|
||||
days
|
||||
</Label1>
|
||||
</Box>
|
||||
)
|
||||
default:
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
const ThresholdInput = memo(({ currency }) => {
|
||||
const { values } = useFormikContext()
|
||||
|
||||
return <DisplayThreshold isEdit={true} config={values} currency={currency} />
|
||||
})
|
||||
|
||||
const ThresholdView = ({ config, currency }) => {
|
||||
return <DisplayThreshold config={config} currency={currency} />
|
||||
}
|
||||
|
||||
const getElements = (currency, classes) => [
|
||||
{
|
||||
name: 'triggerType',
|
||||
size: 'sm',
|
||||
|
|
@ -239,35 +493,28 @@ const elements = [
|
|||
name: 'requirement',
|
||||
size: 'sm',
|
||||
width: 230,
|
||||
input: ({ field: { value: name } }) => (
|
||||
<>{getView(requirementOptions, 'display')(name)}</>
|
||||
),
|
||||
view: getView(requirementOptions, 'display'),
|
||||
inputProps: {
|
||||
options: requirementOptions,
|
||||
valueProp: 'code',
|
||||
getLabel: R.path(['display']),
|
||||
limit: null
|
||||
}
|
||||
bypassField: true,
|
||||
input: RequirementInput,
|
||||
view: it => <RequirementView {...it} />
|
||||
},
|
||||
{
|
||||
name: 'threshold',
|
||||
size: 'sm',
|
||||
width: 260,
|
||||
width: 284,
|
||||
textAlign: 'right',
|
||||
input: TextInput
|
||||
input: () => <ThresholdInput currency={currency} />,
|
||||
view: (it, config) => <ThresholdView config={config} currency={currency} />
|
||||
},
|
||||
{
|
||||
name: 'cashDirection',
|
||||
size: 'sm',
|
||||
width: 282,
|
||||
view: it => <DirectionDisplay code={it} />,
|
||||
input: Autocomplete,
|
||||
input: RadioGroup,
|
||||
inputProps: {
|
||||
options: directionOptions,
|
||||
valueProp: 'code',
|
||||
getLabel: R.path(['display']),
|
||||
limit: null
|
||||
labelClassName: classes.tableRadioLabel,
|
||||
className: classes.tableRadioGroup,
|
||||
options: directionOptions2
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
@ -280,4 +527,37 @@ const sortBy = [
|
|||
)
|
||||
]
|
||||
|
||||
export { Schema, elements, direction, type, requirements, sortBy }
|
||||
const fromServer = triggers =>
|
||||
R.map(
|
||||
({ requirement, suspensionDays, threshold, thresholdDays, ...rest }) => ({
|
||||
requirement: {
|
||||
requirement,
|
||||
suspensionDays
|
||||
},
|
||||
threshold: {
|
||||
threshold,
|
||||
thresholdDays
|
||||
},
|
||||
...rest
|
||||
})
|
||||
)(triggers)
|
||||
|
||||
const toServer = triggers =>
|
||||
R.map(({ requirement, threshold, ...rest }) => ({
|
||||
requirement: requirement.requirement,
|
||||
suspensionDays: requirement.suspensionDays,
|
||||
threshold: threshold.threshold,
|
||||
thresholdDays: threshold.thresholdDays,
|
||||
...rest
|
||||
}))(triggers)
|
||||
|
||||
export {
|
||||
Schema,
|
||||
getElements,
|
||||
direction,
|
||||
type,
|
||||
requirements,
|
||||
sortBy,
|
||||
fromServer,
|
||||
toServer
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue